summaryrefslogtreecommitdiff
path: root/muse2/muse/helper.cpp
diff options
context:
space:
mode:
authorFlorian Jung <flo@windfisch.org>2011-12-30 17:55:58 +0000
committerFlorian Jung <flo@windfisch.org>2011-12-30 17:55:58 +0000
commit6f35a1b2b84ab6cfc5d77fd46d5e31887a1590e1 (patch)
treeadece0e0c4fbe63659741539296df9fd32bfcaab /muse2/muse/helper.cpp
parent4d8477ab60093fc4c1f6190a931d0c2fdc65384c (diff)
instruments can load their patch'es drummaps
automatic setting of drummap according to patch this is turned off when the user manually changes the drummap TODO: let him turn it on again moved MidiTrack::read/writeOurDrummap out to helper.cpp extended xg.idf and gs.idf to ship the drummaps still work in progress, but should be usable and stable, though incomplete
Diffstat (limited to 'muse2/muse/helper.cpp')
-rw-r--r--muse2/muse/helper.cpp199
1 files changed, 193 insertions, 6 deletions
diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp
index 05cecc08..7d07a6ce 100644
--- a/muse2/muse/helper.cpp
+++ b/muse2/muse/helper.cpp
@@ -116,15 +116,12 @@ bool any_event_selected(const set<Part*>& parts, bool in_range)
return !get_events(parts, in_range ? 3 : 1).empty();
}
-bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int len)
+bool drummaps_almost_equal(const DrumMap* one, const DrumMap* two, int len)
{
for (int i=0; i<len; i++)
- {
- DrumMap tmp = one[i];
- tmp.mute=two[i].mute;
- if (tmp!=two[i])
+ if (!one[i].almost_equals(two[i]))
return false;
- }
+
return true;
}
@@ -164,6 +161,196 @@ QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks)
return result;
}
+bool parse_range(const QString& str, int* from, int* to)
+{
+ int idx = str.indexOf("-");
+ if (idx<0) // no "-" in str
+ {
+ bool ok;
+ int i = str.toInt(&ok);
+ if (!ok)
+ {
+ *from=-1; *to=-1;
+ return false;
+ }
+ else
+ {
+ *from=i; *to=i;
+ return true;
+ }
+ }
+ else // there is a "-" in str
+ {
+ QString str1=str.mid(0,idx);
+ QString str2=str.mid(idx+1);
+
+ bool ok;
+ int i = str1.toInt(&ok);
+ if (!ok)
+ {
+ *from=-1; *to=-1;
+ return false;
+ }
+ else
+ {
+ *from=i;
+
+ i = str2.toInt(&ok);
+ if (!ok)
+ {
+ *from=-1; *to=-1;
+ return false;
+ }
+ else
+ {
+ *to=i;
+ return true;
+ }
+ }
+ }
+}
+
+void write_new_style_drummap(int level, Xml& xml, const char* tagname,
+ DrumMap* drummap, bool* drummap_hidden, bool full)
+{
+ xml.tag(level++, tagname);
+
+ for (int i=0;i<128;i++)
+ {
+ DrumMap* dm = &drummap[i];
+ const DrumMap* idm = &iNewDrumMap[i];
+
+ if ( (dm->name != idm->name) || (dm->vol != idm->vol) ||
+ (dm->quant != idm->quant) || (dm->len != idm->len) ||
+ (dm->lv1 != idm->lv1) || (dm->lv2 != idm->lv2) ||
+ (dm->lv3 != idm->lv3) || (dm->lv4 != idm->lv4) ||
+ (dm->enote != idm->enote) || (dm->mute != idm->mute) ||
+ (drummap_hidden && drummap_hidden[i]) || full)
+ {
+ xml.tag(level++, "entry pitch=\"%d\"", i);
+
+ // when any of these "if"s changes, also update the large "if"
+ // above (this scope's parent)
+ if (full || dm->name != idm->name) xml.strTag(level, "name", dm->name);
+ if (full || dm->vol != idm->vol) xml.intTag(level, "vol", dm->vol);
+ if (full || dm->quant != idm->quant) xml.intTag(level, "quant", dm->quant);
+ if (full || dm->len != idm->len) xml.intTag(level, "len", dm->len);
+ if (full || dm->lv1 != idm->lv1) xml.intTag(level, "lv1", dm->lv1);
+ if (full || dm->lv2 != idm->lv2) xml.intTag(level, "lv2", dm->lv2);
+ if (full || dm->lv3 != idm->lv3) xml.intTag(level, "lv3", dm->lv3);
+ if (full || dm->lv4 != idm->lv4) xml.intTag(level, "lv4", dm->lv4);
+ if (full || dm->enote != idm->enote) xml.intTag(level, "enote", dm->enote);
+ if (full || dm->mute != idm->mute) xml.intTag(level, "mute", dm->mute);
+ if (drummap_hidden &&
+ (full || drummap_hidden[i])) xml.intTag(level, "hide", drummap_hidden[i]);
+
+ // anote is ignored anyway, as dm->anote == i, and this is
+ // already stored in the begin tag (pitch=...)
+
+ // channel and port are ignored as well, as they're not used
+ // in new-style-drum-mode
+
+ xml.tag(level--, "/entry");
+ }
+ }
+
+ xml.etag(level, tagname);
+}
+
+void read_new_style_drummap(Xml& xml, const char* tagname,
+ DrumMap* drummap, bool* drummap_hidden)
+{
+ for (;;)
+ {
+ Xml::Token token = xml.parse();
+ if (token == Xml::Error || token == Xml::End)
+ break;
+ const QString& tag = xml.s1();
+ switch (token)
+ {
+ case Xml::TagStart:
+ if (tag == "entry") // then read that entry with a nested loop
+ {
+ DrumMap* dm=NULL;
+ bool* hidden=NULL;
+ for (;;) // nested loop
+ {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token)
+ {
+ case Xml::Error:
+ case Xml::End:
+ goto end_of_nested_for;
+
+ case Xml::Attribut:
+ if (tag == "pitch")
+ {
+ int pitch = xml.s2().toInt() & 0x7f;
+ if (pitch < 0 || pitch > 127)
+ printf("ERROR: THIS SHOULD NEVER HAPPEN: invalid pitch in read_new_style_drummap()!\n");
+ else
+ {
+ dm = &drummap[pitch];
+ hidden = drummap_hidden ? &drummap_hidden[pitch] : NULL;
+ }
+ }
+ break;
+
+ case Xml::TagStart:
+ if (dm==NULL)
+ printf("ERROR: THIS SHOULD NEVER HAPPEN: no valid 'pitch' attribute in <entry> tag, but sub-tags follow in read_new_style_drummap()!\n");
+ else if (tag == "name")
+ dm->name = xml.parse(QString("name"));
+ else if (tag == "vol")
+ dm->vol = (unsigned char)xml.parseInt();
+ else if (tag == "quant")
+ dm->quant = xml.parseInt();
+ else if (tag == "len")
+ dm->len = xml.parseInt();
+ else if (tag == "lv1")
+ dm->lv1 = xml.parseInt();
+ else if (tag == "lv2")
+ dm->lv2 = xml.parseInt();
+ else if (tag == "lv3")
+ dm->lv3 = xml.parseInt();
+ else if (tag == "lv4")
+ dm->lv4 = xml.parseInt();
+ else if (tag == "enote")
+ dm->enote = xml.parseInt();
+ else if (tag == "mute")
+ dm->mute = xml.parseInt();
+ else if (tag == "hide")
+ {
+ if (hidden) *hidden = xml.parseInt();
+ }
+ else
+ xml.unknown("read_new_style_drummap");
+ break;
+
+ case Xml::TagEnd:
+ if (tag == "entry")
+ goto end_of_nested_for;
+
+ default:
+ break;
+ }
+ } // end of nested loop
+ end_of_nested_for: ;
+ } // end of 'if (tag == "entry")'
+ else
+ xml.unknown("read_new_style_drummap");
+ break;
+
+ case Xml::TagEnd:
+ if (tag == tagname)
+ return;
+
+ default:
+ break;
+ }
+ }
+}
} // namespace MusECore