summaryrefslogtreecommitdiff
path: root/muse2
diff options
context:
space:
mode:
authorTim E. Real <termtech@rogers.com>2012-08-01 21:23:34 +0000
committerTim E. Real <termtech@rogers.com>2012-08-01 21:23:34 +0000
commit004af724045ae8b8a0be1152b4de755f34b1b053 (patch)
tree84bd4b2de61900de081160442e6a860871bd3cb1 /muse2
parentf45bff39714939eb105b2830317ec4de77bf2bb7 (diff)
Finished the Sysex Editor in the Instrument Editor.
Create, delete, save named instrument sysexes. Does nothing more for now.
Diffstat (limited to 'muse2')
-rw-r--r--muse2/ChangeLog3
-rw-r--r--muse2/muse/instruments/editinstrument.cpp482
-rw-r--r--muse2/muse/instruments/editinstrument.h7
-rw-r--r--muse2/muse/instruments/editinstrumentbase.ui12
-rw-r--r--muse2/muse/instruments/minstrument.cpp270
-rw-r--r--muse2/muse/instruments/minstrument.h11
-rw-r--r--muse2/share/instruments/gm.idf6
-rw-r--r--muse2/share/instruments/gs.idf6
-rw-r--r--muse2/share/instruments/xg.idf14
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" />