summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/al/sig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/al/sig.cpp')
-rw-r--r--attic/muse2-oom/muse2/al/sig.cpp617
1 files changed, 617 insertions, 0 deletions
diff --git a/attic/muse2-oom/muse2/al/sig.cpp b/attic/muse2-oom/muse2/al/sig.cpp
new file mode 100644
index 00000000..7eeae6be
--- /dev/null
+++ b/attic/muse2-oom/muse2/al/sig.cpp
@@ -0,0 +1,617 @@
+//=============================================================================
+// 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 "gconfig.h" // Tim
+#include "sig.h"
+///#include "xml.h"
+
+
+namespace AL {
+
+SigList sigmap;
+
+//---------------------------------------------------------
+// isValid
+//---------------------------------------------------------
+
+bool TimeSignature::isValid() const
+{
+ if((z < 1) || (z > 63))
+ return false;
+
+ switch(n)
+ {
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ return true;
+ default:
+ return false;
+ }
+}
+
+//---------------------------------------------------------
+// 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);
+ // Added by Tim.
+ return;
+ }
+ tick = raster1(tick, 0);
+ iSigEvent e = upper_bound(tick);
+ if(e == end())
+ {
+ printf("SigList::add Signal not found tick:%d\n", tick);
+ return;
+ }
+
+ 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();
+ }
+
+/*
+void SigList::add(unsigned tick, int z, int n)
+ {
+ if (z == 0 || n == 0) {
+ printf("SigList::add illegal signature %d/%d\n", z, n);
+ // Added by Tim.
+ return;
+ }
+ tick = raster1(tick, 0);
+ iSigEvent e = upper_bound(tick);
+ if(e == end())
+ {
+ printf("SigList::add Signal not found tick:%d\n", tick);
+ return;
+ }
+
+ if (tick == e->second->tick) {
+ e->second->sig.z = z;
+ e->second->sig.n = n;
+ }
+ else {
+ SigEvent* ne = e->second;
+ SigEvent* ev = new SigEvent(ne->sig.z, ne->sig.n, ne->tick);
+ ne->sig.z = z;
+ ne->sig.n = n;
+ 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() next event not found!\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(int Z, int N) const
+ {
+ return ticks_beat(N) * 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);
+ if(i == end())
+ {
+ printf("SigList::ticksBeat event not found! tick:%d\n", tick);
+ return 0;
+ }
+ return ticks_beat(i->second->sig.n);
+ }
+
+int SigList::ticks_beat(int n) const
+ {
+
+ ///int m = AL::division;
+ int m = config.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;
+ }
+
+void SigList::timesig(unsigned tick, int& z, int& n) const
+ {
+ ciSigEvent i = upper_bound(tick);
+ if (i == end()) {
+ printf("timesig(%d): not found\n", tick);
+ // abort();
+ z = 4;
+ n = 4;
+ }
+ else {
+ z = i->second->sig.z;
+ n = i->second->sig.n;
+ }
+ }
+
+//---------------------------------------------------------
+// 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());
+ *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);
+ if(e == end())
+ {
+ printf("SigList::raster1 event not found tick:%d\n", t);
+ //return 0;
+ 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)*raster;
+ }
+
+//---------------------------------------------------------
+// raster2
+// round up
+//---------------------------------------------------------
+
+unsigned SigList::raster2(unsigned t, int raster) const
+ {
+ if (raster == 1)
+ return t;
+ ciSigEvent e = upper_bound(t);
+ if(e == end())
+ {
+ printf("SigList::raster2 event not found tick:%d\n", t);
+ //return 0;
+ 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-1)/raster)*raster;
+ }
+
+//---------------------------------------------------------
+// rasterStep
+//---------------------------------------------------------
+
+int SigList::rasterStep(unsigned t, int raster) const
+ {
+ if (raster == 0) {
+ ciSigEvent e = upper_bound(t);
+ if(e == end())
+ {
+ printf("SigList::rasterStep event not found tick:%d\n", t);
+ //return 0;
+ return raster;
+ }
+
+ return ticks_beat(e->second->sig.n) * e->second->sig.z;
+ }
+ return raster;
+ }
+
+//---------------------------------------------------------
+// SigList::write
+//---------------------------------------------------------
+
+#if 0
+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");
+ }
+#endif
+
+void SigList::write(int level, Xml& xml) const
+ {
+ xml.tag(level++, "siglist");
+ for (ciSigEvent i = begin(); i != end(); ++i)
+ i->second->write(level, xml, i->first);
+ xml.tag(level, "/siglist");
+ }
+
+//---------------------------------------------------------
+// SigList::read
+//---------------------------------------------------------
+
+#if 0
+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().constData());
+ node = node.nextSibling();
+ }
+ normalize();
+ }
+#endif
+
+void SigList::read(Xml& xml)
+ {
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "sig") {
+ SigEvent* t = new SigEvent();
+ unsigned tick = t->read(xml);
+ iSigEvent pos = find(tick);
+ if (pos != end())
+ erase(pos);
+ insert(std::pair<const unsigned, SigEvent*> (tick, t));
+ }
+ else
+ xml.unknown("SigList");
+ break;
+ case Xml::Attribut:
+ break;
+ case Xml::TagEnd:
+ if (tag == "siglist") {
+ normalize();
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// SigEvent::write
+//---------------------------------------------------------
+
+#if 0
+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");
+ }
+#endif
+
+void SigEvent::write(int level, Xml& xml, int at) const
+ {
+ xml.tag(level++, "sig at=\"%d\"", at);
+ xml.intTag(level, "tick", tick);
+ xml.intTag(level, "nom", sig.z);
+ xml.intTag(level, "denom", sig.n);
+ xml.tag(level, "/sig");
+ }
+
+//---------------------------------------------------------
+// SigEvent::read
+//---------------------------------------------------------
+
+#if 0
+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().constData());
+ node = node.nextSibling();
+ }
+ return at;
+ }
+
+}
+#endif
+
+int SigEvent::read(Xml& xml)
+ {
+ int at = 0;
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return 0;
+ case Xml::TagStart:
+ if (tag == "tick")
+ tick = xml.parseInt();
+ else if (tag == "nom")
+ sig.z = xml.parseInt();
+ else if (tag == "denom")
+ sig.n = xml.parseInt();
+ else
+ xml.unknown("SigEvent");
+ break;
+ case Xml::Attribut:
+ if (tag == "at")
+ at = xml.s2().toInt();
+ break;
+ case Xml::TagEnd:
+ if (tag == "sig")
+ return at;
+ default:
+ break;
+ }
+ }
+ return 0;
+ }
+
+
+} // namespace AL
+