summaryrefslogtreecommitdiff
path: root/muse2/muse/sig.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/sig.cpp')
-rw-r--r--muse2/muse/sig.cpp439
1 files changed, 439 insertions, 0 deletions
diff --git a/muse2/muse/sig.cpp b/muse2/muse/sig.cpp
new file mode 100644
index 00000000..8bbebfae
--- /dev/null
+++ b/muse2/muse/sig.cpp
@@ -0,0 +1,439 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: sig.cpp,v 1.5.2.2 2009/03/09 02:05:17 terminator356 Exp $
+//
+// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <stdio.h>
+#include <assert.h>
+#include "sig.h"
+#include "gconfig.h"
+#include "xml.h"
+
+SigList sigmap;
+
+//---------------------------------------------------------
+// SigList
+//---------------------------------------------------------
+
+SigList::SigList()
+ {
+ insert(std::pair<const unsigned, SigEvent*> (MAX_TICK, new SigEvent(4, 4, 0)));
+ }
+
+//---------------------------------------------------------
+// add
+// signatures are only allowed at the beginning of
+// a bar
+//---------------------------------------------------------
+
+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 p3.3.43
+ return;
+ }
+ tick = raster1(tick, 0);
+ iSigEvent e = upper_bound(tick);
+ assert(e != end());
+
+ if (tick == e->second->tick) {
+ e->second->z = z;
+ e->second->n = n;
+ }
+ else {
+ SigEvent* ne = e->second;
+ SigEvent* ev = new SigEvent(ne->z, ne->n, ne->tick);
+ ne->z = z;
+ ne->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() HALLO\n");
+ return;
+ }
+ ne->second->z = e->second->z;
+ ne->second->n = e->second->n;
+ ne->second->tick = e->second->tick;
+ erase(e);
+ normalize();
+ }
+
+//---------------------------------------------------------
+// SigList::normalize
+//---------------------------------------------------------
+
+void SigList::normalize()
+ {
+ int z = 0;
+ int n = 0;
+ unsigned tick = 0;
+ iSigEvent ee;
+
+ for (iSigEvent e = begin(); e != end();) {
+ if (z == e->second->z && n == e->second->n) {
+ e->second->tick = tick;
+ erase(ee);
+ }
+ z = e->second->z;
+ n = e->second->n;
+ 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->n);
+ int ticksM = ticksB * e->second->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->z, i->second->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(4, 4, 0)));
+ }
+
+//---------------------------------------------------------
+// ticksMeasure
+//---------------------------------------------------------
+
+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->z, i->second->n);
+ }
+
+//---------------------------------------------------------
+// ticksBeat
+//---------------------------------------------------------
+
+int SigList::ticksBeat(unsigned tick) const
+ {
+ ciSigEvent i = upper_bound(tick);
+ assert(i != end());
+ return ticks_beat(i->second->n);
+ }
+
+int SigList::ticks_beat(int n) const
+ {
+ 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: assert(false); break;
+ }
+ return m;
+ }
+
+//---------------------------------------------------------
+// timesig
+//---------------------------------------------------------
+
+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->z;
+ n = i->second->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());
+ // abort();
+ *bar = 0;
+ *beat = 0;
+ *tick = 0;
+ return;
+ }
+
+ int delta = t - e->second->tick;
+ int ticksB = ticks_beat(e->second->n);
+ int ticksM = ticksB * e->second->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->n);
+ int ticksM = ticksB * e->second->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->n) * e->second->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);
+ assert(e != end());
+
+ int delta = t - e->second->tick;
+ int ticksM = ticks_beat(e->second->n) * e->second->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);
+ assert(e != end());
+
+ int delta = t - e->second->tick;
+ int ticksM = ticks_beat(e->second->n) * e->second->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);
+ assert(e != end());
+ return ticks_beat(e->second->n) * e->second->z;
+ }
+ return raster;
+ }
+
+//---------------------------------------------------------
+// SigList::write
+//---------------------------------------------------------
+
+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
+//---------------------------------------------------------
+
+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
+//---------------------------------------------------------
+
+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", z);
+ xml.intTag(level, "denom", n);
+ xml.tag(level, "/sig");
+ }
+
+//---------------------------------------------------------
+// SigEvent::read
+//---------------------------------------------------------
+
+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")
+ z = xml.parseInt();
+ else if (tag == "denom")
+ 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;
+ }
+
+