diff options
Diffstat (limited to 'attic/muse2-oom/muse2/al/sig.cpp')
-rw-r--r-- | attic/muse2-oom/muse2/al/sig.cpp | 617 |
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 + |