summaryrefslogtreecommitdiff
path: root/muse2/muse/instruments
diff options
context:
space:
mode:
Diffstat (limited to 'muse2/muse/instruments')
-rw-r--r--muse2/muse/instruments/editinstrument.cpp398
-rw-r--r--muse2/muse/instruments/editinstrument.h27
-rw-r--r--muse2/muse/instruments/editinstrumentbase.ui592
-rw-r--r--muse2/muse/instruments/minstrument.cpp391
-rw-r--r--muse2/muse/instruments/minstrument.h55
5 files changed, 1348 insertions, 115 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>&amp;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>&amp;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>&amp;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>&amp;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>&amp;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..bd4b3bd4 100644
--- a/muse2/muse/instruments/minstrument.cpp
+++ b/muse2/muse/instruments/minstrument.cpp
@@ -41,14 +41,14 @@
#include "midictrl.h"
#include "gconfig.h"
#include "popupmenu.h"
+#include "drummap.h"
+#include "helper.h"
namespace MusECore {
MidiInstrumentList midiInstruments;
MidiInstrument* genericMidiInstrument;
-static const char* gmdrumname = "GM-drums";
-
//---------------------------------------------------------
// string2sysex
//---------------------------------------------------------
@@ -364,6 +364,7 @@ void MidiInstrument::init()
MidiController* prog = new MidiController("Program", CTRL_PROGRAM, 0, 0xffffff, 0);
_controller->add(prog);
_dirty = false;
+
}
MidiInstrument::MidiInstrument()
@@ -408,8 +409,12 @@ MidiInstrument::~MidiInstrument()
if (_initScript)
delete _initScript;
+
+ patch_drummap_mapping.clear();
}
+
+
/*
//---------------------------------------------------------
// uniqueCopy
@@ -515,7 +520,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 +742,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 +948,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 +960,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 +1038,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");
@@ -906,8 +1075,6 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru
tmask = 4;
break;
case MT_GM:
- if(drumchan)
- return gmdrumname;
tmask = 1;
break;
default:
@@ -919,10 +1086,8 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru
const PatchList& pl = (*i)->patches;
for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
const Patch* mp = *ipl;
- if ((mp->typ & tmask)
- && (pr == mp->prog)
- && ((drum && mode != MT_GM) ||
- (mp->drum == drumchan))
+ if ( (pr == mp->prog)
+ && (mp->drum == drum)
&& (hbank == mp->hbank || !hb || mp->hbank == -1)
&& (lbank == mp->lbank || !lb || mp->lbank == -1))
@@ -936,49 +1101,35 @@ QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool dru
// populatePatchPopup
//---------------------------------------------------------
-void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MType songType, bool drum)
+void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int, MType, 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(gmdrumname);
- //act->setCheckable(true);
- act->setData(id);
- return;
- }
- mask = 1;
- break;
- case MT_UNKNOWN: mask = 7; break;
- }
+
if (pg.size() > 1) {
for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) {
PatchGroup* pgp = *i;
- //QMenu* pm = menu->addMenu(pgp->name);
MusEGui::PopupMenu* pm = new MusEGui::PopupMenu(pgp->name, menu, menu->stayOpen()); // Use the parent stayOpen here.
- menu->addMenu(pm);
- pm->setFont(MusEGlobal::config.fonts[0]);
const PatchList& pl = pgp->patches;
+ bool added=false;
for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
const Patch* mp = *ipl;
- if ((mp->typ & mask) &&
- ((drum && songType != MT_GM) ||
- (mp->drum == drumchan)) )
+ if (mp->drum == drum)
{
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);
+ added=true;
}
-
}
+ if (added)
+ {
+ menu->addMenu(pm);
+ pm->setFont(MusEGlobal::config.fonts[0]);
+ }
+ else
+ delete pm;
+
}
}
else if (pg.size() == 1 ){
@@ -986,81 +1137,113 @@ void MidiInstrument::populatePatchPopup(MusEGui::PopupMenu* menu, int chan, MTyp
const PatchList& pl = pg.front()->patches;
for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
const Patch* mp = *ipl;
- if (mp->typ & mask) {
+ if (mp->drum == drum) {
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);
}
}
}
-} // 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];
+}
-} // namespace MusEGui
+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;
+}
+
+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; }
};
//---------------------------------------------------------