diff options
Diffstat (limited to 'muse2/muse/instruments')
-rw-r--r-- | muse2/muse/instruments/editinstrument.cpp | 398 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrument.h | 27 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrumentbase.ui | 592 | ||||
-rw-r--r-- | muse2/muse/instruments/minstrument.cpp | 338 | ||||
-rw-r--r-- | muse2/muse/instruments/minstrument.h | 55 |
5 files changed, 1332 insertions, 78 deletions
diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index b90b872e..ac3ec68f 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -32,6 +32,9 @@ #include <QMessageBox> #include <QLineEdit> #include <QWhatsThis> +#include <QStringListModel> +#include <QScrollBar> +#include <list> #include "editinstrument.h" #include "minstrument.h" @@ -42,10 +45,14 @@ #include "gconfig.h" #include "icons.h" +#include "dlist.h" +#include "drummap.h" +#include "header.h" + namespace MusEGui { enum { - COL_NAME = 0, COL_TYPE, + COL_CNAME = 0, COL_TYPE, COL_HNUM, COL_LNUM, COL_MIN, COL_MAX, COL_DEF }; @@ -72,10 +79,10 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) // populate instrument list // Populate common controller list. for(int i = 0; i < 128; ++i) - { - QListWidgetItem *lci = new QListWidgetItem(MusECore::midiCtrlName(i)); - listController->addItem(lci); - } + { + QListWidgetItem *lci = new QListWidgetItem(MusECore::midiCtrlName(i)); + listController->addItem(lci); + } oldMidiInstrument = 0; oldPatchItem = 0; for (MusECore::iMidiInstrument i = MusECore::midiInstruments.begin(); i != MusECore::midiInstruments.end(); ++i) { @@ -105,8 +112,66 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) // workingInstrument.assign( *wip ); + dlist_header = new Header(dlistContainer, "header"); + dlist_header->setFixedHeight(31); + dlist_header->setColumnLabel(tr("Name"), COL_NAME, 120); + dlist_header->setColumnLabel(tr("Vol"), COL_VOLUME); + dlist_header->setColumnLabel(tr("Quant"), COL_QUANT, 30); + dlist_header->setColumnLabel(tr("E-Note"), COL_INPUTTRIGGER, 50); + dlist_header->setColumnLabel(tr("Len"), COL_NOTELENGTH); + dlist_header->setColumnLabel(tr("A-Note"), COL_NOTE, 50); + dlist_header->setColumnLabel(tr("LV1"), COL_LEVEL1); + dlist_header->setColumnLabel(tr("LV2"), COL_LEVEL2); + dlist_header->setColumnLabel(tr("LV3"), COL_LEVEL3); + dlist_header->setColumnLabel(tr("LV4"), COL_LEVEL4); + dlist_header->hideSection(COL_OUTPORT); + dlist_header->hideSection(COL_OUTCHANNEL); + dlist_header->hideSection(COL_HIDE); + dlist_header->hideSection(COL_MUTE); + dlist_header->hide(); + + + connect(patchFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(patchToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(lbankFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(lbankToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(hbankFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(hbankToBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); + connect(patchCheckbox, SIGNAL(toggled(bool)), this, SLOT(patchCollectionCheckboxChanged(bool))); + connect(lbankCheckbox, SIGNAL(toggled(bool)), this, SLOT(patchCollectionCheckboxChanged(bool))); + connect(hbankCheckbox, SIGNAL(toggled(bool)), this, SLOT(patchCollectionCheckboxChanged(bool))); + + connect(addCollBtn, SIGNAL(clicked()), this, SLOT(addPatchCollection())); + connect(rmCollBtn, SIGNAL(clicked()), this, SLOT(delPatchCollection())); + connect(copyCollBtn, SIGNAL(clicked()), this, SLOT(copyPatchCollection())); + connect(collUpBtn, SIGNAL(clicked()), this, SLOT(patchCollectionUp())); + connect(collDownBtn, SIGNAL(clicked()), this, SLOT(patchCollectionDown())); + + connect(patchCollections, SIGNAL(activated(const QModelIndex&)), this, SLOT(patchActivated(const QModelIndex&))); + connect(patchCollections, SIGNAL(clicked (const QModelIndex&)), this, SLOT(patchActivated(const QModelIndex&))); + + patch_coll_model=new QStringListModel(); + patchCollections->setModel(patch_coll_model); + patchCollections->setEditTriggers(QAbstractItemView::NoEditTriggers); + connect(instrumentList, SIGNAL(itemSelectionChanged()), SLOT(instrumentChanged())); connect(patchView, SIGNAL(itemSelectionChanged()), SLOT(patchChanged())); + + dlist_vscroll = new QScrollBar(Qt::Vertical, this); + dlist_vscroll->setMaximum(128*TH); + dlist_vscroll->hide(); + + dlist_grid = new QGridLayout(dlistContainer); + dlist_grid->setContentsMargins(0, 0, 0, 0); + dlist_grid->setSpacing(0); + dlist_grid->setRowStretch(1, 100); + dlist_grid->setColumnStretch(0, 100); + dlist_grid->addWidget(dlist_header, 0, 0); + dlist_grid->addWidget(dlist_vscroll, 1,1); + + dlist=NULL; + + //instrumentChanged(); changeInstrument(); @@ -151,6 +216,306 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) //connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked())); } + +void EditInstrument::patchCollectionSpinboxChanged(int) +{ + if (patchFromBox->value() > patchToBox->value()) + patchToBox->setValue(patchFromBox->value()); + + if (lbankFromBox->value() > lbankToBox->value()) + lbankToBox->setValue(lbankFromBox->value()); + + if (hbankFromBox->value() > hbankToBox->value()) + hbankToBox->setValue(hbankFromBox->value()); + + storePatchCollection(); +} + +void EditInstrument::patchCollectionCheckboxChanged(bool) +{ + storePatchCollection(); +} + +void EditInstrument::storePatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + if (idx>=0 && (unsigned)idx<pdm->size()) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx); + + if (patchCheckbox->isChecked()) + { + it->affected_patches.first_program=patchFromBox->value()-1; + it->affected_patches.last_program=patchToBox->value()-1; + } + else + { + it->affected_patches.first_program=0; + it->affected_patches.last_program=127; + } + + if (lbankCheckbox->isChecked()) + { + it->affected_patches.first_lbank=lbankFromBox->value()-1; + it->affected_patches.last_lbank=lbankToBox->value()-1; + } + else + { + it->affected_patches.first_lbank=0; + it->affected_patches.last_lbank=127; + } + + if (hbankCheckbox->isChecked()) + { + it->affected_patches.first_hbank=hbankFromBox->value()-1; + it->affected_patches.last_hbank=hbankToBox->value()-1; + } + else + { + it->affected_patches.first_hbank=0; + it->affected_patches.last_hbank=127; + } + + workingInstrument.setDirty(true); + repopulatePatchCollections(); + } +} + +void EditInstrument::fetchPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + if (idx>=0 && (unsigned)idx<pdm->size()) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx); + + patchFromBox->blockSignals(true); + patchToBox->blockSignals(true); + lbankFromBox->blockSignals(true); + lbankToBox->blockSignals(true); + hbankFromBox->blockSignals(true); + hbankToBox->blockSignals(true); + + patchFromBox->setValue(it->affected_patches.first_program+1); + patchToBox->setValue(it->affected_patches.last_program+1); + + lbankFromBox->setValue(it->affected_patches.first_lbank+1); + lbankToBox->setValue(it->affected_patches.last_lbank+1); + + hbankFromBox->setValue(it->affected_patches.first_hbank+1); + hbankToBox->setValue(it->affected_patches.last_hbank+1); + + patchFromBox->blockSignals(false); + patchToBox->blockSignals(false); + lbankFromBox->blockSignals(false); + lbankToBox->blockSignals(false); + hbankFromBox->blockSignals(false); + hbankToBox->blockSignals(false); + + + patchCheckbox->setChecked(it->affected_patches.first_program>0 || it->affected_patches.last_program < 127); + lbankCheckbox->setChecked(it->affected_patches.first_lbank>0 || it->affected_patches.last_lbank < 127); + hbankCheckbox->setChecked(it->affected_patches.first_hbank>0 || it->affected_patches.last_hbank < 127); + } +} + +void EditInstrument::patchActivated(const QModelIndex& idx) +{ + using MusECore::patch_drummap_mapping_t; + + if (idx.row()>=0) + { + using MusECore::DrumMap; + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + if ((unsigned)idx.row()>=tmp->size()) + printf("THIS SHOULD NEVER HAPPEN: idx.row()>=tmp->size() in EditInstrument::patchActivated()\n"); + + advance(it, idx.row()); + DrumMap* dm=it->drummap; + + + if (dlist) + { + dlist->hide(); + delete dlist; + dlist=NULL; + } + + dlist=new DList(dlist_header,dlistContainer,1,dm); + + dlist->setYPos(dlist_vscroll->value()); + + connect(dlist_vscroll, SIGNAL(valueChanged(int)), dlist, SLOT(setYPos(int))); + dlist_grid->addWidget(dlist, 1, 0); + + + dlist_header->show(); + dlist->show(); + dlist_vscroll->show(); + + collUpBtn->setEnabled(idx.row()>0); + collDownBtn->setEnabled(idx.row()<patch_coll_model->rowCount()-1); + rmCollBtn->setEnabled(true); + copyCollBtn->setEnabled(true); + patchCollectionContainer->setEnabled(true); + + fetchPatchCollection(); + } +} + +void EditInstrument::addPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + advance(it,idx+1); + tmp->insert(it,patch_drummap_mapping_t()); + + repopulatePatchCollections(); + patchCollections->setCurrentIndex(patch_coll_model->index(idx+1)); + patchActivated(patchCollections->currentIndex()); + + workingInstrument.setDirty(true); +} + +void EditInstrument::delPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + if (idx>=0) + { + if (dlist) + { + dlist->hide(); + delete dlist; + dlist=NULL; + } + + dlist_header->hide(); + dlist_vscroll->hide(); + + rmCollBtn->setEnabled(false); + copyCollBtn->setEnabled(false); + patchCollectionContainer->setEnabled(false); + collUpBtn->setEnabled(false); + collDownBtn->setEnabled(false); + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + advance(it,idx); + tmp->erase(it); + + repopulatePatchCollections(); + + patchActivated(patchCollections->currentIndex()); + workingInstrument.setDirty(true); + } +} + +void EditInstrument::copyPatchCollection() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + + std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); + std::list<patch_drummap_mapping_t>::iterator it=tmp->begin(); + advance(it,idx); + patch_drummap_mapping_t tmp2(*it); + it++; + tmp->insert(it,tmp2); + + patch_coll_model->insertRow(idx+1); + patch_coll_model->setData(patch_coll_model->index(idx+1), patch_coll_model->index(idx).data()); + patchCollections->setCurrentIndex(patch_coll_model->index(idx+1)); + patchActivated(patchCollections->currentIndex()); + workingInstrument.setDirty(true); +} + +void EditInstrument::patchCollectionUp() +{ + using MusECore::patch_drummap_mapping_t; + + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + int idx=patchCollections->currentIndex().row(); + + if (idx>=1) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx-1); + std::list<patch_drummap_mapping_t>::iterator it2=it; + it2++; + + //it2 is the element to move, it is the element to put before. + + pdm->insert(it,*it2); + pdm->erase(it2); + + repopulatePatchCollections(); + + patchCollections->setCurrentIndex(patch_coll_model->index(idx-1)); + patchActivated(patchCollections->currentIndex()); + + workingInstrument.setDirty(true); + } +} + +void EditInstrument::patchCollectionDown() +{ + using MusECore::patch_drummap_mapping_t; + + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + int idx=patchCollections->currentIndex().row(); + + if ((unsigned)idx<pdm->size()-1) + { + std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); + advance(it,idx); + std::list<patch_drummap_mapping_t>::iterator it2=it; + it2++; it2++; + + //it is the element to move, it2 is the element to put before (might be end()) + + pdm->insert(it2,*it); + pdm->erase(it); + + repopulatePatchCollections(); + + patchCollections->setCurrentIndex(patch_coll_model->index(idx+1)); + patchActivated(patchCollections->currentIndex()); + + workingInstrument.setDirty(true); + } +} + +void EditInstrument::repopulatePatchCollections() +{ + using MusECore::patch_drummap_mapping_t; + + int idx=patchCollections->currentIndex().row(); + QStringList strlist; + + std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); + for (std::list<patch_drummap_mapping_t>::iterator it=pdm->begin(); it!=pdm->end(); it++) + strlist << it->affected_patches.to_string(); + + patch_coll_model->setStringList(strlist); + patchCollections->setCurrentIndex(patch_coll_model->index(idx)); +} + //--------------------------------------------------------- // helpWhatsThis //--------------------------------------------------------- @@ -1014,6 +1379,25 @@ void EditInstrument::changeInstrument() */ + + repopulatePatchCollections(); + if (dlist) + { + dlist->hide(); + delete dlist; + dlist=NULL; + } + + dlist_header->hide(); + dlist_vscroll->hide(); + + rmCollBtn->setEnabled(false); + copyCollBtn->setEnabled(false); + patchCollectionContainer->setEnabled(false); + collUpBtn->setEnabled(false); + collDownBtn->setEnabled(false); + + } //--------------------------------------------------------- @@ -1801,9 +2185,9 @@ void EditInstrument::ctrlNameReturn() } c->setName(ctrlName->text()); - item->setText(COL_NAME, ctrlName->text()); + item->setText(COL_CNAME, ctrlName->text()); //c->setName(s); - //item->setText(COL_NAME, s); + //item->setText(COL_CNAME, s); workingInstrument.setDirty(true); } diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h index ba53aae1..ab5edf39 100644 --- a/muse2/muse/instruments/editinstrument.h +++ b/muse2/muse/instruments/editinstrument.h @@ -31,9 +31,14 @@ class QDialog; class QMenu; class QCloseEvent; +class QGridLayout; +class QStringListModel; namespace MusEGui { +class Header; +class DList; + //--------------------------------------------------------- // EditInstrument //--------------------------------------------------------- @@ -44,6 +49,15 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { MusECore::MidiInstrument workingInstrument; QListWidgetItem* oldMidiInstrument; QTreeWidgetItem* oldPatchItem; + + Header* dlist_header; + DList* dlist; + QScrollBar* dlist_vscroll; + QGridLayout* dlist_grid; + QStringListModel* patch_coll_model; + + + void closeEvent(QCloseEvent*); int checkDirty(MusECore::MidiInstrument*, bool isClose = false); bool fileSave(MusECore::MidiInstrument*, const QString&); @@ -61,7 +75,6 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { void setDefaultPatchControls(int); QString getPatchName(int); void deleteInstrument(QListWidgetItem*); - ///QMenu* patchpopup; private slots: virtual void fileNew(); @@ -99,6 +112,18 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { //void newSysexClicked(); void ctrlNullParamHChanged(int); void ctrlNullParamLChanged(int); + + void patchCollectionSpinboxChanged(int); + void patchCollectionCheckboxChanged(bool); + void patchActivated(const QModelIndex&); + void addPatchCollection(); + void delPatchCollection(); + void copyPatchCollection(); + void patchCollectionUp(); + void patchCollectionDown(); + void repopulatePatchCollections(); + void storePatchCollection(); + void fetchPatchCollection(); public: EditInstrument(QWidget* parent = 0, Qt::WFlags fl = Qt::Window); diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui index 3337cfc0..5295abb2 100644 --- a/muse2/muse/instruments/editinstrumentbase.ui +++ b/muse2/muse/instruments/editinstrumentbase.ui @@ -1370,6 +1370,404 @@ Typically, set to 127/127, or an unused </item> </layout> </widget> + <widget class="QWidget" name="drumTab"> + <attribute name="title"> + <string>Drummaps</string> + </attribute> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <widget class="QLabel" name="label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Patch Collections:</string> + </property> + </widget> + </item> + <item> + <widget class="QListView" name="patchCollections"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </item> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <property name="spacing"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="addCollBtn"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Add</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="copyCollBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Copy</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="rmCollBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Remove</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QPushButton" name="collUpBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Up</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="collDownBtn"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Down</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item> + <widget class="QWidget" name="patchCollectionContainer" native="true"> + <property name="enabled"> + <bool>false</bool> + </property> + <layout class="QGridLayout" name="gridLayout_"> + <property name="margin"> + <number>0</number> + </property> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QCheckBox" name="patchCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Patch:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_5"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>from</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QSpinBox" name="patchFromBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="0" column="3"> + <widget class="QLabel" name="label_8"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item row="0" column="4"> + <widget class="QSpinBox" name="patchToBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QCheckBox" name="hbankCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Bank Hi:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_6"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>from</string> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QSpinBox" name="hbankFromBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="1" column="3"> + <widget class="QLabel" name="label_9"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item row="1" column="4"> + <widget class="QSpinBox" name="hbankToBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QCheckBox" name="lbankCheckbox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Bank Lo:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_7"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>from</string> + </property> + </widget> + </item> + <item row="2" column="2"> + <widget class="QSpinBox" name="lbankFromBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + <item row="2" column="3"> + <widget class="QLabel" name="label_10"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>to</string> + </property> + </widget> + </item> + <item row="2" column="4"> + <widget class="QSpinBox" name="lbankToBox"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>128</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QWidget" name="dlistContainer" native="true"/> + </item> + </layout> + </item> + </layout> + </widget> </widget> </widget> </item> @@ -1396,7 +1794,7 @@ Typically, set to 127/127, or an unused <x>0</x> <y>0</y> <width>802</width> - <height>21</height> + <height>25</height> </rect> </property> <property name="defaultUp"> @@ -1645,5 +2043,197 @@ Typically, set to 127/127, or an unused </hint> </hints> </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_5</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>patchFromBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>343</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_8</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>390</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>patchCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>patchToBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>214</x> + <y>411</y> + </hint> + <hint type="destinationlabel"> + <x>436</x> + <y>412</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>lbankFromBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>343</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>lbankToBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>436</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_7</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>lbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_10</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>221</x> + <y>469</y> + </hint> + <hint type="destinationlabel"> + <x>390</x> + <y>470</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>hbankFromBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>343</x> + <y>441</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>hbankToBox</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>436</x> + <y>441</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_6</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>289</x> + <y>441</y> + </hint> + </hints> + </connection> + <connection> + <sender>hbankCheckbox</sender> + <signal>toggled(bool)</signal> + <receiver>label_9</receiver> + <slot>setEnabled(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>220</x> + <y>440</y> + </hint> + <hint type="destinationlabel"> + <x>390</x> + <y>441</y> + </hint> + </hints> + </connection> </connections> </ui> diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index 22ed3737..1349c9c9 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,12 @@ MidiInstrument::~MidiInstrument() if (_initScript) delete _initScript; + + patch_drummap_mapping.clear(); } + + /* //--------------------------------------------------------- // uniqueCopy @@ -515,7 +522,11 @@ MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins) _name = ins._name; _filePath = ins._filePath; - + + patch_drummap_mapping=ins.patch_drummap_mapping; + + + // Hmm, dirty, yes? But init sets it to false... //_dirty = ins._dirty; //_dirty = false; @@ -733,6 +744,160 @@ void MidiInstrument::readMidiState(Xml& xml) } } +void MidiInstrument::readDrummaps(Xml& xml) +{ + patch_drummap_mapping.clear(); + + 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; + + 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=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"); +} + +void MidiInstrument::writeDrummaps(int level, Xml& xml) const +{ + xml.tag(level++, "Drummaps"); + + for (std::list<patch_drummap_mapping_t>::const_iterator it=patch_drummap_mapping.begin(); + it!=patch_drummap_mapping.end(); it++) + { + xml.tag(level++, "entry"); + + const patch_collection_t* ap = &it->affected_patches; + QString tmp="<patch_collection "; + if (ap->first_program==ap->last_program) + tmp+="prog=\""+QString::number(ap->first_program)+"\" "; + else if (! (ap->first_program==0 && ap->last_program>=127)) + tmp+="prog=\""+QString::number(ap->first_program)+"-"+QString::number(ap->last_program)+"\" "; + + if (ap->first_lbank==ap->last_lbank) + tmp+="lbank=\""+QString::number(ap->first_lbank)+"\" "; + else if (! (ap->first_lbank==0 && ap->last_lbank>=127)) + tmp+="lbank=\""+QString::number(ap->first_lbank)+"-"+QString::number(ap->last_lbank)+"\" "; + + if (ap->first_hbank==ap->last_hbank) + tmp+="hbank=\""+QString::number(ap->first_hbank)+"\" "; + else if (! (ap->first_hbank==0 && ap->last_hbank>=127)) + tmp+="hbank=\""+QString::number(ap->first_hbank)+"-"+QString::number(ap->last_hbank)+"\" "; + + tmp+="/>\n"; + + xml.nput(level, tmp.toAscii().data()); + + write_new_style_drummap(level, xml, "drummap", it->drummap); + + xml.etag(--level, "entry"); + } + + xml.etag(--level, "Drummaps"); +} + //--------------------------------------------------------- // read //--------------------------------------------------------- @@ -785,6 +950,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 +962,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) { @@ -872,6 +1040,9 @@ void MidiInstrument::write(int level, Xml& xml) //(*ic)->write(xml); ic->second->write(level, xml); //xml.etag("MidiInstrument"); + + writeDrummaps(level, xml); + level--; xml.etag(level, "MidiInstrument"); //xml.etag("muse"); @@ -996,71 +1167,104 @@ void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MTyp } } -} // namespace MusECore + } -/* -namespace MusEGui { +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++) + { + const patch_collection_t* ap = &it->affected_patches; + // if the entry matches our patch + if ( (program >= ap->first_program && program <= ap->last_program) && + (hbank >= ap->first_hbank && hbank <= ap->last_hbank) && + (lbank >= ap->first_lbank && lbank <= ap->last_lbank) ) + { + return it->drummap; + } + } + + // if nothing was found + return iNewDrumMap; +} -void populatePatchPopup(MusECore::MidiInstrument* midiInstrument, PopupMenu* menu, int chan, MType songType, bool drum) - { - menu->clear(); - int mask = 0; - bool drumchan = chan == 9; - switch (songType) { - case MT_XG: mask = 4; break; - case MT_GS: mask = 2; break; - case MT_GM: - if(drumchan) - { - int id = (0xff << 16) + (0xff << 8) + 0x00; // First patch - QAction* act = menu->addAction(MusECore::gmdrumname); - //act->setCheckable(true); - act->setData(id); - return; - } - mask = 1; - break; - case MT_UNKNOWN: mask = 7; break; - } - if (midiInstrument->groups()->size() > 1) { - for (MusECore::ciPatchGroup i = midiInstrument->groups()->begin(); i != midiInstrument->groups()->end(); ++i) { - MusECore::PatchGroup* pgp = *i; - //QMenu* pm = menu->addMenu(pgp->name); - PopupMenu* pm = new PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here. - menu->addMenu(pm); - pm->setFont(MusEGlobal::config.fonts[0]); - const MusECore::PatchList& pl = pgp->patches; - for (MusECore::ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { - const MusECore::Patch* mp = *ipl; - if ((mp->typ & mask) && - ((drum && songType != MT_GM) || - (mp->drum == drumchan)) ) - { - int id = ((mp->hbank & 0xff) << 16) - + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); - QAction* act = pm->addAction(mp->name); - //act->setCheckable(true); - act->setData(id); - } - - } - } - } - else if (midiInstrument->groups()->size() == 1 ){ - // no groups - const MusECore::PatchList& pl = midiInstrument->groups()->front()->patches; - for (MusECore::ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) { - const MusECore::Patch* mp = *ipl; - if (mp->typ & mask) { - int id = ((mp->hbank & 0xff) << 16) - + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); - QAction* act = menu->addAction(mp->name); - //act->setCheckable(true); - act->setData(id); - } - } - } - } -*/ +patch_drummap_mapping_t::patch_drummap_mapping_t() +{ + drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=iNewDrumMap[i]; +} + +patch_drummap_mapping_t::patch_drummap_mapping_t(const patch_drummap_mapping_t& that) +{ + drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=that.drummap[i]; + + affected_patches=that.affected_patches; +} + +patch_drummap_mapping_t& patch_drummap_mapping_t::operator=(const patch_drummap_mapping_t& that) +{ + if (drummap) + delete [] drummap; + + drummap=new DrumMap[128]; + for (int i=0;i<128;i++) + drummap[i]=that.drummap[i]; + + affected_patches=that.affected_patches; + + return *this; +} -} // namespace MusEGui +patch_drummap_mapping_t::~patch_drummap_mapping_t() +{ + delete [] drummap; +} + +QString patch_collection_t::to_string() +{ + QString tmp; + + if (first_program==0 && last_program>=127 && + first_lbank==0 && last_lbank>=127 && + first_hbank==0 && last_hbank>=127) + tmp="default"; + else + { + tmp+="prog: "; + if (first_program==last_program) + tmp+=QString::number(first_program+1); + else if (! (first_program==0 && last_program>=127)) + tmp+=QString::number(first_program+1)+"-"+QString::number(last_program+1); + else + tmp+="*"; + + tmp+=" bank="; + if (first_lbank==last_lbank) + tmp+=QString::number(first_lbank+1); + else if (! (first_lbank==0 && last_lbank>=127)) + tmp+=QString::number(first_lbank+1)+"-"+QString::number(last_lbank+1); + else + tmp+="*"; + + tmp+="/"; + if (first_hbank==last_hbank) + tmp+=QString::number(first_hbank+1); + else if (! (first_hbank==0 && last_hbank>=127)) + tmp+=QString::number(first_hbank+1)+"-"+QString::number(last_hbank+1); + else + tmp+="*"; + + } + return tmp; +} + +} // namespace MusECore diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h index 385e67b4..f793a7b6 100644 --- a/muse2/muse/instruments/minstrument.h +++ b/muse2/muse/instruments/minstrument.h @@ -27,8 +27,7 @@ #include "globaldefs.h" #include <list> #include <vector> - -class QString; +#include <QString> namespace MusEGui { class PopupMenu; @@ -40,6 +39,7 @@ class MidiControllerList; class MidiPort; class MidiPlayEvent; class Xml; +class DrumMap; //--------------------------------------------------------- @@ -80,6 +80,48 @@ 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; + } + + QString to_string(); +}; + +struct patch_drummap_mapping_t +{ + patch_collection_t affected_patches; + DrumMap* drummap; + + patch_drummap_mapping_t(const patch_collection_t& a, DrumMap* d) + { + affected_patches=a; + drummap=d; + } + + patch_drummap_mapping_t(const patch_drummap_mapping_t& that); + patch_drummap_mapping_t(); + ~patch_drummap_mapping_t(); + + patch_drummap_mapping_t& operator=(const patch_drummap_mapping_t& that); +}; + //--------------------------------------------------------- // MidiInstrument //--------------------------------------------------------- @@ -88,6 +130,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 +146,11 @@ class MidiInstrument { char* _initScript; QString _name; QString _filePath; + + void writeDrummaps(int level, Xml& xml) const; + void readDrummaps(Xml& xml); + patch_drummap_mapping_t readDrummapsEntry(Xml& xml); + patch_collection_t readDrummapsEntryPatchCollection(Xml& xml); public: MidiInstrument(); @@ -123,6 +171,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; } @@ -148,6 +198,7 @@ class MidiInstrument { void write(int level, Xml&); PatchGroupList* groups() { return &pg; } + std::list<patch_drummap_mapping_t>* get_patch_drummap_mapping() { return &patch_drummap_mapping; } }; //--------------------------------------------------------- |