diff options
-rw-r--r-- | muse2/ChangeLog | 3 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrument.cpp | 482 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrument.h | 7 | ||||
-rw-r--r-- | muse2/muse/instruments/editinstrumentbase.ui | 12 | ||||
-rw-r--r-- | muse2/muse/instruments/minstrument.cpp | 270 | ||||
-rw-r--r-- | muse2/muse/instruments/minstrument.h | 11 | ||||
-rw-r--r-- | muse2/share/instruments/gm.idf | 6 | ||||
-rw-r--r-- | muse2/share/instruments/gs.idf | 6 | ||||
-rw-r--r-- | muse2/share/instruments/xg.idf | 14 |
9 files changed, 331 insertions, 480 deletions
diff --git a/muse2/ChangeLog b/muse2/ChangeLog index bd511a9f..faa7b698 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -1,3 +1,6 @@ +01.08.2012: + - Finished the Sysex Editor in the Instrument Editor. (Tim) + Create, delete, save named instrument sysexes. Does nothing more than that for now. 29.07.2012: - Tweaked drum editor zooming to give correct initial zoom (rj) 12.07.2012: diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index e9ced6b2..7205af9d 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -34,6 +34,7 @@ #include <QWhatsThis> #include <QStringListModel> #include <QScrollBar> +#include <QVariant> #include <list> #include "editinstrument.h" @@ -49,6 +50,11 @@ #include "drummap.h" #include "header.h" +namespace MusECore { +extern int string2sysex(const QString& s, unsigned char** data); +extern QString sysex2string(int len, unsigned char* data); +} + namespace MusEGui { enum { @@ -99,16 +105,6 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) instrumentList->setSelectionMode(QAbstractItemView::SingleSelection); if(instrumentList->item(0)) instrumentList->setCurrentItem(instrumentList->item(0)); - //DELETETHIS - //oldMidiInstrument = (MusECore::MidiInstrument*)((ListBoxData*)instrumentList->item(0))->data(); - //oldMidiInstrument = (ListBoxData*)instrumentList->item(0); - //oldMidiInstrument = (ListBoxData*)instrumentList->selectedItem(); - -// MusECore::MidiInstrument* wip = (MusECore::MidiInstrument*)((ListBoxData*)instrumentList->item(0))->data(); -// if(wip) - // Assignment -// workingInstrument.assign( *wip ); - dlist_header = new Header(dlistContainer, "header"); dlist_header->setFixedHeight(31); @@ -169,8 +165,6 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) dlist=NULL; - - changeInstrument(); connect(viewController, SIGNAL(itemSelectionChanged()), SLOT(controllerChanged())); @@ -204,9 +198,10 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl) connect(nullParamSpinBoxL, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamLChanged(int))); connect(tabWidget3, SIGNAL(currentChanged(QWidget*)), SLOT(tabChanged(QWidget*))); - //connect(sysexList, SIGNAL(selectionChanged()), SLOT(sysexChanged())); DELETETHIS or is it needed later? - //connect(deleteSysex, SIGNAL(clicked()), SLOT(deleteSysexClicked())); - //connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked())); + connect(sysexList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + SLOT(sysexChanged(QListWidgetItem*, QListWidgetItem*))); + connect(deleteSysex, SIGNAL(clicked()), SLOT(deleteSysexClicked())); + connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked())); } @@ -643,16 +638,6 @@ void EditInstrument::fileSave() bool EditInstrument::fileSave(MusECore::MidiInstrument* instrument, const QString& name) { - //QFile f(name); DELETETHIS - //if (!f.open(QIODevice::WriteOnly)) { - // QString s("Creating file failed: "); - // s += strerror(errno); - // QMessageBox::critical(this, - // tr("MusE: Create file failed"), s); - // return false; - // } - //MusECore::Xml xml(&f); - FILE* f = fopen(name.toAscii().constData(), "w"); if(f == 0) { @@ -703,18 +688,7 @@ void EditInstrument::saveAs() patchNameReturn(); ctrlNameReturn(); - //QListWidgetItem* item = instrumentList->currentItem(); DELETETHIS -// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); -// if (item == 0) -// return; - //MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(Qt::UserRole).value<void*>(); -// MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(); - - //QString path = QDir::homePath() + "/" + MusEGlobal::config.instrumentPath; - //QString path = QDir::homeDirPath() + "/" + MusEGlobal::museGlobalShare; - //QString path = MusEGlobal::museInstruments; QString path = MusEGlobal::museUserInstruments; - if(!QDir(MusEGlobal::museUserInstruments).exists()) { printf("MusE Error! User instrument directory: %s does not exist. Should be created at startup!\n", MusEGlobal::museUserInstruments.toLatin1().constData()); @@ -740,12 +714,6 @@ void EditInstrument::saveAs() // This will still allow a user instrument to override a built-in instrument with the same name. if(fi.absolutePath() != MusEGlobal::museInstruments) { - //QMessageBox::critical(this, DELETETHIS??? - // tr("MusE: Bad instrument name"), - // tr("Please change the instrument name to a new unique name before saving, to avoid duplicates"), - // QMessageBox::Ok, - // QMessageBox::NoButton, - // QMessageBox::NoButton); printf("EditInstrument::saveAs Error: Instrument name %s already used!\n", workingInstrument.iname().toLatin1().constData()); return; } @@ -822,13 +790,6 @@ void EditInstrument::fileSaveAs() break; } - //QListWidgetItem* item = instrumentList->currentItem(); DELETETHIS -// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); -// if (item == 0) -// return; - //MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(Qt::UserRole).value<void*>(); -// MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(); - bool isuser = false; QString so; if(workingInstrument.iname().isEmpty()) @@ -1006,15 +967,6 @@ void EditInstrument::closeEvent(QCloseEvent* ev) patchNameReturn(); ctrlNameReturn(); - //QListWidgetItem* item = instrumentList->currentItem(); DELETETHIS - -// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem(); - -// if(item) -// { - //MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(Qt::UserRole).value<void*>(); -// MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(); -// int res = checkDirty(instrument, true); MusECore::MidiInstrument* oi = 0; if(oldMidiInstrument) oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>(); @@ -1116,6 +1068,19 @@ void EditInstrument::changeInstrument() nullParamSpinBoxH->blockSignals(false); nullParamSpinBoxL->blockSignals(false); + sysexList->blockSignals(true); + sysexList->clear(); + foreach(const MusECore::SysEx* s, workingInstrument.sysex()) { + QListWidgetItem* item = new QListWidgetItem(s->name); + QVariant v = QVariant::fromValue((void*)s); + item->setData(Qt::UserRole, v); + sysexList->addItem(item); + } + if(sysexList->item(0)) + sysexList->item(0)->setSelected(true); + sysexList->blockSignals(false); + sysexChanged(sysexList->item(0), 0); + MusECore::PatchGroupList* pg = workingInstrument.groups(); for (MusECore::ciPatchGroup g = pg->begin(); g != pg->end(); ++g) { MusECore::PatchGroup* pgp = *g; @@ -1147,63 +1112,23 @@ void EditInstrument::changeInstrument() if(fc) { // This may cause a patchChanged call. - //if(patchView->selectedItem() != fc) DELETETHIS patchView->blockSignals(true); fc->setSelected(true); patchView->blockSignals(false); - //else - // patchChanged(); DELETETHIS - - //patchView->firstChild()->setSelected(true); DELETETHIS - //patchView->triggerUpdate(true); } patchChanged(); -// oldPatchItem = (ListViewData*)patchView->selectedItem(); DELETETHIS - //patchChanged(); -// if(oldPatchItem) -// { -// if(oldPatchItem->parent()) -// patchNameEdit->setText( ((MusECore::Patch*)oldPatchItem->data())->name ); -// else -// patchNameEdit->setText( ((MusECore::PatchGroup*)oldPatchItem->data())->name ); -// } - - //MusECore::MidiControllerList* cl = instrument->controller(); - MusECore::MidiControllerList* cl = workingInstrument.controller(); for (MusECore::ciMidiController ic = cl->begin(); ic != cl->end(); ++ic) { MusECore::MidiController* c = ic->second; - //QListWidgetItem* item = new QListWidgetItem(c->name()); DELETETHIS - // ListBoxData* item = new ListBoxData(c->name()); - //QVariant v = QVariant::fromValue((void*)c); - //item->setData(Qt::UserRole, v); - // item->setData((void*)c); - // listController->insertItem(item); - addControllerToView(c); } - - //listController->setItemSelected(listController->item(0), true); DELETETHIS - -// oldController = 0; - - //ListBoxData* ci = (ListBoxData*)listController->item(0); - QTreeWidgetItem *ci = viewController->topLevelItem(0); if(ci) { - // This may cause a controllerChanged call. DELETETHIS - //if(listController->selectedItem != ci) - // listController->blockSignals(true); - // listController->setSelected(ci, true); - // listController->blockSignals(false); - //else - // controllerChanged(); - viewController->blockSignals(true); ci->setSelected(true); viewController->blockSignals(false); @@ -1211,33 +1136,6 @@ void EditInstrument::changeInstrument() controllerChanged(); - //oldController = (ListBoxData*)listController->selectedItem(); DELETETHIS - - - //controllerChanged(listController->item(0), 0); - //controllerChanged(); - -/* DELETETHIS - category->addItems(instrument->categories()); - - foreach(const SysEx* s, instrument->sysex()) { - QListWidgetItem* item = new QListWidgetItem(s->name); - QVariant v = QVariant::fromValue((void*)s); - item->setData(Qt::UserRole, v); - sysexList->addItem(item); - } - - sysexList->setItemSelected(sysexList->item(0), true); - sysexChanged(sysexList->item(0), 0); - - if (!cl->empty()) { - listController->setItemSelected(listController->item(0), true); - controllerChanged(listController->item(0), 0); - } -*/ - - - repopulatePatchCollections(); if (dlist) { @@ -1482,36 +1380,6 @@ void EditInstrument::patchNameReturn() item->setText(0, s); workingInstrument.setDirty(true); - - // DELETETHIS - // Since the name of the patch/group in the working instrument will be updated later, - // there's no need to do manually set the name here now. - /* - // If the item has a parent, it's a patch item. - if(item->parent()) - { - MusECore::Patch* p = item->data(); - if(s != p->name) - { - item->setText(s); - p->name = s; - workingInstrument.setDirty(true); - //patchView->triggerUpdate(true); - } - } - else - // The item has no parent. It's a patch group item. - { - MusECore::PatchGroup* pg = (MusECore::PatchGroup*)item->data(); - if(s != pg->name) - { - item->setText(s); - pg->name = s; - workingInstrument.setDirty(true); - //patchView->triggerUpdate(true); - } - } - */ } //--------------------------------------------------------- @@ -2130,80 +1998,6 @@ void EditInstrument::ctrlTypeChanged(int idx) c->setInitVal(spinBoxDefault->value()); } - - /* DELETETHIS - - if(rng != 0) - { - int mn = c->minVal(); - int mx = c->maxVal(); - //if(val > item->text(COL_MAX).toInt()) - if(mx > max) - { - c->setMaxVal(max); - spinBoxMax->blockSignals(true); - spinBoxMax->setValue(max); - spinBoxMax->blockSignals(false); - if(item) - item->setText(COL_MAX, QString().setNum(max)); - } - //else - if(mn < min) - { - c->setMinVal(min); - spinBoxMin->blockSignals(true); - spinBoxMin->setValue(min); - spinBoxMin->blockSignals(false); - if(item) - item->setText(COL_MIN, QString().setNum(min)); - } - //else - if(mx - mn > rng) - { - //mx = val + rng; - c->setMinVal(0); - c->setMaxVal(rng); - spinBoxMin->blockSignals(true); - spinBoxMax->blockSignals(true); - spinBoxMin->setValue(0); - spinBoxMax->setValue(rng); - spinBoxMin->blockSignals(false); - spinBoxMax->blockSignals(false); - if(item) - { - item->setText(COL_MIN, QString().setNum(0)); - item->setText(COL_MAX, QString().setNum(rng)); - } - } - - spinBoxDefault->blockSignals(true); - - spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value()); - int inval = c->initVal(); - if(inval == MusECore::CTRL_VAL_UNKNOWN) - spinBoxDefault->setValue(spinBoxDefault->minimum()); - else - { - if(inval < c->minVal()) - { - c->setInitVal(c->minVal()); - spinBoxDefault->setValue(c->minVal()); - } - else - if(inval > c->maxVal()) - { - c->setInitVal(c->maxVal()); - spinBoxDefault->setValue(c->maxVal()); - } - } - - //spinBoxDefault->setRange(c->minVal() - 1, c->maxVal()); - spinBoxDefault->blockSignals(false); - - } - - */ - workingInstrument.setDirty(true); } @@ -2507,6 +2301,115 @@ void EditInstrument::ctrlNullParamLChanged(int nvl) } //--------------------------------------------------------- +// updateSysex +//--------------------------------------------------------- + +void EditInstrument::updateSysex(MusECore::MidiInstrument* instrument, MusECore::SysEx* so) + { + if (sysexName->text() != so->name) { + so->name = sysexName->text(); + instrument->setDirty(true); + } + if (sysexComment->toPlainText() != so->comment) { + so->comment = sysexComment->toPlainText(); + instrument->setDirty(true); + } + unsigned char* data; + int len = MusECore::string2sysex(sysexData->toPlainText(), &data); + if (len == -1) // Conversion unsuccessful? + { + QMessageBox::information(0, + QString("MusE"), + QWidget::tr("Cannot convert sysex string")); + return; + } + if(so->dataLen != len || memcmp(data, so->data, len) != 0) { + if(so->dataLen != 0 && so->data) + delete[] so->data; + so->data = data; + so->dataLen = len; + instrument->setDirty(true); + } + } + +//--------------------------------------------------------- +// sysexChanged +//--------------------------------------------------------- + +void EditInstrument::sysexChanged(QListWidgetItem* sel, QListWidgetItem* old) + { + if (old) { + MusECore::SysEx* so = (MusECore::SysEx*)old->data(Qt::UserRole).value<void*>(); + updateSysex(&workingInstrument, so); + } + if (sel == 0) { + sysexName->setText(""); + sysexComment->setText(""); + sysexData->setText(""); + sysexName->setEnabled(false); + sysexComment->setEnabled(false); + sysexData->setEnabled(false); + return; + } + sysexName->setEnabled(true); + sysexComment->setEnabled(true); + sysexData->setEnabled(true); + + MusECore::SysEx* sx = (MusECore::SysEx*)sel->data(Qt::UserRole).value<void*>(); + sysexName->setText(sx->name); + sysexComment->setText(sx->comment); + sysexData->setText(MusECore::sysex2string(sx->dataLen, sx->data)); + } + +//--------------------------------------------------------- +// deleteSysexClicked +//--------------------------------------------------------- + +void EditInstrument::deleteSysexClicked() + { + QListWidgetItem* item2 = sysexList->currentItem(); + if(item2 == 0) + return; + MusECore::SysEx* sysex = (MusECore::SysEx*)item2->data(Qt::UserRole).value<void*>(); + workingInstrument.removeSysex(sysex); + delete item2; + workingInstrument.setDirty(true); + } + +//--------------------------------------------------------- +// newSysexClicked +//--------------------------------------------------------- + +void EditInstrument::newSysexClicked() + { + QString sysexName; + for (int i = 1;; ++i) { + sysexName = QString("Sysex-%1").arg(i); + + bool found = false; + foreach(const MusECore::SysEx* s, workingInstrument.sysex()) { + if (s->name == sysexName) { + found = true; + break; + } + } + if (!found) + break; + } + MusECore::SysEx* nsysex = new MusECore::SysEx; + nsysex->name = sysexName; + workingInstrument.addSysex(nsysex); + + QListWidgetItem* item = new QListWidgetItem(sysexName); + QVariant v = QVariant::fromValue((void*)nsysex); + item->setData(Qt::UserRole, v); + sysexList->addItem(item); + sysexList->setCurrentItem(item); + workingInstrument.setDirty(true); + + } + +//--------------------------------------------------------- // deletePatchClicked //--------------------------------------------------------- @@ -3002,38 +2905,6 @@ void EditInstrument::addControllerClicked() workingInstrument.setDirty(true); } -/* DELETETHIS or later needed??? -//--------------------------------------------------------- -// deleteSysexClicked -//--------------------------------------------------------- - -void EditInstrument::deleteSysexClicked() - { - //QListWidgetItem* item = instrumentList->currentItem(); - //QListWidgetItem* item2 = sysexList->currentItem(); - //if (item == 0 || item2 == 0) - // return; - - //MusECore::MidiInstrument* instrument = (MusECore::MidiInstrument*)item->data(Qt::UserRole).value<void*>(); - //SysEx* sysex = (SysEx*)item2->data(Qt::UserRole).value<void*>(); - //QList<SysEx*> sl = instrument->sysex(); - //instrument->removeSysex(sysex); - //delete item2; - //instrument->setDirty(true); - - - - ListBoxData* item = (ListBoxData*)sysexList->selectedItem(); - if(!item) - return; - - EventList* el = (EventList*)item->data(); - if(!el) - return; - - } -*/ - //--------------------------------------------------------- // updatePatchGroup //--------------------------------------------------------- @@ -3105,96 +2976,19 @@ void EditInstrument::updatePatch(MusECore::MidiInstrument* instrument, MusECore: } } -/* DELETETHIS -//--------------------------------------------------------- -// updateController -//--------------------------------------------------------- - -void EditInstrument::updateController(MusECore::MidiInstrument* instrument, MusECore::MidiController* oc) - { - printf("updateController: A\n"); - - int ctrlH = spinBoxHCtrlNo->value(); - int ctrlL = spinBoxLCtrlNo->value(); - //MusECore::MidiController::ControllerType type = (MusECore::MidiController::ControllerType)ctrlType->currentIndex(); - MusECore::MidiController::ControllerType type = (MusECore::MidiController::ControllerType)ctrlType->currentItem(); - int num = MusECore::MidiController::genNum(type, ctrlH, ctrlL); - //int num = (ctrlH << 8) & 0x7f + ctrlL & 0x7f; - - printf("updateController: B\n"); - - if (num != oc->num()) { - - printf("updateController: num changed, setting dirty. num:%d c->num:%d\n", num, oc->num()); - - oc->setNum(num); - instrument->setDirty(true); - } - - if(type != MusECore::MidiController::Pitch && type != MusECore::MidiController::Program) - { - if (spinBoxMin->value() != oc->minVal()) { - - printf("updateController: min changed, setting dirty. min:%d c->min:%d\n", spinBoxMin->value(), oc->minVal()); - - oc->setMinVal(spinBoxMin->value()); - instrument->setDirty(true); - } - if (spinBoxMax->value() != oc->maxVal()) { - - printf("updateController: max changed, setting dirty. num:%d max:%d c->max:%d\n", num, spinBoxMax->value(), oc->maxVal()); - - oc->setMaxVal(spinBoxMax->value()); - instrument->setDirty(true); - } - - int dv = spinBoxDefault->value(); - if(dv == oc->minVal() - 1) - dv = MusECore::CTRL_VAL_UNKNOWN; - - //if (spinBoxDefault->value() != oc->initVal()) { - if(dv != oc->initVal()) { - //oc->setInitVal(spinBoxDefault->value()); - oc->setInitVal(dv); - - printf("updateController: default changed, setting dirty. def:%d c->init:%d\n", dv, oc->initVal()); - - instrument->setDirty(true); - } - } - - - printf("updateController: C\n"); - - //if (moveWithPart->isChecked() ^ oc->moveWithPart()) { - // oc->setMoveWithPart(moveWithPart->isChecked()); - // instrument->setDirty(true); - // } - if (ctrlName->text() != oc->name()) { - oc->setName(ctrlName->text()); - - printf("updateController: name changed, setting dirty. name:%s c->name:%s\n", ctrlName->text().toLatin1().constData(), oc->name().toLatin1().constData()); - - instrument->setDirty(true); - } - //if (ctrlComment->toPlainText() != oc->comment()) { - // oc->setComment(ctrlComment->toPlainText()); - // instrument->setDirty(true); - // } - - printf("updateController: D\n"); - - } -*/ - //--------------------------------------------------------- // updateInstrument //--------------------------------------------------------- void EditInstrument::updateInstrument(MusECore::MidiInstrument* instrument) { - QTreeWidgetItem* patchItem = patchView->currentItem(); + QListWidgetItem* sysexItem = sysexList->currentItem(); + if (sysexItem) { + MusECore::SysEx* so = (MusECore::SysEx*)sysexItem->data(Qt::UserRole).value<void*>(); + updateSysex(instrument, so); + } + QTreeWidgetItem* patchItem = patchView->currentItem(); if (patchItem) { // If the item has a parent, it's a patch item. diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h index 187f1989..9e7af7d2 100644 --- a/muse2/muse/instruments/editinstrument.h +++ b/muse2/muse/instruments/editinstrument.h @@ -65,6 +65,7 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { void updateInstrument(MusECore::MidiInstrument*); void updatePatch(MusECore::MidiInstrument*, MusECore::Patch*); void updatePatchGroup(MusECore::MidiInstrument*, MusECore::PatchGroup*); + void updateSysex(MusECore::MidiInstrument*, MusECore::SysEx*); void changeInstrument(); QTreeWidgetItem* addControllerToView(MusECore::MidiController* mctrl); QString getPatchItemText(int); @@ -104,9 +105,9 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { void ctrlMinChanged(int); void ctrlMaxChanged(int); void ctrlDefaultChanged(int); - //void sysexChanged(); DELETETHIS? - //void deleteSysexClicked(); - //void newSysexClicked(); + void sysexChanged(QListWidgetItem*, QListWidgetItem*); + void deleteSysexClicked(); + void newSysexClicked(); void ctrlNullParamHChanged(int); void ctrlNullParamLChanged(int); diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui index db49aa9b..65bc007d 100644 --- a/muse2/muse/instruments/editinstrumentbase.ui +++ b/muse2/muse/instruments/editinstrumentbase.ui @@ -1312,6 +1312,16 @@ Typically, set to 127/127, or an unused <widget class="QLineEdit" name="sysexName"/> </item> <item> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Comment:</string> + </property> + </widget> + </item> + <item> + <widget class="QTextEdit" name="sysexComment"/> + </item> + <item> <widget class="QLabel" name="textLabel1_2"> <property name="text"> <string>Hex Entry:</string> @@ -1812,7 +1822,7 @@ Typically, set to 127/127, or an unused <x>0</x> <y>0</y> <width>802</width> - <height>25</height> + <height>21</height> </rect> </property> <property name="defaultUp"> diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index 9e4d4bd9..196ce513 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -22,11 +22,12 @@ //========================================================= #include <stdio.h> +#include <string.h> #include <QAction> #include <QDir> #include <QFileInfo> -#include <QMessageBox> +#include <QString> #include "minstrument.h" #include "midiport.h" @@ -52,12 +53,12 @@ static const char* gmdrumname = "GM-drums"; //--------------------------------------------------------- // string2sysex +// Return -1 if cannot be converted. //--------------------------------------------------------- int string2sysex(const QString& s, unsigned char** data) { - QByteArray ba = s.toLatin1(); - const char* src = ba.constData(); + const char* src = s.toLatin1().constData(); char buffer[2048]; char* dst = buffer; @@ -66,29 +67,32 @@ int string2sysex(const QString& s, unsigned char** data) while (*src == ' ' || *src == '\n') { ++src; } + if(!(*src)) + break; char* ep; long val = strtol(src, &ep, 16); if (ep == src) { - QMessageBox::information(0, - QString("MusE"), - QWidget::tr("Cannot convert sysex string")); - return 0; + printf("string2sysex: Cannot convert string to sysex %s\n", src); + return -1; } src = ep; *dst++ = val; if (dst - buffer >= 2048) { - QMessageBox::information(0, - QString("MusE"), - QWidget::tr("Hex String too long (2048 bytes limit)")); - return 0; + printf("string2sysex: Hex String too long (2048 bytes limit)\n"); + return -1; } } } int len = dst - buffer; - unsigned char* b = new unsigned char[len+1]; - memcpy(b, buffer, len); - b[len] = 0; - *data = b; + if(len > 0) + { + unsigned char* b = new unsigned char[len]; + memcpy(b, buffer, len); + *data = b; + } + else + *data = 0; + return len; } @@ -152,62 +156,6 @@ static void readEventList(Xml& xml, EventList* el, const char* name) static void loadIDF(QFileInfo* fi) { -/* DELETETHIS - QFile qf(fi->filePath()); - if (!qf.open(IO_ReadOnly)) { - printf("cannot open file %s\n", fi->fileName().toLatin1()); - return; - } - if (MusEGlobal::debugMsg) - printf(" load instrument definition <%s>\n", fi->filePath().local8Bit().data()); - QDomDocument doc; - int line, column; - QString err; - if (!doc.setContent(&qf, false, &err, &line, &column)) { - QString col, ln, error; - col.setNum(column); - ln.setNum(line); - error = err + " at line: " + ln + " col: " + col; - printf("error reading file <%s>:\n %s\n", - fi->filePath().toLatin1(), error.toLatin1()); - return; - } - QDomNode node = doc.documentElement(); - while (!node.isNull()) { - QDomElement e = node.toElement(); - if (e.isNull()) - continue; - if (e.tagName() == "muse") { - QString version = e.attribute(QString("version")); - for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) { - QDomElement e = n.toElement(); - if (e.tagName() == "MidiInstrument") { - MidiInstrument* i = new MidiInstrument(); - i->read(n); - i->setFilePath(fi->filePath()); - bool replaced = false; - for (int idx = 0; idx < midiInstruments.size(); ++idx) { - if (midiInstruments[idx]->iname() == i->iname()) { - midiInstruments.replace(idx, i); - replaced = true; - if (MusEGlobal::debugMsg) - printf("Midi Instrument Definition <%s> overwritten\n", - i->iname().toLocal8Bit().data()); - break; - } - } - if (!replaced) - midiInstruments += i; - } - } - } - else - printf("MusE:laodIDF: %s not supported\n", e.tagName().toLatin1()); - node = node.nextSibling(); - } - qf.close(); -*/ - FILE* f = fopen(fi->filePath().toAscii().constData(), "r"); if (f == 0) return; @@ -281,13 +229,6 @@ void initMidiInstruments() ++it; } } - //else DELETETHIS - //{ - // if(usrInstrumentsDir.mkdir(MusEGlobal::museUserInstruments)) - // printf("Created user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1()); - // else - // printf("Unable to create user instrument directory: %s\n", MusEGlobal::museUserInstruments.toLatin1()); - //} if (MusEGlobal::debugMsg) printf("load instrument definitions from <%s>\n", MusEGlobal::museInstruments.toLatin1().constData()); @@ -411,41 +352,16 @@ MidiInstrument::~MidiInstrument() if (_initScript) delete _initScript; + if(!_sysex.isEmpty()) + { + int j = _sysex.size(); + for(int i = 0; i < j; ++i) + delete _sysex.at(i); + } + patch_drummap_mapping.clear(); } - -/* DELETETHIS -//--------------------------------------------------------- -// uniqueCopy -//--------------------------------------------------------- - -MidiInstrument& MidiInstrument::uniqueCopy(const MidiInstrument& ins) -{ - _initScript = 0; - _midiInit = new EventList(); - _midiReset = new EventList(); - _midiState = new EventList(); - //--------------------------------------------------------- - // TODO: Copy the init script, and the lists. - //--------------------------------------------------------- - _controller = new MidiControllerList(*(ins._controller)); - - // Assignment - pg = ins.pg; - - _name = ins._name; - _filePath = ins._filePath; - - // Hmm, dirty, yes? But init sets it to false... - //_dirty = ins._dirty; - //_dirty = false; - _dirty = true; - - return *this; -} -*/ - //--------------------------------------------------------- // assign //--------------------------------------------------------- @@ -469,17 +385,19 @@ MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins) _controller->add(new MidiController(*mc)); } -// pg.clear(); -// for(iPatchGroup ipg = pg.begin(); ipg != pg.end(); ++ipg) DELETETHIS -// { - //ipg->patches.clear(); - - //const PatchGroup& g = *ipg; - //for(ciPatch ip = ipg->begin(); ip != ipg->end(); ++ipg) - //{ - - //} -// } + if(!_sysex.isEmpty()) + { + int j = _sysex.size(); + for(int i = 0; i < j; ++i) + delete _sysex.at(i); + _sysex.clear(); + } + if(!ins.sysex().isEmpty()) + { + int j = ins.sysex().size(); + for(int i = 0; i < j; ++i) + _sysex.append(new MusECore::SysEx(*(ins.sysex().at(i)))); + } for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g) { @@ -521,8 +439,6 @@ MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins) patch_drummap_mapping=ins.patch_drummap_mapping; - - // Hmm, dirty, yes? But init sets it to false... DELETETHIS //_dirty = ins._dirty; //_dirty = false; @@ -663,6 +579,94 @@ void Patch::write(int level, Xml& xml) } //--------------------------------------------------------- +// SysEx +//--------------------------------------------------------- + +SysEx::SysEx() +{ + dataLen = 0; + data = 0; +} + +SysEx::SysEx(const SysEx& src) +{ + name = src.name; + comment = src.comment; + dataLen = src.dataLen; + data = 0; + if(dataLen != 0 && src.data) + { + data = new unsigned char[dataLen]; + memcpy(data, src.data, dataLen); + } +} + +SysEx::~SysEx() +{ + if(dataLen != 0 && data) + delete[] data; +} + +bool SysEx::read(Xml& xml) + { + for (;;) { + Xml::Token token = xml.parse(); + const QString& tag = xml.s1(); + switch (token) { + case Xml::Error: + case Xml::End: + return false; + case Xml::TagStart: + if (tag == "comment") + comment = xml.parse1(); + else if (tag == "data") + { + unsigned char*d; + int len = string2sysex(xml.parse1(), &d); + // Was the conversion succesful, even if empty? + if(len != -1) + { + // Delete existing. + if(dataLen != 0 && data) + delete[] data; + dataLen = len; + data = d; + } + } + else + xml.unknown("SysEx"); + break; + case Xml::Attribut: + if (tag == "name") + name = xml.s2(); + break; + case Xml::TagEnd: + if (tag == "SysEx") + { + return !name.isEmpty(); + } + default: + break; + } + } + + return false; + } + +void SysEx::write(int level, Xml& xml) + { + xml.nput(level, "<SysEx name=\"%s\">\n", Xml::xmlString(name).toLatin1().constData()); + + level++; + if(!comment.isEmpty()) + xml.strTag(level, "comment", Xml::xmlString(comment).toLatin1().constData()); + if(dataLen > 0 && data) + xml.strTag(level, "data", sysex2string(dataLen, data)); + + xml.etag(level, "SysEx"); + } + +//--------------------------------------------------------- // readMidiState //--------------------------------------------------------- @@ -930,7 +934,16 @@ void MidiInstrument::read(Xml& xml) memcpy(_initScript, istr, len); } } - + else if (tag == "SysEx") { + SysEx* se = new SysEx; + if(!se->read(xml)) + { + delete se; + printf("MidiInstrument::read():SysEx: reading sysex failed\n"); + } + else + _sysex.append(se); + } else xml.unknown("MidiInstrument"); break; @@ -977,11 +990,8 @@ void MidiInstrument::write(int level, Xml& xml) for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g) { PatchGroup* pgp = *g; const PatchList& pl = pgp->patches; - //xml.stag(QString("PatchGroup name=\"%1\"").arg(Xml::xmlString(g->name))); - //xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(g->name).toLatin1().constData()); xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(pgp->name).toLatin1().constData()); level++; - //for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) for (ciPatch p = pl.begin(); p != pl.end(); ++p) (*p)->write(level, xml); level--; @@ -989,6 +999,12 @@ void MidiInstrument::write(int level, Xml& xml) } for (iMidiController ic = _controller->begin(); ic != _controller->end(); ++ic) ic->second->write(level, xml); + if(!_sysex.isEmpty()) + { + int j = _sysex.size(); + for(int i = 0; i < j; ++i) + _sysex.at(i)->write(level, xml); + } writeDrummaps(level, xml); diff --git a/muse2/muse/instruments/minstrument.h b/muse2/muse/instruments/minstrument.h index 4d5ad8c2..6b534672 100644 --- a/muse2/muse/instruments/minstrument.h +++ b/muse2/muse/instruments/minstrument.h @@ -78,10 +78,14 @@ struct SysEx { QString comment; int dataLen; unsigned char* data; + bool read(Xml&); + void write(int level, Xml&); + + SysEx(); + SysEx(const SysEx& src); + ~SysEx(); }; - - struct patch_collection_t { int first_program; @@ -262,8 +266,5 @@ extern void removeMidiInstrument(const MidiInstrument* instr); } // namespace MusECore -//namespace MusEGui { -//extern void populatePatchPopup(MusECore::MidiInstrument*, PopupMenu*, int, MType, bool); DELETETHIS -//} #endif diff --git a/muse2/share/instruments/gm.idf b/muse2/share/instruments/gm.idf index 69e02503..f0a66ecb 100644 --- a/muse2/share/instruments/gm.idf +++ b/muse2/share/instruments/gm.idf @@ -1,6 +1,12 @@ <?xml version="1.0"?> <muse version="1.0"> <MidiInstrument name="GM" nullparam="32639"> + <SysEx name="GM on"> + <comment>Switch General Midi mode on</comment> + <data>7e 7f 09 01</data> + </SysEx> + <Init> + </Init> <PatchGroup name="Piano"> <Patch name="Grand Piano" prog="0" /> <Patch name="Bright Piano" prog="1" /> diff --git a/muse2/share/instruments/gs.idf b/muse2/share/instruments/gs.idf index 9314e282..3f03f6bc 100644 --- a/muse2/share/instruments/gs.idf +++ b/muse2/share/instruments/gs.idf @@ -1,6 +1,12 @@ <?xml version="1.0"?> <muse version="1.0"> <MidiInstrument name="GS" nullparam="32639"> + <SysEx name="GS on"> + <comment>Switch GS mode on</comment> + <data>0x41 0x10 0x42 0x12 0x40 0x00 0x7f 0x00 0x41</data> + </SysEx> + <Init> + </Init> <PatchGroup name="Piano"> <Patch name="Grand Piano" hbank="0" lbank="0" prog="0" /> <Patch name="Bright Piano" hbank="0" lbank="0" prog="1" /> diff --git a/muse2/share/instruments/xg.idf b/muse2/share/instruments/xg.idf index c281df66..5c3175bf 100644 --- a/muse2/share/instruments/xg.idf +++ b/muse2/share/instruments/xg.idf @@ -1,6 +1,20 @@ <?xml version="1.0"?> <muse version="1.0"> <MidiInstrument name="XG" nullparam="32639"> + <SysEx name="XG on"> + <comment>Switch XG mode on</comment> + <data>0x43 0x10 0x4c 0x00 0x00 0x7e 0x00</data> + </SysEx> + <Init> + <!-- + <event tick="0" type="2" datalen="4"> + 7e 7f 09 01 + </event> + <event tick="0" type="2" datalen="7"> + 43 10 4c 00 00 7e 00 + </event> + --> + </Init> <PatchGroup name="Piano"> <Patch name="Grand Piano" hbank="0" lbank="0" prog="0" /> <Patch name="GrndPnoK" hbank="0" lbank="1" prog="0" /> |