summaryrefslogtreecommitdiff
path: root/muse_qt4_evolution/al/sig.cpp
diff options
context:
space:
mode:
authorRobert Jonsson <spamatica@gmail.com>2009-12-27 11:30:35 +0000
committerRobert Jonsson <spamatica@gmail.com>2009-12-27 11:30:35 +0000
commitb703eab295330e6f81564fbb39a10a1a2fdd2f54 (patch)
treee46b5c9a6bc22fd661c15d1d2123f5bf631cef80 /muse_qt4_evolution/al/sig.cpp
parent5d5fa0fdf913907edbc3d2d29a7548f0cb658c94 (diff)
moved old qt4 branch
Diffstat (limited to 'muse_qt4_evolution/al/sig.cpp')
-rw-r--r--muse_qt4_evolution/al/sig.cpp407
1 files changed, 407 insertions, 0 deletions
diff --git a/muse_qt4_evolution/al/sig.cpp b/muse_qt4_evolution/al/sig.cpp
new file mode 100644
index 00000000..d8672200
--- /dev/null
+++ b/muse_qt4_evolution/al/sig.cpp
@@ -0,0 +1,407 @@
+//=============================================================================
+// AL
+// Audio Utility Library
+// $Id:$
+//
+// Copyright (C) 2002-2006 by Werner Schweer and others
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//=============================================================================
+
+#include "al.h"
+#include "sig.h"
+#include "xml.h"
+
+namespace AL {
+
+SigList sigmap;
+
+//---------------------------------------------------------
+// SigList
+//---------------------------------------------------------
+
+SigList::SigList()
+ {
+ insert(std::pair<const unsigned, SigEvent*> (MAX_TICK, new SigEvent(TimeSignature(4, 4), 0)));
+ }
+
+//---------------------------------------------------------
+// add
+// signatures are only allowed at the beginning of
+// a bar
+//---------------------------------------------------------
+
+void SigList::add(unsigned tick, const TimeSignature& s)
+ {
+ if (s.z == 0 || s.n == 0) {
+ printf("illegal signature %d/%d\n", s.z, s.n);
+ }
+ tick = raster1(tick, 0);
+ iSigEvent e = upper_bound(tick);
+
+ if (tick == e->second->tick) {
+ e->second->sig = s;
+ }
+ else {
+ SigEvent* ne = e->second;
+ SigEvent* ev = new SigEvent(ne->sig, ne->tick);
+ ne->sig = s;
+ ne->tick = tick;
+ insert(std::pair<const unsigned, SigEvent*> (tick, ev));
+ }
+ normalize();
+ }
+
+//---------------------------------------------------------
+// del
+//---------------------------------------------------------
+
+void SigList::del(unsigned tick)
+ {
+// printf("SigList::del(%d)\n", tick);
+ iSigEvent e = find(tick);
+ if (e == end()) {
+ printf("SigList::del(%d): not found\n", tick);
+ return;
+ }
+ iSigEvent ne = e;
+ ++ne;
+ if (ne == end()) {
+ printf("SigList::del() HALLO\n");
+ return;
+ }
+ ne->second->sig = e->second->sig;
+ ne->second->tick = e->second->tick;
+ erase(e);
+ normalize();
+ }
+
+//---------------------------------------------------------
+// SigList::normalize
+//---------------------------------------------------------
+
+void SigList::normalize()
+ {
+ TimeSignature sig(0, 0);
+ unsigned tick = 0;
+ iSigEvent ee;
+
+ for (iSigEvent e = begin(); e != end();) {
+ if (sig.z == e->second->sig.z && sig.n == e->second->sig.n) {
+ e->second->tick = tick;
+ erase(ee);
+ }
+ sig = e->second->sig;
+ ee = e;
+ tick = e->second->tick;
+ ++e;
+ }
+
+ int bar = 0;
+ for (iSigEvent e = begin(); e != end();) {
+ e->second->bar = bar;
+ int delta = e->first - e->second->tick;
+ int ticksB = ticks_beat(e->second->sig.n);
+ int ticksM = ticksB * e->second->sig.z;
+ bar += delta / ticksM;
+ if (delta % ticksM) // Teil eines Taktes
+ ++bar;
+ ++e;
+ }
+ }
+
+//---------------------------------------------------------
+// SigList::dump
+//---------------------------------------------------------
+
+void SigList::dump() const
+ {
+ printf("\nSigList:\n");
+ for (ciSigEvent i = begin(); i != end(); ++i) {
+ printf("%6d %06d Bar %3d %02d/%d\n",
+ i->first, i->second->tick,
+ i->second->bar, i->second->sig.z, i->second->sig.n);
+ }
+ }
+
+void SigList::clear()
+ {
+ for (iSigEvent i = begin(); i != end(); ++i)
+ delete i->second;
+ SIGLIST::clear();
+ insert(std::pair<const unsigned, SigEvent*> (MAX_TICK, new SigEvent(TimeSignature(4, 4), 0)));
+ }
+
+//---------------------------------------------------------
+// ticksMeasure
+//---------------------------------------------------------
+
+int SigList::ticksMeasure(const TimeSignature& sig) const
+ {
+ return ticks_beat(sig.n) * sig.z;
+ }
+
+int SigList::ticksMeasure(unsigned tick) const
+ {
+ ciSigEvent i = upper_bound(tick);
+ if (i == end()) {
+ printf("ticksMeasure: not found %d\n", tick);
+ // abort();
+ return 0;
+ }
+ return ticksMeasure(i->second->sig);
+ }
+
+//---------------------------------------------------------
+// ticksBeat
+//---------------------------------------------------------
+
+int SigList::ticksBeat(unsigned tick) const
+ {
+ ciSigEvent i = upper_bound(tick);
+ return ticks_beat(i->second->sig.n);
+ }
+
+int SigList::ticks_beat(int n) const
+ {
+ int m = AL::division;
+ switch (n) {
+ case 1: m <<= 2; break; // 1536
+ case 2: m <<= 1; break; // 768
+ case 3: m += m >> 1; break; // 384+192
+ case 4: break; // 384
+ case 8: m >>= 1; break; // 192
+ case 16: m >>= 2; break; // 96
+ case 32: m >>= 3; break; // 48
+ case 64: m >>= 4; break; // 24
+ case 128: m >>= 5; break; // 12
+ default: break;
+ }
+ return m;
+ }
+
+//---------------------------------------------------------
+// timesig
+//---------------------------------------------------------
+
+TimeSignature SigList::timesig(unsigned tick) const
+ {
+ ciSigEvent i = upper_bound(tick);
+ if (i == end()) {
+ printf("timesig(%d): not found\n", tick);
+ // abort();
+ return TimeSignature(4,4);
+ }
+ return i->second->sig;
+ }
+
+//---------------------------------------------------------
+// tickValues
+//---------------------------------------------------------
+
+void SigList::tickValues(unsigned t, int* bar, int* beat, unsigned* tick) const
+ {
+ ciSigEvent e = upper_bound(t);
+ if (e == end()) {
+ fprintf(stderr, "tickValues(0x%x) not found(%zd)\n", t, size());
+//DEBUG
+// abort();
+ *bar = 0;
+ *beat = 0;
+ *tick = 0;
+ return;
+ }
+
+ int delta = t - e->second->tick;
+ int ticksB = ticks_beat(e->second->sig.n);
+ int ticksM = ticksB * e->second->sig.z;
+ *bar = e->second->bar + delta / ticksM;
+ int rest = delta % ticksM;
+ *beat = rest / ticksB;
+ *tick = rest % ticksB;
+ }
+
+//---------------------------------------------------------
+// bar2tick
+//---------------------------------------------------------
+
+unsigned SigList::bar2tick(int bar, int beat, unsigned tick) const
+ {
+ ciSigEvent e;
+
+ if (bar < 0)
+ bar = 0;
+ for (e = begin(); e != end();) {
+ ciSigEvent ee = e;
+ ++ee;
+ if (ee == end())
+ break;
+ if (bar < ee->second->bar)
+ break;
+ e = ee;
+ }
+ int ticksB = ticks_beat(e->second->sig.n);
+ int ticksM = ticksB * e->second->sig.z;
+ return e->second->tick + (bar-e->second->bar)*ticksM + ticksB*beat + tick;
+ }
+
+//---------------------------------------------------------
+// raster
+//---------------------------------------------------------
+
+unsigned SigList::raster(unsigned t, int raster) const
+ {
+ if (raster == 1)
+ return t;
+ ciSigEvent e = upper_bound(t);
+ if (e == end()) {
+ printf("SigList::raster(%x,)\n", t);
+ // abort();
+ return t;
+ }
+ int delta = t - e->second->tick;
+ int ticksM = ticks_beat(e->second->sig.n) * e->second->sig.z;
+ if (raster == 0)
+ raster = ticksM;
+ int rest = delta % ticksM;
+ int bb = (delta/ticksM)*ticksM;
+ return e->second->tick + bb + ((rest + raster/2)/raster)*raster;
+ }
+
+//---------------------------------------------------------
+// raster1
+// round down
+//---------------------------------------------------------
+
+unsigned SigList::raster1(unsigned t, int raster) const
+ {
+ if (raster == 1)
+ return t;
+ ciSigEvent e = upper_bound(t);
+
+ int delta = t - e->second->tick;
+ int ticksM = ticks_beat(e->second->sig.n) * e->second->sig.z;
+ if (raster == 0)
+ raster = ticksM;
+ int rest = delta % ticksM;
+ int bb = (delta/ticksM)*ticksM;
+ return e->second->tick + bb + (rest/raster)*raster;
+ }
+
+//---------------------------------------------------------
+// raster2
+// round up
+//---------------------------------------------------------
+
+unsigned SigList::raster2(unsigned t, int raster) const
+ {
+ if (raster == 1)
+ return t;
+ ciSigEvent e = upper_bound(t);
+
+ int delta = t - e->second->tick;
+ int ticksM = ticks_beat(e->second->sig.n) * e->second->sig.z;
+ if (raster == 0)
+ raster = ticksM;
+ int rest = delta % ticksM;
+ int bb = (delta/ticksM)*ticksM;
+ return e->second->tick + bb + ((rest+raster-1)/raster)*raster;
+ }
+
+//---------------------------------------------------------
+// rasterStep
+//---------------------------------------------------------
+
+int SigList::rasterStep(unsigned t, int raster) const
+ {
+ if (raster == 0) {
+ ciSigEvent e = upper_bound(t);
+ return ticks_beat(e->second->sig.n) * e->second->sig.z;
+ }
+ return raster;
+ }
+
+//---------------------------------------------------------
+// SigList::write
+//---------------------------------------------------------
+
+void SigList::write(Xml& xml) const
+ {
+ xml.stag("siglist");
+ for (ciSigEvent i = begin(); i != end(); ++i)
+ i->second->write(xml, i->first);
+ xml.etag("siglist");
+ }
+
+//---------------------------------------------------------
+// SigList::read
+//---------------------------------------------------------
+
+void SigList::read(QDomNode node)
+ {
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ if (e.tagName() == "sig") {
+ SigEvent* t = new SigEvent();
+ unsigned tick = t->read(node);
+ iSigEvent pos = find(tick);
+ if (pos != end())
+ erase(pos);
+ insert(std::pair<const unsigned, SigEvent*> (tick, t));
+ }
+ else
+ printf("MusE:SigList: unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ normalize();
+ }
+
+//---------------------------------------------------------
+// SigEvent::write
+//---------------------------------------------------------
+
+void SigEvent::write(Xml& xml, int at) const
+ {
+ xml.stag(QString("sig at=\"%1\"").arg(at));
+ xml.tag("tick", tick);
+ xml.tag("nom", sig.z);
+ xml.tag("denom", sig.n);
+ xml.etag("sig");
+ }
+
+//---------------------------------------------------------
+// SigEvent::read
+//---------------------------------------------------------
+
+int SigEvent::read(QDomNode node)
+ {
+ QDomElement e = node.toElement();
+ int at = e.attribute("at", "0").toInt();
+ node = node.firstChild();
+
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ if (e.tagName() == "tick")
+ tick = e.text().toInt();
+ else if (e.tagName() == "nom")
+ sig.z = e.text().toInt();
+ else if (e.tagName() == "denom")
+ sig.n = e.text().toInt();
+ else
+ printf("MusE:SigEvent: unknown tag %s\n", e.tagName().toLatin1().data());
+ node = node.nextSibling();
+ }
+ return at;
+ }
+
+}