summaryrefslogtreecommitdiff
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
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
-rw-r--r--muse2/muse/CMakeLists.txt2
-rw-r--r--muse2/muse/app.cpp2
-rw-r--r--muse2/muse/helper.cpp199
-rw-r--r--muse2/muse/helper.h12
-rw-r--r--muse2/muse/instruments/minstrument.cpp188
-rw-r--r--muse2/muse/instruments/minstrument.h47
-rw-r--r--muse2/muse/midiedit/dcanvas.cpp21
-rw-r--r--muse2/muse/midiedit/dlist.cpp2
-rw-r--r--muse2/muse/midiedit/drumedit.cpp2
-rw-r--r--muse2/muse/midiedit/drummap.cpp73
-rw-r--r--muse2/muse/midiedit/drummap.h7
-rw-r--r--muse2/muse/midiedit/scoreedit.cpp4
-rw-r--r--muse2/muse/song.cpp1
-rw-r--r--muse2/muse/track.cpp246
-rw-r--r--muse2/muse/track.h10
-rw-r--r--muse2/muse/trackdrummapupdater.cpp61
-rw-r--r--muse2/muse/trackdrummapupdater.h43
-rw-r--r--muse2/share/instruments/gs.idf367
-rw-r--r--muse2/share/instruments/xg.idf501
19 files changed, 1611 insertions, 177 deletions
diff --git a/muse2/muse/CMakeLists.txt b/muse2/muse/CMakeLists.txt
index 187bd41e..36645db4 100644
--- a/muse2/muse/CMakeLists.txt
+++ b/muse2/muse/CMakeLists.txt
@@ -65,6 +65,7 @@ QT4_WRAP_CPP ( muse_moc_headers
plugin.h
song.h
transport.h
+ trackdrummapupdater.h
value.h
steprec.h
)
@@ -132,6 +133,7 @@ file (GLOB core_source_files
thread.cpp
ticksynth.cpp
track.cpp
+ trackdrummapupdater.cpp
transport.cpp
undo.cpp
value.cpp
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp
index f63eb6e2..6a4e7c06 100644
--- a/muse2/muse/app.cpp
+++ b/muse2/muse/app.cpp
@@ -81,6 +81,7 @@
#include "tools.h"
#include "widgets/unusedwavefiles.h"
#include "functions.h"
+#include "trackdrummapupdater.h"
namespace MusECore {
extern void initMidiSynth();
@@ -346,6 +347,7 @@ MusE::MusE(int /*argc*/, char** /*argv*/) : QMainWindow()
MusEGlobal::heartBeatTimer->setObjectName("timer");
connect(MusEGlobal::heartBeatTimer, SIGNAL(timeout()), MusEGlobal::song, SLOT(beat()));
connect(this, SIGNAL(activeTopWinChanged(MusEGui::TopWin*)), SLOT(activeTopWinChangedSlot(MusEGui::TopWin*)));
+ new MusECore::TrackDrummapUpdater(); // no need for keeping the reference, the thing autoconnects on its own.
#ifdef ENABLE_PYTHON
//---------------------------------------------------
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
diff --git a/muse2/muse/helper.h b/muse2/muse/helper.h
index 8ef39346..2a26c08e 100644
--- a/muse2/muse/helper.h
+++ b/muse2/muse/helper.h
@@ -44,11 +44,21 @@ QString pitch2string(int v);
Part* partFromSerialNumber(int serial);
bool any_event_selected(const std::set<Part*>&, bool in_range=false);
-bool drummaps_almost_equal(DrumMap* one, DrumMap* two, int drummap_size=128);
+bool drummaps_almost_equal(const DrumMap* one, const DrumMap* two, int drummap_size=128);
+
+// drummap_hidden may be NULL.
+void write_new_style_drummap(int level, Xml& xml, const char* tagname,
+ DrumMap* drummap, bool* drummap_hidden=NULL, bool full=false);
+void read_new_style_drummap(Xml& xml, const char* tagname,
+ DrumMap* drummap, bool* drummap_hidden=NULL);
+
QSet<Part*> parts_at_tick(unsigned tick);
QSet<Part*> parts_at_tick(unsigned tick, const Track* track);
QSet<Part*> parts_at_tick(unsigned tick, const QSet<Track*>& tracks);
+
+bool parse_range(const QString& str, int* from, int* to); // returns true if successful, false on error
+
}
namespace MusEGui {
diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp
index a01903ae..3876fb28 100644
--- a/muse2/muse/instruments/minstrument.cpp
+++ b/muse2/muse/instruments/minstrument.cpp
@@ -41,6 +41,8 @@
#include "midictrl.h"
#include "gconfig.h"
#include "popupmenu.h"
+#include "drummap.h"
+#include "helper.h"
namespace MusECore {
@@ -364,6 +366,7 @@ void MidiInstrument::init()
MidiController* prog = new MidiController("Program", CTRL_PROGRAM, 0, 0xffffff, 0);
_controller->add(prog);
_dirty = false;
+
}
MidiInstrument::MidiInstrument()
@@ -408,8 +411,20 @@ MidiInstrument::~MidiInstrument()
if (_initScript)
delete _initScript;
+
+ clear_delete_patch_drummap_mapping();
}
+void MidiInstrument::clear_delete_patch_drummap_mapping()
+{
+ for (std::list<patch_drummap_mapping_t>::iterator it = patch_drummap_mapping.begin();
+ it!=patch_drummap_mapping.end(); it++)
+ delete[] it->drummap;
+
+ patch_drummap_mapping.clear();
+}
+
+
/*
//---------------------------------------------------------
// uniqueCopy
@@ -515,7 +530,20 @@ MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins)
_name = ins._name;
_filePath = ins._filePath;
-
+
+ clear_delete_patch_drummap_mapping();
+ // do a deep copy
+ for (std::list<patch_drummap_mapping_t>::const_iterator it = ins.patch_drummap_mapping.begin();
+ it!=ins.patch_drummap_mapping.end(); it++)
+ {
+ patch_drummap_mapping_t temp = *it;
+ temp.drummap=new DrumMap[128];
+ for (int i=0;i<128;i++)
+ temp.drummap[i]=it->drummap[i];
+ }
+
+
+
// Hmm, dirty, yes? But init sets it to false...
//_dirty = ins._dirty;
//_dirty = false;
@@ -733,6 +761,123 @@ void MidiInstrument::readMidiState(Xml& xml)
}
}
+void MidiInstrument::readDrummaps(Xml& xml)
+{
+ clear_delete_patch_drummap_mapping();
+
+ 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 == "entry")
+ patch_drummap_mapping.push_back(readDrummapsEntry(xml));
+ else
+ xml.unknown("MidiInstrument::readDrummaps");
+ break;
+
+ case Xml::TagEnd:
+ if (tag == "Drummaps")
+ return;
+
+ default:
+ break;
+ }
+ }
+ printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummaps()!\n"
+ " not returning anything. expect undefined behaviour or even crashes.\n");
+}
+
+patch_drummap_mapping_t MidiInstrument::readDrummapsEntry(Xml& xml)
+{
+ using std::list;
+
+ list<patch_collection_t> collection;
+ DrumMap* drummap=new DrumMap[128];
+ for (int i=0;i<128;i++)
+ drummap[i]=iNewDrumMap[i];
+
+ for (;;)
+ {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token)
+ {
+ case Xml::Error:
+ case Xml::End:
+ return patch_drummap_mapping_t(collection, drummap);
+
+ case Xml::TagStart:
+ if (tag == "patch_collection")
+ collection.push_back(readDrummapsEntryPatchCollection(xml));
+ else if (tag == "drummap")
+ read_new_style_drummap(xml, "drummap", drummap);
+ else
+ xml.unknown("MidiInstrument::readDrummapsEntry");
+ break;
+
+ case Xml::TagEnd:
+ if (tag == "entry")
+ return patch_drummap_mapping_t(collection, drummap);
+
+ default:
+ break;
+ }
+ }
+ printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummapsEntry()!\n"
+ " not returning anything. expect undefined behaviour or even crashes.\n");
+ return patch_drummap_mapping_t();
+}
+
+patch_collection_t MidiInstrument::readDrummapsEntryPatchCollection(Xml& xml)
+{
+ int first_prog=0, last_prog=256; // this means:
+ int first_lbank=0, last_lbank=256; // "does not matter"
+ int first_hbank=0, last_hbank=256;
+
+ for (;;)
+ {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token)
+ {
+ case Xml::Error:
+ case Xml::End:
+ return patch_collection_t(-1,-1,-1,-1,-1,-1); // an invalid collection
+
+ case Xml::TagStart:
+ xml.unknown("MidiInstrument::readDrummapsEntryPatchCollection");
+ break;
+
+ case Xml::Attribut:
+ if (tag == "prog")
+ parse_range(xml.s2(), &first_prog, &last_prog);
+ else if (tag == "lbank")
+ parse_range(xml.s2(), &first_lbank, &last_lbank);
+ else if (tag == "hbank")
+ parse_range(xml.s2(), &first_hbank, &last_hbank);
+ break;
+
+ case Xml::TagEnd:
+ if (tag == "patch_collection")
+ return patch_collection_t(first_prog, last_prog, first_lbank, last_lbank, first_hbank, last_hbank);
+
+ default:
+ break;
+ }
+ }
+
+ printf("ERROR: THIS CANNOT HAPPEN: exited infinite loop in MidiInstrument::readDrummapsEntryPatchCollection()!\n"
+ " not returning anything. expect undefined behaviour or even crashes.\n");
+}
+
+
//---------------------------------------------------------
// read
//---------------------------------------------------------
@@ -785,6 +930,9 @@ void MidiInstrument::read(Xml& xml)
_controller->add(mc);
}
+ else if (tag == "Drummaps") {
+ readDrummaps(xml);
+ }
else if (tag == "Init")
readEventList(xml, _midiInit, "Init");
else if (tag == "Reset")
@@ -794,7 +942,7 @@ void MidiInstrument::read(Xml& xml)
else if (tag == "InitScript") {
if (_initScript)
delete _initScript;
- QByteArray ba = xml.parse1().toLatin1();
+ QByteArray ba = xml.parse1().toLatin1();
const char* istr = ba.constData();
int len = strlen(istr) +1;
if (len > 1) {
@@ -998,4 +1146,40 @@ void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MTyp
}
+const DrumMap* MidiInstrument::drummap_for_patch(int patch) const
+{
+ using std::list;
+
+ int program = (patch & 0x0000FF);
+ int lbank = (patch & 0x00FF00) >> 8;
+ int hbank = (patch & 0xFF0000) >> 16;
+
+ for (list<patch_drummap_mapping_t>::const_iterator it=patch_drummap_mapping.begin();
+ it!=patch_drummap_mapping.end(); it++)
+ {
+ for (list<patch_collection_t>::const_iterator it2=it->affected_patches.begin();
+ it2!=it->affected_patches.end(); it2++)
+ {
+ // if the entry matches our patch
+ if ( (program >= it2->first_program && program <= it2->last_program) &&
+ (hbank >= it2->first_hbank && hbank <= it2->last_hbank) &&
+ (lbank >= it2->first_lbank && lbank <= it2->last_lbank) )
+ {
+ return it->drummap;
+ }
+ }
+ }
+
+ // if nothing was found
+ return iNewDrumMap;
+}
+
+patch_drummap_mapping_t::patch_drummap_mapping_t()
+{
+ drummap=new DrumMap[128];
+ for (int i=0;i<128;i++)
+ drummap[i]=iNewDrumMap[i];
+}
+
+
} // namespace MusECore
diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h
index 385e67b4..9a65598b 100644
--- a/muse2/muse/instruments/minstrument.h
+++ b/muse2/muse/instruments/minstrument.h
@@ -40,6 +40,7 @@ class MidiControllerList;
class MidiPort;
class MidiPlayEvent;
class Xml;
+class DrumMap;
//---------------------------------------------------------
@@ -80,6 +81,43 @@ struct SysEx {
unsigned char* data;
};
+
+
+struct patch_collection_t
+{
+ int first_program;
+ int last_program;
+ int first_hbank;
+ int last_hbank;
+ int first_lbank;
+ int last_lbank;
+
+ patch_collection_t(int p1=0, int p2=127, int l1=0, int l2=127, int h1=0, int h2=127)
+ {
+ first_program=p1;
+ last_program=p2;
+ first_lbank=l1;
+ last_lbank=l2;
+ first_hbank=h1;
+ last_hbank=h2;
+ }
+
+};
+
+struct patch_drummap_mapping_t
+{
+ std::list<patch_collection_t> affected_patches;
+ DrumMap* drummap;
+
+ patch_drummap_mapping_t(const std::list<patch_collection_t>& a, DrumMap* d)
+ {
+ affected_patches=a;
+ drummap=d;
+ }
+
+ patch_drummap_mapping_t();
+};
+
//---------------------------------------------------------
// MidiInstrument
//---------------------------------------------------------
@@ -88,6 +126,7 @@ class MidiInstrument {
PatchGroupList pg;
MidiControllerList* _controller;
QList<SysEx*> _sysex;
+ std::list<patch_drummap_mapping_t> patch_drummap_mapping;
bool _dirty;
int _nullvalue;
@@ -103,6 +142,12 @@ class MidiInstrument {
char* _initScript;
QString _name;
QString _filePath;
+
+ void clear_delete_patch_drummap_mapping();
+
+ void readDrummaps(Xml& xml);
+ patch_drummap_mapping_t readDrummapsEntry(Xml& xml);
+ patch_collection_t readDrummapsEntryPatchCollection(Xml& xml);
public:
MidiInstrument();
@@ -123,6 +168,8 @@ class MidiInstrument {
void removeSysex(SysEx* sysex) { _sysex.removeAll(sysex); }
void addSysex(SysEx* sysex) { _sysex.append(sysex); }
+ const DrumMap* drummap_for_patch(int patch) const;
+
EventList* midiInit() const { return _midiInit; }
EventList* midiReset() const { return _midiReset; }
EventList* midiState() const { return _midiState; }
diff --git a/muse2/muse/midiedit/dcanvas.cpp b/muse2/muse/midiedit/dcanvas.cpp
index 4c033946..ad0226da 100644
--- a/muse2/muse/midiedit/dcanvas.cpp
+++ b/muse2/muse/midiedit/dcanvas.cpp
@@ -1008,6 +1008,19 @@ void DrumCanvas::mapChanged(int spitch, int dpitch)
using MusEGlobal::global_drum_ordering_t;
using MusEGlobal::global_drum_ordering;
+ for (QSet<MusECore::Track*>::iterator it=instrument_map[spitch].tracks.begin();
+ it!=instrument_map[spitch].tracks.end(); it++)
+ {
+ if (dynamic_cast<MusECore::MidiTrack*>(*it))
+ dynamic_cast<MusECore::MidiTrack*>(*it)->set_drummap_ordering_tied_to_patch(false);
+ }
+ for (QSet<MusECore::Track*>::iterator it=instrument_map[dpitch].tracks.begin();
+ it!=instrument_map[dpitch].tracks.end(); it++)
+ {
+ if (dynamic_cast<MusECore::MidiTrack*>(*it))
+ dynamic_cast<MusECore::MidiTrack*>(*it)->set_drummap_ordering_tied_to_patch(false);
+ }
+
MusECore::DrumMap dm_temp = ourDrumMap[spitch];
instrument_number_mapping_t im_temp = instrument_map[spitch];
@@ -1450,9 +1463,13 @@ void DrumCanvas::propagate_drummap_change(int instr, bool update_druminmap)
for (QSet<MusECore::Track*>::const_iterator it = tracks.begin(); it != tracks.end(); it++)
{
- dynamic_cast<MusECore::MidiTrack*>(*it)->drummap()[index] = ourDrumMap[instr];
+ MusECore::MidiTrack* mt=dynamic_cast<MusECore::MidiTrack*>(*it);
+ // if we're not only changing "mute" state...
+ if (!mt->drummap()[index].almost_equals(ourDrumMap[instr]))
+ mt->set_drummap_tied_to_patch(false);
+ mt->drummap()[index] = ourDrumMap[instr];
if (update_druminmap)
- dynamic_cast<MusECore::MidiTrack*>(*it)->update_drum_in_map();
+ mt->update_drum_in_map();
}
}
diff --git a/muse2/muse/midiedit/dlist.cpp b/muse2/muse/midiedit/dlist.cpp
index 2eb5e64a..fc6384f7 100644
--- a/muse2/muse/midiedit/dlist.cpp
+++ b/muse2/muse/midiedit/dlist.cpp
@@ -401,6 +401,7 @@ void DList::viewMousePressEvent(QMouseEvent* ev)
{
MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(*it);
mt->drummap()[mt->map_drum_in(val)].enote=dm->enote;
+ mt->set_drummap_tied_to_patch(false);
}
// propagating this is unneccessary as it's already done.
// updating the drumInmap is unneccessary, as the propagate call below
@@ -900,6 +901,7 @@ void DList::pitchEdited()
{
MusECore::MidiTrack* mt = dynamic_cast<MusECore::MidiTrack*>(*it);
mt->drummap()[mt->map_drum_in(val)].enote=editEntry->enote;
+ mt->set_drummap_tied_to_patch(false);
}
// propagating this is unneccessary as it's already done.
// updating the drumInmap is unneccessary, as the propagate call below
diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp
index 3bb48705..1f159d1a 100644
--- a/muse2/muse/midiedit/drumedit.cpp
+++ b/muse2/muse/midiedit/drumedit.cpp
@@ -644,7 +644,7 @@ DrumEdit::DrumEdit(MusECore::PartList* pl, QWidget* parent, const char* name, un
void DrumEdit::songChanged1(int bits)
{
- if(_isDeleting) // Ignore while while deleting to prevent crash.
+ if(_isDeleting) // Ignore while deleting to prevent crash.
return;
if (bits & SC_SOLO)
diff --git a/muse2/muse/midiedit/drummap.cpp b/muse2/muse/midiedit/drummap.cpp
index 2705a252..d86bcd65 100644
--- a/muse2/muse/midiedit/drummap.cpp
+++ b/muse2/muse/midiedit/drummap.cpp
@@ -43,15 +43,13 @@ namespace MusECore {
const DrumMap blankdm = { QString(""), 100, 16, 32, 9, 0, 70, 90, 127, 110, 127, 127, false };
-// this map must have 128 entries, as it's used for initalising new-style-drummaps as well.
-// new-style-drummaps only have 128 entries. also, the every "out-note" ("anote") must be
-// represented exactly once in that map, and there may be no duplicate or unused "out-notes".
-// reason: the track's drummap are inited as follows: iterate through the full idrumMap[],
-// tracks_drummap[ idrumMap[i].anote ] = idrumMap[i]
-// if you ever want to change this, you will need to go through track.cpp/.h and
-// {dlist,dcanvas,drumedit,drummap}{.cpp,.h} (and possibly some more) and find every usage
-// of idrumMap by new style drummaps, and fix the problem. a possible fix would be duplicating
-// idrumMap, change idrumMap, and use the duplicate for the new style stuff instead.
+// this map should have 128 entries, as it's used for initalising iNewDrumMap as well.
+// iNewDrumMap only has 128 entries. also, the every "out-note" ("anote") should be
+// represented exactly once in idrumMap, and there shall be no duplicate or unused
+// "out-notes".
+// reason: iNewDrumMap is inited as follows: iterate through the full idrumMap[],
+// iNewDrumMap[ idrumMap[i].anote ] = idrumMap[i]
+// if you ever want to change this, you will need to fix the initNewDrumMap() function.
const DrumMap idrumMap[DRUM_MAPSIZE] = {
{ QString("Acoustic Bass Drum"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 35, 35, false },
{ QString("Bass Drum 1"), 100, 16, 32, 9, 0, 70, 90, 127, 110, 36, 36, false },
@@ -261,6 +259,55 @@ const DrumMap idrumMap[DRUM_MAPSIZE] = {
{ QString(""), 100, 16, 32, 9, 0, 70, 90, 127, 110, 34, 34, false }
};
+DrumMap iNewDrumMap[128];
+
+void initNewDrumMap()
+{
+ bool done[128];
+ for (int i=0;i<128;i++) done[i]=false;
+
+ for (int i=0;i<DRUM_MAPSIZE;i++)
+ {
+ int idx=idrumMap[i].anote;
+ if (idx < 0 || idx >= 128)
+ printf("ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx);
+ else
+ {
+ if (done[idx]==true)
+ {
+ printf("ERROR: iNewDrumMap[%i] is already initalized!\n"
+ " this will be probably not a problem, but some programmer didn't read\n"
+ " flo's comment at drummap.cpp, above idrumMap[].\n", idx);
+ }
+ else
+ {
+ iNewDrumMap[idx]=idrumMap[i];
+ done[idx]=true;
+ }
+ }
+ }
+
+ for (int i=0;i<128;i++)
+ {
+ if (done[i]==false)
+ {
+ printf("ERROR: iNewDrumMap[%i] is uninitalized!\n"
+ " this will be probably not a problem, but some programmer didn't read\n"
+ " flo's comment at drummap.cpp, above idrumMap[].\n", i);
+ iNewDrumMap[i].name="";
+ iNewDrumMap[i].vol=100;
+ iNewDrumMap[i].quant=16;
+ iNewDrumMap[i].len=32;
+ iNewDrumMap[i].lv1=70;
+ iNewDrumMap[i].lv2=90;
+ iNewDrumMap[i].lv3=127;
+ iNewDrumMap[i].lv4=110;
+ iNewDrumMap[i].enote=i;
+ iNewDrumMap[i].anote=i;
+ }
+ }
+}
+
//---------------------------------------------------------
// initDrumMap
@@ -332,6 +379,14 @@ bool DrumMap::operator==(const DrumMap& map) const
&& mute == map.mute;
}
+bool DrumMap::almost_equals(const DrumMap& map) const
+{
+ DrumMap tmp=map;
+ tmp.mute=this->mute;
+ return tmp==*this;
+}
+
+
//---------------------------------------------------------
// writeDrumMap
//---------------------------------------------------------
diff --git a/muse2/muse/midiedit/drummap.h b/muse2/muse/midiedit/drummap.h
index 3b6ffaf3..7f28b068 100644
--- a/muse2/muse/midiedit/drummap.h
+++ b/muse2/muse/midiedit/drummap.h
@@ -49,12 +49,15 @@ struct DrumMap {
bool operator==(const DrumMap& map) const;
bool operator!=(const DrumMap& map) const { return !operator==(map); }
+ bool almost_equals(const DrumMap& map) const;
};
-// please let this at "128". idrumMap must have length 128 (see drummap.cpp for details)
+// please let this at "128". idrumMap should have length 128 (see drummap.cpp for details)
#define DRUM_MAPSIZE 128
-extern const DrumMap idrumMap[DRUM_MAPSIZE]; //FINDMICH dummy!
+extern DrumMap iNewDrumMap[128];
+extern void initNewDrumMap();
+
extern void initDrumMap();
extern void writeDrumMap(int level, Xml& xml, bool external);
extern void readDrumMap(Xml& xml, bool external);
diff --git a/muse2/muse/midiedit/scoreedit.cpp b/muse2/muse/midiedit/scoreedit.cpp
index c10adafd..055134e2 100644
--- a/muse2/muse/midiedit/scoreedit.cpp
+++ b/muse2/muse/midiedit/scoreedit.cpp
@@ -4686,8 +4686,8 @@ void ScoreCanvas::add_new_parts(const std::map< MusECore::Part*, std::set<MusECo
* ("BUGGY! problem is: while changing entries, ourDrumMap
* may be reallocated which causes abort()s and/or bugs.")
* [ seems to work now, needs further testing! ]
- * > o my record flag handling
- * o once, using super glue while a score editor displaying the glued
+ * x my record flag handling
+ * * once, using super glue while a score editor displaying the glued
* parts is open let muse segfault. this may or may not be fixed
* now. check!
* state of revision #1337: no segfaults, but the score editors
diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp
index 484e2d42..69900bbc 100644
--- a/muse2/muse/song.cpp
+++ b/muse2/muse/song.cpp
@@ -2074,6 +2074,7 @@ void Song::clear(bool signal, bool clear_all)
// _tempo = 500000; // default tempo 120
dirty = false;
initDrumMap();
+ initNewDrumMap();
if (signal) {
emit loopChanged(false);
recordChanged(false);
diff --git a/muse2/muse/track.cpp b/muse2/muse/track.cpp
index 4dd2e0c5..595a25e7 100644
--- a/muse2/muse/track.cpp
+++ b/muse2/muse/track.cpp
@@ -34,6 +34,8 @@
#include "globaldefs.h"
#include "route.h"
#include "drummap.h"
+#include "midictrl.h"
+#include "helper.h"
namespace MusECore {
@@ -618,19 +620,28 @@ void MidiTrack::init()
_recEcho = true;
}
+void MidiTrack::init_drum_ordering()
+{
+ // first display entries with non-empty names, then with empty names.
+
+ remove_ourselves_from_drum_ordering();
+
+ for (int i=0;i<128;i++)
+ if (_drummap[i].name!="" && _drummap[i].name!="?") // non-empty name?
+ MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,i));
+
+ for (int i=0;i<128;i++)
+ if (!(_drummap[i].name!="" && _drummap[i].name!="?")) // empty name?
+ MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,i));
+}
+
void MidiTrack::init_drummap(bool write_ordering)
{
for (int i=0;i<128;i++)
- {
- int idx=idrumMap[i].anote;
- if (idx < 0 || idx >= 128)
- printf ("ERROR: THIS SHOULD NEVER HAPPEN: idrumMap[%i].anote is not within 0..127!\n", idx);
- else
- _drummap[idx]=idrumMap[i];
-
- if (write_ordering)
- MusEGlobal::global_drum_ordering.push_back(std::pair<MidiTrack*,int>(this,idx));
- }
+ _drummap[i]=iNewDrumMap[i];
+
+ if (write_ordering)
+ init_drum_ordering();
update_drum_in_map();
@@ -638,6 +649,7 @@ void MidiTrack::init_drummap(bool write_ordering)
_drummap_hidden[i]=false;
_drummap_tied_to_patch=true;
+ _drummap_ordering_tied_to_patch=true;
}
void MidiTrack::update_drum_in_map()
@@ -945,62 +957,14 @@ void MidiTrack::writeOurDrumSettings(int level, Xml& xml) const
writeOurDrumMap(level, xml, false);
xml.intTag(level, "tied", _drummap_tied_to_patch);
+ xml.intTag(level, "ordering_tied", _drummap_ordering_tied_to_patch);
xml.etag(level, "our_drum_settings");
}
void MidiTrack::writeOurDrumMap(int level, Xml& xml, bool full) const
{
- xml.tag(level++, "our_drummap");
-
- for (int i=0;i<128;i++)
- {
- int j;
- for (j=0;j<128;j++)
- if (idrumMap[j].anote == i) break;
-
- if (j==128)
- printf("THIS SHOULD NEVER HAPPEN: couldn't find initial drum map entry in MidiTrack::writeOurDrumMap()\n");
- else
- {
- DrumMap* dm = &_drummap[i];
- const DrumMap* idm = &idrumMap[j];
-
- 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[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 (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, "our_drummap");
+ write_new_style_drummap(level, xml, "our_drummap", _drummap, _drummap_hidden, full);
}
//---------------------------------------------------------
@@ -1095,6 +1059,8 @@ void MidiTrack::readOurDrumSettings(Xml& xml)
case Xml::TagStart:
if (tag == "tied")
_drummap_tied_to_patch = xml.parseInt();
+ else if (tag == "ordering_tied")
+ _drummap_ordering_tied_to_patch = xml.parseInt();
else if (tag == "our_drummap")
readOurDrumMap(xml);
else
@@ -1115,98 +1081,9 @@ void MidiTrack::readOurDrumMap(Xml& xml, bool dont_init)
{
if (!dont_init) init_drummap(false);
_drummap_tied_to_patch=false;
-
- 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 MidiTrack::readOurDrumMap()!\n");
- else
- {
- dm = &_drummap[pitch];
- hidden = &_drummap_hidden[pitch];
- }
- }
- 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 MidiTrack::readOurDrumMap()!\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")
- *hidden = xml.parseInt();
- else
- xml.unknown("MidiTrack::readOurDrumMap");
- 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("MidiTrack::readOurDrumMap");
- break;
-
- case Xml::TagEnd:
- if (tag == "our_drummap")
- {
- update_drum_in_map();
- return;
- }
-
- default:
- break;
- }
- }
+ _drummap_ordering_tied_to_patch=false;
+ read_new_style_drummap(xml, "our_drummap", _drummap, _drummap_hidden);
+ update_drum_in_map();
}
@@ -1395,4 +1272,69 @@ void Track::writeRouting(int level, Xml& xml) const
}
}
+int MidiTrack::getFirstControllerValue(int ctrl, int def)
+{
+ int val=def;
+ unsigned tick=-1; // maximum integer
+
+ for (iPart pit=parts()->begin(); pit!=parts()->end(); pit++)
+ {
+ Part* part=pit->second;
+ if (part->tick() > tick) break; // ignore this and the rest. we won't find anything new.
+ for (iEvent eit=part->events()->begin(); eit!=part->events()->end(); eit++)
+ {
+ if (eit->first+part->tick() >= tick) break;
+ // else if (eit->first+part->tick() < tick) and
+ if (eit->second.type()==Controller && eit->second.dataA()==ctrl)
+ {
+ val = eit->second.dataB();
+ tick = eit->first+part->tick();
+ break;
+ }
+ }
+ }
+
+ return val;
+}
+
+
+// returns true if the autoupdate changed something
+bool MidiTrack::auto_update_drummap()
+{
+ if (_drummap_tied_to_patch)
+ {
+ int patch = getFirstControllerValue(CTRL_PROGRAM,0);
+ const DrumMap* new_drummap = MusEGlobal::midiPorts[_outPort].instrument()->drummap_for_patch(patch);
+
+ if (!drummaps_almost_equal(new_drummap, this->drummap(), 128))
+ {
+ for (int i=0;i<128;i++)
+ {
+ bool temp_mute=_drummap[i].mute;
+ _drummap[i]=new_drummap[i];
+ _drummap[i].mute=temp_mute;
+ }
+
+ if (_drummap_ordering_tied_to_patch)
+ init_drum_ordering();
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void MidiTrack::set_drummap_tied_to_patch(bool val)
+{
+ _drummap_tied_to_patch=val;
+ if (val) auto_update_drummap();
+}
+
+void MidiTrack::set_drummap_ordering_tied_to_patch(bool val)
+{
+ _drummap_ordering_tied_to_patch=val;
+ if (val && _drummap_tied_to_patch) init_drum_ordering();
+}
+
} // namespace MusECore
diff --git a/muse2/muse/track.h b/muse2/muse/track.h
index f2e12e3a..1df8cad0 100644
--- a/muse2/muse/track.h
+++ b/muse2/muse/track.h
@@ -236,11 +236,13 @@ class MidiTrack : public Track {
DrumMap* _drummap; // _drummap[foo].anote is always equal to foo
bool* _drummap_hidden; // _drummap und _drummap_hidden will be an array[128]
bool _drummap_tied_to_patch; //if true, changing patch also changes drummap
+ bool _drummap_ordering_tied_to_patch; //if true, changing patch also changes drummap-ordering
int drum_in_map[128];
void init();
void init_drummap(bool write_ordering); // function without argument in public
void remove_ourselves_from_drum_ordering();
+ void init_drum_ordering();
void writeOurDrumSettings(int level, Xml& xml) const;
void readOurDrumSettings(Xml& xml);
@@ -310,6 +312,8 @@ class MidiTrack : public Track {
virtual bool canRecord() const { return true; }
static void setVisible(bool t) { _isVisible = t; }
static bool visible() { return _isVisible; }
+
+ int getFirstControllerValue(int ctrl, int def=-1);
void setClef(clefTypes i) { clefType = i; }
clefTypes getClef() { return clefType; }
@@ -320,6 +324,12 @@ class MidiTrack : public Track {
void update_drum_in_map();
void init_drummap() { init_drummap(false); } // function with argument in private
+
+ bool auto_update_drummap();
+ void set_drummap_tied_to_patch(bool);
+ bool drummap_tied_to_patch() { return _drummap_tied_to_patch; }
+ void set_drummap_ordering_tied_to_patch(bool);
+ bool drummap_ordering_tied_to_patch() { return _drummap_ordering_tied_to_patch; }
//void writeOurDrumSettings(int level, Xml& xml) const; // above in private:
//void readOurDrumSettings(Xml& xml); // above in private:
diff --git a/muse2/muse/trackdrummapupdater.cpp b/muse2/muse/trackdrummapupdater.cpp
new file mode 100644
index 00000000..35d5c056
--- /dev/null
+++ b/muse2/muse/trackdrummapupdater.cpp
@@ -0,0 +1,61 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: trackdrummapupdater.cpp,v 1.59.2.52 2011/12/27 20:25:58 flo93 Exp $
+//
+// (C) Copyright 2011 Florian Jung (florian.a.jung (at) web.de)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+
+#include "trackdrummapupdater.h"
+#include "song.h"
+#include "globals.h"
+
+namespace MusECore {
+
+using MusEGlobal::song;
+
+TrackDrummapUpdater::TrackDrummapUpdater()
+{
+ connect(song,SIGNAL(songChanged(int)), this, SLOT(songChanged(int)));
+}
+
+void TrackDrummapUpdater::songChanged(int flags)
+{
+ if (flags & (SC_TRACK_INSERTED | SC_TRACK_REMOVED | SC_TRACK_MODIFIED |
+ SC_PART_INSERTED | SC_PART_REMOVED | SC_PART_MODIFIED |
+ SC_EVENT_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED ) )
+ {
+ bool changed=false;
+ for (iTrack t=song->tracks()->begin(); t!=song->tracks()->end(); t++)
+ {
+ MidiTrack* track=dynamic_cast<MidiTrack*>(*t);
+ if (track && track->auto_update_drummap())
+ changed=true;
+ }
+
+ if (changed)
+ {
+ // allow recursion. there will be no more recursion, because this
+ // is only executed when something other than SC_DRUMMAP happens
+ song->update(SC_DRUMMAP, true);
+ }
+
+ }
+}
+
+} //namespace MusECore
diff --git a/muse2/muse/trackdrummapupdater.h b/muse2/muse/trackdrummapupdater.h
new file mode 100644
index 00000000..caa2ac28
--- /dev/null
+++ b/muse2/muse/trackdrummapupdater.h
@@ -0,0 +1,43 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: trackdrummapupdater.h,v 1.59.2.52 2011/12/27 20:25:58 flo93 Exp $
+//
+// (C) Copyright 2011 Florian Jung (florian.a.jung (at) web.de)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; version 2 of
+// the License, or (at your option) any later version.
+//
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+//=========================================================
+
+#ifndef __TRACKDRUMMAPUPDATER_H__
+#define __TRACKDRUMMAPUPDATER_H__
+
+#include <QObject>
+
+namespace MusECore {
+
+class TrackDrummapUpdater : public QObject
+{
+ Q_OBJECT
+
+ public:
+ TrackDrummapUpdater();
+
+ private slots:
+ void songChanged(int flags);
+};
+
+} //namespace MusECore
+#endif
diff --git a/muse2/share/instruments/gs.idf b/muse2/share/instruments/gs.idf
index 3368b7c9..1e8a54c0 100644
--- a/muse2/share/instruments/gs.idf
+++ b/muse2/share/instruments/gs.idf
@@ -214,5 +214,372 @@
<Controller name="DrumChorusSend" type="NRPN" h="30" l="pitch" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
+ <Drummaps>
+ <entry>
+ <patch_collection hbank="127" prog="0-7" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Kick Drum 2</name> </entry>
+ <entry pitch="36"> <name>Kick Drum 1</name> </entry>
+ <entry pitch="38"> <name>Snare Drum 1</name> </entry>
+ <entry pitch="40"> <name>Snare Drum 2</name> </entry>
+ <entry pitch="41"> <name>Low Tom 2</name> </entry>
+ <entry pitch="43"> <name>Low Tom 1</name> </entry>
+ <entry pitch="45"> <name>Mid Tom 2</name> </entry>
+ <entry pitch="47"> <name>Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>High Tom 2</name> </entry>
+ <entry pitch="50"> <name>High Tom 1</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="8-15" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Kick Drum 2</name> </entry>
+ <entry pitch="36"> <name>Kick Drum 1</name> </entry>
+ <entry pitch="38"> <name>Snare Drum 1</name> </entry>
+ <entry pitch="40"> <name>Snare Drum 2</name> </entry>
+ <entry pitch="41"> <name>Room Low Tom 2</name> </entry>
+ <entry pitch="43"> <name>Room Low Tom 1</name> </entry>
+ <entry pitch="45"> <name>Room Mid Tom 2</name> </entry>
+ <entry pitch="47"> <name>Room Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>Room High Tom 2</name> </entry>
+ <entry pitch="50"> <name>Room High Tom 1</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="16-23" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Kick Drum 2</name> </entry>
+ <entry pitch="36"> <name>Mondo Kick</name> </entry>
+ <entry pitch="38"> <name>Gated Snare</name> </entry>
+ <entry pitch="40"> <name>Snare Drum 2</name> </entry>
+ <entry pitch="41"> <name>Room Low Tom 2</name> </entry>
+ <entry pitch="43"> <name>Room Low Tom 1</name> </entry>
+ <entry pitch="45"> <name>Room Mid Tom 2</name> </entry>
+ <entry pitch="47"> <name>Room Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>Room High Tom 2</name> </entry>
+ <entry pitch="50"> <name>Room High Tom 1</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="24" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Kick Drum 2</name> </entry>
+ <entry pitch="36"> <name>Elec. Bass Drum</name> </entry>
+ <entry pitch="38"> <name>Elec. Snare</name> </entry>
+ <entry pitch="40"> <name>Gated Snare</name> </entry>
+ <entry pitch="41"> <name>Elec. Low Tom 2</name> </entry>
+ <entry pitch="43"> <name>Elec. Low Tom 1</name> </entry>
+ <entry pitch="45"> <name>Elec. Mid Tom 2</name> </entry>
+ <entry pitch="47"> <name>Elec. Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>Elec. High Tom 2</name> </entry>
+ <entry pitch="50"> <name>Elec. High Tom 1</name> </entry>
+ <entry pitch="52"> <name>Reverse Cymbal</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="25-31" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Kick Drum 2</name> </entry>
+ <entry pitch="36"> <name>808 Bass Drum</name> </entry>
+ <entry pitch="37"> <name>808 Rim Shot</name> </entry>
+ <entry pitch="38"> <name>808 Snare Drum</name> </entry>
+ <entry pitch="40"> <name>Snare Drum 2</name> </entry>
+ <entry pitch="41"> <name>808 Low Tom 2</name> </entry>
+ <entry pitch="42"> <name>808 Closed Hi-Hat</name> </entry>
+ <entry pitch="43"> <name>808 Low Tom 1</name> </entry>
+ <entry pitch="44"> <name>808 Pedal Hi-Hat</name> </entry>
+ <entry pitch="45"> <name>808 Tom 2</name> </entry>
+ <entry pitch="46"> <name>808 Open Hi-Hat</name> </entry>
+ <entry pitch="47"> <name>808 Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>808 High Tom 2</name> </entry>
+ <entry pitch="49"> <name>808 Cymbal</name> </entry>
+ <entry pitch="50"> <name>808 High Tom 1</name> </entry>
+ <entry pitch="52"> <name>Reverse Cymbal</name> </entry>
+ <entry pitch="56"> <name>808 Cowbell</name> </entry>
+ <entry pitch="62"> <name>808 High Conga</name> </entry>
+ <entry pitch="63"> <name>808 Mid Conga</name> </entry>
+ <entry pitch="64"> <name>808 Low Conga</name> </entry>
+ <entry pitch="70"> <name>808 Maracas</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="32-39" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Jazz Bass Drum 2</name> </entry>
+ <entry pitch="36"> <name>Jazz Bass Drum 1</name> </entry>
+ <entry pitch="38"> <name>Snare Drum 1</name> </entry>
+ <entry pitch="40"> <name>Snare Drum 2</name> </entry>
+ <entry pitch="41"> <name>Low Tom 2</name> </entry>
+ <entry pitch="43"> <name>Low Tom 1</name> </entry>
+ <entry pitch="45"> <name>Mid Tom 2</name> </entry>
+ <entry pitch="47"> <name>Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>High Tom 2</name> </entry>
+ <entry pitch="50"> <name>High Tom 1</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="40-47" />
+ <drummap>
+ <entry pitch="27"> <name>High Q</name> </entry>
+ <entry pitch="28"> <name>Slap</name> </entry>
+ <entry pitch="29"> <name>Scratch Push</name> </entry>
+ <entry pitch="30"> <name>Scratch Pull</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Jazz Bass Drum 2</name> </entry>
+ <entry pitch="36"> <name>Jazz Bass Drum 1</name> </entry>
+ <entry pitch="38"> <name>Brush Tap</name> </entry>
+ <entry pitch="39"> <name>Brush Slap</name> </entry>
+ <entry pitch="40"> <name>Brush Swirl</name> </entry>
+ <entry pitch="41"> <name>Low Tom 2</name> </entry>
+ <entry pitch="43"> <name>Low Tom 1</name> </entry>
+ <entry pitch="45"> <name>Mid Tom 2</name> </entry>
+ <entry pitch="47"> <name>Mid Tom 1</name> </entry>
+ <entry pitch="48"> <name>High Tom 2</name> </entry>
+ <entry pitch="50"> <name>High Tom 1</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="48-55" />
+ <drummap>
+ <entry pitch="27"> <name>Closed Hi-Hat</name> </entry>
+ <entry pitch="28"> <name>Pedal Hi-Hat</name> </entry>
+ <entry pitch="29"> <name>Open Hi-Hat</name> </entry>
+ <entry pitch="30"> <name>Ride Cymbal</name> </entry>
+ <entry pitch="31"> <name>Sticks</name> </entry>
+ <entry pitch="32"> <name>Square Click</name> </entry>
+ <entry pitch="33"> <name>Metronome Click</name> </entry>
+ <entry pitch="34"> <name>Metronome Bell</name> </entry>
+ <entry pitch="35"> <name>Concert Bass Drum 2</name> </entry>
+ <entry pitch="36"> <name>Concert Bass Drum 1</name> </entry>
+ <entry pitch="38"> <name>Concert Snare Drum</name> </entry>
+ <entry pitch="39"> <name>Castanets</name> </entry>
+ <entry pitch="40"> <name>Concert Snare Drum</name> </entry>
+ <entry pitch="41"> <name>Timpani F</name> </entry>
+ <entry pitch="42"> <name>Timpani F#</name> </entry>
+ <entry pitch="43"> <name>Timpani G</name> </entry>
+ <entry pitch="44"> <name>Timpani G#</name> </entry>
+ <entry pitch="45"> <name>Timpani A</name> </entry>
+ <entry pitch="46"> <name>Timpani A#</name> </entry>
+ <entry pitch="47"> <name>Timpani B</name> </entry>
+ <entry pitch="48"> <name>Timpani C</name> </entry>
+ <entry pitch="49"> <name>Timpani C#</name> </entry>
+ <entry pitch="50"> <name>Timpani D</name> </entry>
+ <entry pitch="51"> <name>Timpani D#</name> </entry>
+ <entry pitch="52"> <name>Timpani E</name> </entry>
+ <entry pitch="53"> <name>Timpani F</name> </entry>
+ <entry pitch="57"> <name>Concert Cymbal 2</name> </entry>
+ <entry pitch="59"> <name>Concert Cymbal 1</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ <entry pitch="85"> <name>Castanets</name> </entry>
+ <entry pitch="86"> <name>Mute Surdo</name> </entry>
+ <entry pitch="87"> <name>Open Surdo</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="56-126" />
+ <drummap>
+ <entry pitch="35"> <name></name> </entry>
+ <entry pitch="36"> <name></name> </entry>
+ <entry pitch="37"> <name></name> </entry>
+ <entry pitch="38"> <name></name> </entry>
+ <entry pitch="39"> <name>High Q</name> </entry>
+ <entry pitch="40"> <name>Slap</name> </entry>
+ <entry pitch="41"> <name>Scratch Push</name> </entry>
+ <entry pitch="42"> <name>Scratch Pull</name> </entry>
+ <entry pitch="43"> <name>Sticks</name> </entry>
+ <entry pitch="44"> <name>Square Click</name> </entry>
+ <entry pitch="45"> <name>Metronome Click</name> </entry>
+ <entry pitch="46"> <name>Metronome Bell</name> </entry>
+ <entry pitch="47"> <name>Guitar Fret Noise</name> </entry>
+ <entry pitch="48"> <name>Guitar Cut Noise Up</name> </entry>
+ <entry pitch="49"> <name>Guitar Cut Noise Down</name> </entry>
+ <entry pitch="50"> <name>Double Bass String Slap</name> </entry>
+ <entry pitch="51"> <name>Flute Key Click</name> </entry>
+ <entry pitch="52"> <name>Laughing</name> </entry>
+ <entry pitch="53"> <name>Screaming</name> </entry>
+ <entry pitch="54"> <name>Punch</name> </entry>
+ <entry pitch="55"> <name>Heartbeat</name> </entry>
+ <entry pitch="56"> <name>Footsteps 1</name> </entry>
+ <entry pitch="57"> <name>Footsteps 2</name> </entry>
+ <entry pitch="58"> <name>Applause</name> </entry>
+ <entry pitch="59"> <name>Door Creaking</name> </entry>
+ <entry pitch="60"> <name>Door Closing</name> </entry>
+ <entry pitch="61"> <name>Scratch</name> </entry>
+ <entry pitch="62"> <name>Wind Chimes</name> </entry>
+ <entry pitch="63"> <name>Car Engine</name> </entry>
+ <entry pitch="64"> <name>Car Brakes</name> </entry>
+ <entry pitch="65"> <name>Car Passing</name> </entry>
+ <entry pitch="66"> <name>Car Crash</name> </entry>
+ <entry pitch="67"> <name>Siren</name> </entry>
+ <entry pitch="68"> <name>Train</name> </entry>
+ <entry pitch="69"> <name>Jet Plane</name> </entry>
+ <entry pitch="70"> <name>Helicopter</name> </entry>
+ <entry pitch="71"> <name>Starship</name> </entry>
+ <entry pitch="72"> <name>Gun Shot</name> </entry>
+ <entry pitch="73"> <name>Machine Gun</name> </entry>
+ <entry pitch="74"> <name>Laser Gun</name> </entry>
+ <entry pitch="75"> <name>Explosion</name> </entry>
+ <entry pitch="76"> <name>Dog Bark</name> </entry>
+ <entry pitch="77"> <name>Horse Gallop</name> </entry>
+ <entry pitch="78"> <name>Birds Tweet</name> </entry>
+ <entry pitch="79"> <name>Rain</name> </entry>
+ <entry pitch="80"> <name>Thunder</name> </entry>
+ <entry pitch="81"> <name>Wind</name> </entry>
+ <entry pitch="82"> <name>Seashore</name> </entry>
+ <entry pitch="83"> <name>Stream</name> </entry>
+ <entry pitch="84"> <name>Bubble</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="127" />
+ <drummap>
+ <entry pitch="52"> <name></name> </entry>
+ <entry pitch="53"> <name></name> </entry>
+ <entry pitch="55"> <name></name> </entry>
+ <entry pitch="57"> <name></name> </entry>
+ <entry pitch="58"> <name></name> </entry>
+ <entry pitch="59"> <name></name> </entry>
+ <entry pitch="73"> <name>Quijada</name> </entry>
+ <entry pitch="74"> <name></name> </entry>
+ <entry pitch="76"> <name>Laughing</name> </entry>
+ <entry pitch="77"> <name>Screaming</name> </entry>
+ <entry pitch="78"> <name>Punch</name> </entry>
+ <entry pitch="79"> <name>Heartbeat</name> </entry>
+ <entry pitch="80"> <name>Footsteps 1</name> </entry>
+ <entry pitch="81"> <name>Footsteps 2</name> </entry>
+ <entry pitch="82"> <name>Applause</name> </entry>
+ <entry pitch="83"> <name>Door Creaking</name> </entry>
+ <entry pitch="84"> <name>Door Closing</name> </entry>
+ <entry pitch="85"> <name>Scratch</name> </entry>
+ <entry pitch="86"> <name>Wind Chimes</name> </entry>
+ <entry pitch="87"> <name>Car Engine</name> </entry>
+ <entry pitch="88"> <name>Car Brakes</name> </entry>
+ <entry pitch="89"> <name>Car Passing</name> </entry>
+ <entry pitch="90"> <name>Car Crash</name> </entry>
+ <entry pitch="91"> <name>Siren</name> </entry>
+ <entry pitch="92"> <name>Train</name> </entry>
+ <entry pitch="93"> <name>Jet Plane</name> </entry>
+ <entry pitch="94"> <name>Helicopter</name> </entry>
+ <entry pitch="95"> <name>Starship</name> </entry>
+ <entry pitch="96"> <name>Gun Shot</name> </entry>
+ <entry pitch="97"> <name>Machine Gun</name> </entry>
+ <entry pitch="98"> <name>Laser Gun</name> </entry>
+ <entry pitch="99"> <name>Explosion</name> </entry>
+ <entry pitch="100"> <name>Dog Bark</name> </entry>
+ <entry pitch="101"> <name>Horse Gallop</name> </entry>
+ <entry pitch="102"> <name>Birds Tweet</name> </entry>
+ <entry pitch="103"> <name>Rain</name> </entry>
+ <entry pitch="104"> <name>Thunder</name> </entry>
+ <entry pitch="105"> <name>Wind</name> </entry>
+ <entry pitch="106"> <name>Seashore</name> </entry>
+ <entry pitch="107"> <name>Stream</name> </entry>
+ <entry pitch="108"> <name>Bubble</name> </entry>
+ </drummap>
+ </entry>
+
</MidiInstrument>
</muse>
diff --git a/muse2/share/instruments/xg.idf b/muse2/share/instruments/xg.idf
index 4f5f586e..c281df66 100644
--- a/muse2/share/instruments/xg.idf
+++ b/muse2/share/instruments/xg.idf
@@ -602,5 +602,506 @@
<Controller name="Drum VariationSendLev" type="NRPN" h="31" l="pitch" />
<Controller name="Pitch" type="Pitch" />
<Controller name="Program" type="Program" />
+
+ <Drummaps>
+ <entry>
+ <patch_collection hbank="127" prog="0" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Snare L</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum L</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Bass Drum M</name> </entry>
+ <entry pitch="36"> <name>Bass Drum H</name> </entry>
+ <entry pitch="38"> <name>Snare M</name> </entry>
+ <entry pitch="40"> <name>Snare H</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="1-7" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll 2</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Snare L 2</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum L</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot 2</name> </entry>
+ <entry pitch="35"> <name>Bass Drum M 2</name> </entry>
+ <entry pitch="36"> <name>Bass Drum H 2</name> </entry>
+ <entry pitch="38"> <name>Snare M 2</name> </entry>
+ <entry pitch="40"> <name>Snare H 2</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="8-15" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Snare L</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum L</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Bass Drum M</name> </entry>
+ <entry pitch="36"> <name>Room Bass Drum</name> </entry>
+ <entry pitch="38"> <name>Room Snare L</name> </entry>
+ <entry pitch="40"> <name>Room Snare H</name> </entry>
+ <entry pitch="41"> <name>Room Tom 1</name> </entry>
+ <entry pitch="43"> <name>Room Tom 2</name> </entry>
+ <entry pitch="45"> <name>Room Tom 3</name> </entry>
+ <entry pitch="47"> <name>Room Tom 4</name> </entry>
+ <entry pitch="48"> <name>Room Tom 5</name> </entry>
+ <entry pitch="50"> <name>Room Tom 6</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="16-23" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Rock Snare M</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Rock Bass Drum M</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Bass Drum H 3</name> </entry>
+ <entry pitch="36"> <name>Rock Bass Drum</name> </entry>
+ <entry pitch="38"> <name>Rock Snare L</name> </entry>
+ <entry pitch="40"> <name>Rock Snare Rim</name> </entry>
+ <entry pitch="41"> <name>Rock Tom 1</name> </entry>
+ <entry pitch="43"> <name>Rock Tom 2</name> </entry>
+ <entry pitch="45"> <name>Rock Tom 3</name> </entry>
+ <entry pitch="47"> <name>Rock Tom 4</name> </entry>
+ <entry pitch="48"> <name>Rock Tom 5</name> </entry>
+ <entry pitch="50"> <name>Rock Tom 6</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="24" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Reverse Cymbal</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>High Q</name> </entry>
+ <entry pitch="31"> <name>Snare M</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum H 4</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Rock Bass Drum</name> </entry>
+ <entry pitch="36"> <name>Gated Bass Drum</name> </entry>
+ <entry pitch="38"> <name>Rock Snare L</name> </entry>
+ <entry pitch="40"> <name>Rock Snare H</name> </entry>
+ <entry pitch="41"> <name>Elec. Tom 1</name> </entry>
+ <entry pitch="43"> <name>Elec. Tom 2</name> </entry>
+ <entry pitch="45"> <name>Elec. Tom 3</name> </entry>
+ <entry pitch="47"> <name>Elec. Tom 4</name> </entry>
+ <entry pitch="48"> <name>Elec. Tom 5</name> </entry>
+ <entry pitch="50"> <name>Elec. Tom 6</name> </entry>
+ <entry pitch="78"> <name>Scratch Push</name> </entry>
+ <entry pitch="79"> <name>Scratch Pull</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="25-31" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Reverse Cymbal</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>High Q</name> </entry>
+ <entry pitch="31"> <name>Rock Snare H</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum M</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Analog Bass Drum L</name> </entry>
+ <entry pitch="36"> <name>Analog Bass Drum H</name> </entry>
+ <entry pitch="37"> <name>Analog Side Stick</name> </entry>
+ <entry pitch="38"> <name>Analog Snare L</name> </entry>
+ <entry pitch="40"> <name>Analog Snare H</name> </entry>
+ <entry pitch="41"> <name>Analog Tom 1</name> </entry>
+ <entry pitch="42"> <name>Analog Hi-Hat Closed 1</name> </entry>
+ <entry pitch="43"> <name>Analog Tom 2</name> </entry>
+ <entry pitch="44"> <name>Analog Hi-Hat Closed 2</name> </entry>
+ <entry pitch="45"> <name>Analog Tom 3</name> </entry>
+ <entry pitch="46"> <name>Analog Hi-Hat Open</name> </entry>
+ <entry pitch="47"> <name>Analog Tom 4</name> </entry>
+ <entry pitch="48"> <name>Analog Tom 5</name> </entry>
+ <entry pitch="49"> <name>Analog Cymbal</name> </entry>
+ <entry pitch="50"> <name>Analog Tom 6</name> </entry>
+ <entry pitch="56"> <name>Analog Cowbell</name> </entry>
+ <entry pitch="62"> <name>Analog Conga H</name> </entry>
+ <entry pitch="63"> <name>Analog Conga M</name> </entry>
+ <entry pitch="64"> <name>Analog Conga L</name> </entry>
+ <entry pitch="70"> <name>Analog Maracas</name> </entry>
+ <entry pitch="75"> <name>Analog Claves</name> </entry>
+ <entry pitch="78"> <name>Scratch Push</name> </entry>
+ <entry pitch="79"> <name>Scratch Pull</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="32-39" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Snare L</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum L</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Bass Drum M</name> </entry>
+ <entry pitch="36"> <name>Jazz Bass Drum</name> </entry>
+ <entry pitch="38"> <name>Snare M</name> </entry>
+ <entry pitch="40"> <name>Snare H</name> </entry>
+ <entry pitch="41"> <name>Jazz Tom 1</name> </entry>
+ <entry pitch="43"> <name>Jazz Tom 2</name> </entry>
+ <entry pitch="45"> <name>Jazz Tom 3</name> </entry>
+ <entry pitch="47"> <name>Jazz Tom 4</name> </entry>
+ <entry pitch="48"> <name>Jazz Tom 5</name> </entry>
+ <entry pitch="50"> <name>Jazz Tom 6</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="40-47" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Brush Slap L</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum L</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Bass Drum M</name> </entry>
+ <entry pitch="36"> <name>Soft Bass Drum</name> </entry>
+ <entry pitch="38"> <name>Brush Slap</name> </entry>
+ <entry pitch="40"> <name>Brush Tap</name> </entry>
+ <entry pitch="41"> <name>Brush Tom 1</name> </entry>
+ <entry pitch="43"> <name>Brush Tom 2</name> </entry>
+ <entry pitch="45"> <name>Brush Tom 3</name> </entry>
+ <entry pitch="47"> <name>Brush Tom 4</name> </entry>
+ <entry pitch="48"> <name>Brush Tom 5</name> </entry>
+ <entry pitch="50"> <name>Brush Tom 6</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="127" prog="48-127" />
+ <drummap>
+ <entry pitch="13"> <name>Mute Surdo</name> </entry>
+ <entry pitch="14"> <name>Open Surdo</name> </entry>
+ <entry pitch="15"> <name>High Q</name> </entry>
+ <entry pitch="16"> <name>Whip Slap</name> </entry>
+ <entry pitch="17"> <name>Scratch Push</name> </entry>
+ <entry pitch="18"> <name>Scratch Pull</name> </entry>
+ <entry pitch="19"> <name>Finger Snap</name> </entry>
+ <entry pitch="20"> <name>Click Noise</name> </entry>
+ <entry pitch="21"> <name>Metronome Click</name> </entry>
+ <entry pitch="22"> <name>Metronome Bell</name> </entry>
+ <entry pitch="23"> <name>Seq Click L</name> </entry>
+ <entry pitch="24"> <name>Seq Click H</name> </entry>
+ <entry pitch="25"> <name>Brush Tap</name> </entry>
+ <entry pitch="26"> <name>Brush Swirl L</name> </entry>
+ <entry pitch="27"> <name>Brush Slap</name> </entry>
+ <entry pitch="28"> <name>Brush Swirl H</name> </entry>
+ <entry pitch="29"> <name>Snare Roll</name> </entry>
+ <entry pitch="30"> <name>Castanet</name> </entry>
+ <entry pitch="31"> <name>Snare L</name> </entry>
+ <entry pitch="32"> <name>Sticks</name> </entry>
+ <entry pitch="33"> <name>Bass Drum L 2</name> </entry>
+ <entry pitch="34"> <name>Open Rim Shot</name> </entry>
+ <entry pitch="35"> <name>Gran Cassa</name> </entry>
+ <entry pitch="36"> <name>Gran Cassa Mute</name> </entry>
+ <entry pitch="38"> <name>Marching Snare H</name> </entry>
+ <entry pitch="40"> <name>Marching Snare M</name> </entry>
+ <entry pitch="41"> <name>Jazz Tom 1</name> </entry>
+ <entry pitch="43"> <name>Jazz Tom 2</name> </entry>
+ <entry pitch="45"> <name>Jazz Tom 3</name> </entry>
+ <entry pitch="47"> <name>Jazz Tom 4</name> </entry>
+ <entry pitch="48"> <name>Jazz Tom 5</name> </entry>
+ <entry pitch="49"> <name>Hand Cym. Open L</name> </entry>
+ <entry pitch="50"> <name>Jazz Tom 6</name> </entry>
+ <entry pitch="51"> <name>Hand Cym. Closed L</name> </entry>
+ <entry pitch="57"> <name>Hand Cym. Open H</name> </entry>
+ <entry pitch="59"> <name>Hand Cym. Closed H</name> </entry>
+ <entry pitch="82"> <name>Shaker</name> </entry>
+ <entry pitch="83"> <name>Jingle Bell</name> </entry>
+ <entry pitch="84"> <name>Belltree</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="126" prog="0" />
+ <drummap>
+ <entry pitch="35"> <name></name> </entry>
+ <entry pitch="36"> <name>Guitar Cutting Noise</name> </entry>
+ <entry pitch="37"> <name>Guitar Cutting Noise 2</name> </entry>
+ <entry pitch="38"> <name>Dist. Cut Noise</name> </entry>
+ <entry pitch="39"> <name>String Slap</name> </entry>
+ <entry pitch="40"> <name>Bass Slide</name> </entry>
+ <entry pitch="41"> <name>Pick Scrape</name> </entry>
+ <entry pitch="42"> <name></name> </entry>
+ <entry pitch="43"> <name></name> </entry>
+ <entry pitch="44"> <name></name> </entry>
+ <entry pitch="45"> <name></name> </entry>
+ <entry pitch="46"> <name></name> </entry>
+ <entry pitch="47"> <name></name> </entry>
+ <entry pitch="48"> <name></name> </entry>
+ <entry pitch="49"> <name></name> </entry>
+ <entry pitch="50"> <name></name> </entry>
+ <entry pitch="51"> <name></name> </entry>
+ <entry pitch="52"> <name>FL.Key Click</name> </entry>
+ <entry pitch="53"> <name></name> </entry>
+ <entry pitch="54"> <name></name> </entry>
+ <entry pitch="55"> <name></name> </entry>
+ <entry pitch="56"> <name></name> </entry>
+ <entry pitch="57"> <name></name> </entry>
+ <entry pitch="58"> <name></name> </entry>
+ <entry pitch="59"> <name></name> </entry>
+ <entry pitch="60"> <name></name> </entry>
+ <entry pitch="61"> <name></name> </entry>
+ <entry pitch="62"> <name></name> </entry>
+ <entry pitch="63"> <name></name> </entry>
+ <entry pitch="64"> <name></name> </entry>
+ <entry pitch="65"> <name></name> </entry>
+ <entry pitch="66"> <name></name> </entry>
+ <entry pitch="67"> <name></name> </entry>
+ <entry pitch="68"> <name>Rain</name> </entry>
+ <entry pitch="69"> <name>Thunder</name> </entry>
+ <entry pitch="70"> <name>Wind</name> </entry>
+ <entry pitch="71"> <name>Stream</name> </entry>
+ <entry pitch="72"> <name>Bubble</name> </entry>
+ <entry pitch="73"> <name>Feed</name> </entry>
+ <entry pitch="74"> <name></name> </entry>
+ <entry pitch="75"> <name></name> </entry>
+ <entry pitch="76"> <name></name> </entry>
+ <entry pitch="77"> <name></name> </entry>
+ <entry pitch="78"> <name></name> </entry>
+ <entry pitch="79"> <name></name> </entry>
+ <entry pitch="80"> <name></name> </entry>
+ <entry pitch="81"> <name></name> </entry>
+ <entry pitch="82"> <name></name> </entry>
+ <entry pitch="83"> <name></name> </entry>
+ <entry pitch="84"> <name>Dog</name> </entry>
+ <entry pitch="85"> <name>Horse Gallop</name> </entry>
+ <entry pitch="86"> <name>Bird 2</name> </entry>
+ <entry pitch="87"> <name>Kitty</name> </entry>
+ <entry pitch="88"> <name>Growl</name> </entry>
+ <entry pitch="89"> <name>Haunted</name> </entry>
+ <entry pitch="90"> <name>Ghost</name> </entry>
+ <entry pitch="91"> <name>Maou</name> </entry>
+ </drummap>
+ </entry>
+
+ <entry>
+ <patch_collection hbank="126" prog="1" />
+ <drummap>
+ <entry pitch="35"> <name></name> </entry>
+ <entry pitch="36"> <name>Dial Tone</name> </entry>
+ <entry pitch="37"> <name>Door Creaking</name> </entry>
+ <entry pitch="38"> <name>Door Slam</name> </entry>
+ <entry pitch="39"> <name>Scratch</name> </entry>
+ <entry pitch="40"> <name>Scratch 2</name> </entry>
+ <entry pitch="41"> <name>Windchime</name> </entry>
+ <entry pitch="42"> <name>Telephone Ring 2</name> </entry>
+ <entry pitch="43"> <name></name> </entry>
+ <entry pitch="44"> <name></name> </entry>
+ <entry pitch="45"> <name></name> </entry>
+ <entry pitch="46"> <name></name> </entry>
+ <entry pitch="47"> <name></name> </entry>
+ <entry pitch="48"> <name></name> </entry>
+ <entry pitch="49"> <name></name> </entry>
+ <entry pitch="50"> <name></name> </entry>
+ <entry pitch="51"> <name></name> </entry>
+ <entry pitch="52"> <name>Engine Start</name> </entry>
+ <entry pitch="53"> <name>Tire Screech</name> </entry>
+ <entry pitch="54"> <name>Car Passing</name> </entry>
+ <entry pitch="55"> <name>Crash</name> </entry>
+ <entry pitch="56"> <name>Siren</name> </entry>
+ <entry pitch="57"> <name>Train</name> </entry>
+ <entry pitch="58"> <name>Jetplane</name> </entry>
+ <entry pitch="59"> <name>Starship</name> </entry>
+ <entry pitch="60"> <name>Burst Noise</name> </entry>
+ <entry pitch="61"> <name>Coaster</name> </entry>
+ <entry pitch="62"> <name>SbMarine</name> </entry>
+ <entry pitch="63"> <name></name> </entry>
+ <entry pitch="64"> <name></name> </entry>
+ <entry pitch="65"> <name></name> </entry>
+ <entry pitch="66"> <name></name> </entry>
+ <entry pitch="67"> <name></name> </entry>
+ <entry pitch="68"> <name>Laughing</name> </entry>
+ <entry pitch="69"> <name>Screaming</name> </entry>
+ <entry pitch="70"> <name>Punch</name> </entry>
+ <entry pitch="71"> <name>Heartbeat</name> </entry>
+ <entry pitch="72"> <name>Footsteps</name> </entry>
+ <entry pitch="73"> <name>Applaus2</name> </entry>
+ <entry pitch="74"> <name></name> </entry>
+ <entry pitch="75"> <name></name> </entry>
+ <entry pitch="76"> <name></name> </entry>
+ <entry pitch="77"> <name></name> </entry>
+ <entry pitch="78"> <name></name> </entry>
+ <entry pitch="79"> <name></name> </entry>
+ <entry pitch="80"> <name></name> </entry>
+ <entry pitch="81"> <name></name> </entry>
+ <entry pitch="82"> <name></name> </entry>
+ <entry pitch="83"> <name></name> </entry>
+ <entry pitch="84"> <name>Machine Gun</name> </entry>
+ <entry pitch="85"> <name>Laser Gun</name> </entry>
+ <entry pitch="86"> <name>Explosion</name> </entry>
+ <entry pitch="87"> <name>Firework</name> </entry>
+ </drummap>
+ </entry>
+
+ </Drummaps>
</MidiInstrument>
</muse>