diff options
| author | terminator356 <termtech@rogers.com> | 2014-01-10 21:16:26 -0500 | 
|---|---|---|
| committer | terminator356 <termtech@rogers.com> | 2014-01-10 21:16:26 -0500 | 
| commit | 0da82e59960c237955e14fa45965ae60b1d181b8 (patch) | |
| tree | 3c65741b7b5c82d73d01a3cbee7ce480d1ab1956 /muse2/muse | |
| parent | 59402f5bcb3804eaa7a2027f2677364c7cca544c (diff) | |
Added Initialization Sequence editor. Roland SD-50 idf. Modify sysex editor...
Diffstat (limited to 'muse2/muse')
22 files changed, 794 insertions, 271 deletions
diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index df061217..97781a2a 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -2864,7 +2864,7 @@ again:  //   startEditInstrument  //--------------------------------------------------------- -void MusE::startEditInstrument(const QString& find_instrument, EditInstrument::TabType show_tab) +void MusE::startEditInstrument(const QString& find_instrument, EditInstrumentTabType show_tab)      {        if(editInstrument == 0)        { diff --git a/muse2/muse/app.h b/muse2/muse/app.h index 5d17f096..4fe7658c 100644 --- a/muse2/muse/app.h +++ b/muse2/muse/app.h @@ -25,8 +25,8 @@  #define __APP_H__  #include "config.h" +#include "globaldefs.h"  #include "cobject.h" -#include <editinstrument.h>  #include <QFileInfo>  #include <list> @@ -60,7 +60,6 @@ class WaveTrack;  class Xml;  } -  namespace MusEGui {  class Appearance;  class Arranger; @@ -342,7 +341,7 @@ class MusE : public QMainWindow        void showArranger(bool);        void importMidi(const QString &file);        void showDidYouKnowDialog(); -      void startEditInstrument(const QString& find_instrument = QString(), EditInstrument::TabType show_tab = EditInstrument::Patches); +      void startEditInstrument(const QString& find_instrument = QString(), EditInstrumentTabType show_tab = EditInstrumentPatches);        void configMidiPorts();        void startEditor(MusECore::PartList*, int); diff --git a/muse2/muse/ctrl/ctrlpanel.cpp b/muse2/muse/ctrl/ctrlpanel.cpp index c8ed9bbd..dbbbc2f9 100644 --- a/muse2/muse/ctrl/ctrlpanel.cpp +++ b/muse2/muse/ctrl/ctrlpanel.cpp @@ -36,11 +36,11 @@  #include <math.h> +#include "globaldefs.h"  #include "app.h"  #include "globals.h"  #include "midictrl.h"  #include "instruments/minstrument.h" -#include "editinstrument.h"  #include "midiport.h"  #include "mididev.h"  #include "xml.h" @@ -646,7 +646,7 @@ void CtrlPanel::ctrlPopupTriggered(QAction* act)          }    else if (rv == edit_ins) {            // edit instrument          MusECore::MidiInstrument* instr = port->instrument(); -        MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrument::Controllers); +        MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrumentControllers);          }    else {                           // Select a control          MusECore::iMidiCtrlValList i = cll->find(channel, rv); diff --git a/muse2/muse/globaldefs.h b/muse2/muse/globaldefs.h index 300aa07d..70fd4b02 100644 --- a/muse2/muse/globaldefs.h +++ b/muse2/muse/globaldefs.h @@ -28,8 +28,9 @@  //    MT_GM  - General Midi  //    MT_GS  - Roland GS  //    MT_XG  - Yamaha XG +//    MT_GM2 - General Midi Level 2 -enum MType { MT_UNKNOWN=0, MT_GM, MT_GS, MT_XG }; +enum MType { MT_UNKNOWN=0, MT_GM, MT_GS, MT_XG, MT_GM2 };  enum AutomationType {        AUTO_OFF, AUTO_READ, AUTO_TOUCH, AUTO_WRITE @@ -49,5 +50,9 @@ const int MIDI_PORTS   = 200;  // max Number of Midi Ports  #define MIDI_CHANNELS 16       // Channels per Port  #endif +namespace MusEGui { +enum EditInstrumentTabType { EditInstrumentPatches=0, EditInstrumentDrumMaps=1, EditInstrumentControllers=2, EditInstrumentSysex=3, EditInstrumentInitSeq=4 }; +} +  #endif diff --git a/muse2/muse/helper.cpp b/muse2/muse/helper.cpp index 75cbce9f..5aae9905 100644 --- a/muse2/muse/helper.cpp +++ b/muse2/muse/helper.cpp @@ -40,6 +40,7 @@  #include "audiodev.h"  #include "midi.h"  #include "midiseq.h" +#include "midictrl.h"  #include "popupmenu.h"  #include "menutitleitem.h" diff --git a/muse2/muse/instruments/CMakeLists.txt b/muse2/muse/instruments/CMakeLists.txt index 5a3bedad..7fcc22b6 100644 --- a/muse2/muse/instruments/CMakeLists.txt +++ b/muse2/muse/instruments/CMakeLists.txt @@ -43,9 +43,7 @@ QT4_WRAP_UI ( instruments_uis ${instruments_ui_files} )  ##  file (GLOB instruments_source_files     editinstrument.cpp -   editinstrument.h     minstrument.cpp -   minstrument.h     )  ## diff --git a/muse2/muse/instruments/editinstrument.cpp b/muse2/muse/instruments/editinstrument.cpp index c0d82595..b3efdb8a 100644 --- a/muse2/muse/instruments/editinstrument.cpp +++ b/muse2/muse/instruments/editinstrument.cpp @@ -37,20 +37,25 @@  #include <QScrollBar>  #include <QVariant>  #include <QList> +#include <QString> +#include <QObject> +#include <QTreeWidgetItem>  #include <list> -#include "editinstrument.h"  #include "minstrument.h" +#include "midictrl.h" +#include "editinstrument.h"  #include "globals.h"  #include "song.h"  #include "xml.h" -#include "midictrl.h" +#include "midi.h"  #include "gconfig.h"  #include "icons.h"  #include "popupmenu.h"  #include "dlist.h"  #include "drummap.h"  #include "header.h" +#include "editevent.h"  namespace MusECore {  extern int string2sysex(const QString& s, unsigned char** data); @@ -65,6 +70,120 @@ enum {        };  //--------------------------------------------------------- +//   InitListItem +//--------------------------------------------------------- + +class InitListItem : public QTreeWidgetItem { +   public: +      MusECore::Event _event; +      MusECore::MidiInstrument* _instr; + +      InitListItem(QTreeWidget* parent, MusECore::Event ev, MusECore::MidiInstrument* ins) +         : QTreeWidgetItem(parent) { +            _event = ev; +            _instr = ins; +            setData(0, Qt::DisplayRole, colText(0)); +            setData(1, Qt::DisplayRole, colText(1)); +            setData(2, Qt::DisplayRole, colText(2)); +            setData(3, Qt::DisplayRole, colText(3)); +            } +      virtual QString colText(int col) const; + +      //virtual QVariant data(int col, int role) const; + +      virtual bool operator< ( const QTreeWidgetItem & other ) const +        { +          int col = other.treeWidget()->sortColumn(); +          InitListItem* eli = (InitListItem*) &other; +          switch(col) +          { +            case 0: +                  return _event.tick() < eli->_event.tick(); +                  break; +            case 1: +                  return _event.dataLen() < eli->_event.dataLen(); +                  break; +            case 2: +                  return colText(col).localeAwareCompare(other.text(col)) < 0; +                  break; +            case 3: +                  return colText(col).localeAwareCompare(other.text(col)) < 0; +                  break; +            default: +                  break; +            } +          return 0; +          } +      }; + +// //--------------------------------------------------------- +// //  data +// //--------------------------------------------------------- +//  +// QVariant InitListItem::data(int col, int role) const +//       { +//       if(role != Qt::DisplayRole && role != Qt::EditRole) +//         return QString(); +//       return colText(col); +//       } +       +//--------------------------------------------------------- +//   colText +//--------------------------------------------------------- + +QString InitListItem::colText(int col) const +      { +      QString s; +      QString commentLabel; +      switch(col) { +            case 0: +                  s.setNum(_event.tick()); +                  break; +            case 1: +                  s.setNum(_event.dataLen()); +                  break; +            case 2: +                  switch(_event.type()) { +                        case MusECore::Sysex: +                              { +                              int i; +                              for (i = 0; i < 10; ++i) { +                                    if (i >= _event.dataLen()) +                                          break; +                                    s += QString(" 0x"); +                                    QString k; +                                    k.setNum(_event.data()[i] & 0xff, 16); +                                    s += k; +                                    } +                              if (i == 10) +                                    s += QString("..."); +                              } +                              break; +                        default: +                              break; +                        } +                  break; +            case 3: +                  switch(_event.type()) { +                        case MusECore::Sysex: +                              { +                              return MusECore::nameSysex(_event.dataLen(), _event.data(), _instr); +                              } +                              break; +                        case MusECore::Controller: +                              s = QObject::tr("Controller !"); +                              break; +                        default: +                              s = QObject::tr("Other !"); +                              break; +                        } +                  break; + +            } +      return s; +      } +       +//---------------------------------------------------------  //   EditInstrument  //--------------------------------------------------------- @@ -73,6 +192,8 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)        {        setupUi(this); +      workingInstrument = new MusECore::MidiInstrument(); +              ctrlType->addItem(tr("Control7"), MusECore::MidiController::Controller7);        ctrlType->addItem(tr("Control14"), MusECore::MidiController::Controller14);        ctrlType->addItem(tr("RPN"), MusECore::MidiController::RPN); @@ -141,6 +262,26 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)        dlist_header->hideSection(COL_MUTE);        dlist_header->hide(); +      QFontMetrics fm(initEventList->font()); +      int n = fm.width('9'); +      int b = 24; +      initEventList->setAllColumnsShowFocus(true); +      initEventList->setSelectionMode(QAbstractItemView::SingleSelection); +      QStringList columnnames; +      columnnames << tr("Tick") +                  << tr("Len") +                  << tr("Data") +                  << tr("Name"); +      initEventList->setHeaderLabels(columnnames); +      initEventList->setColumnWidth(0, n * 6 + b); +      initEventList->setColumnWidth(1, n * 6 + b); +      //initEventList->setSortingEnabled(true);             // No sorting - we want same order of event list! +      //initEventList->sortByColumn(0, Qt::AscendingOrder); +      connect(initEventList, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), SLOT(editInitListItem(QTreeWidgetItem*))); +      connect(initChangeButton, SIGNAL(clicked(bool)), SLOT(initListChangeClicked())); +      connect(initAddButton, SIGNAL(clicked(bool)), SLOT(initListAddClicked())); +      connect(initDeleteButton, SIGNAL(clicked(bool)), SLOT(initListDeleteClicked())); +        ctrlValidLabel->setPixmap(*greendotIcon);        connect(patchFromBox, SIGNAL(valueChanged(int)), this, SLOT(patchCollectionSpinboxChanged(int))); @@ -223,6 +364,11 @@ EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)        connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked()));        } +EditInstrument::~EditInstrument() +{ +  delete workingInstrument; +} +  void EditInstrument::findInstrument(const QString& find_instrument)  {    if(find_instrument.isEmpty()) @@ -232,7 +378,7 @@ void EditInstrument::findInstrument(const QString& find_instrument)      instrumentList->setCurrentItem(found.at(0));  } -void EditInstrument::showTab(TabType n) +void EditInstrument::showTab(EditInstrumentTabType n)  {    if(n >= tabWidget3->count())      return; @@ -264,7 +410,7 @@ 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(); +  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(); @@ -303,7 +449,7 @@ void EditInstrument::storePatchCollection()        it->affected_patches.last_hbank=127;      } -    workingInstrument.setDirty(true); +    workingInstrument->setDirty(true);      repopulatePatchCollections();    }  } @@ -313,7 +459,7 @@ 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(); +  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(); @@ -357,7 +503,7 @@ void EditInstrument::patchActivated(const QModelIndex& idx)    {      using MusECore::DrumMap; -    std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); +    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"); @@ -401,7 +547,7 @@ void EditInstrument::addPatchCollection()    int idx=patchCollections->currentIndex().row(); -  std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); +  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()); @@ -410,7 +556,7 @@ void EditInstrument::addPatchCollection()    patchCollections->setCurrentIndex(patch_coll_model->index(idx+1));    patchActivated(patchCollections->currentIndex()); -  workingInstrument.setDirty(true); +  workingInstrument->setDirty(true);  }  void EditInstrument::delPatchCollection() @@ -436,7 +582,7 @@ void EditInstrument::delPatchCollection()      collUpBtn->setEnabled(false);      collDownBtn->setEnabled(false); -    std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); +    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); @@ -444,7 +590,7 @@ void EditInstrument::delPatchCollection()      repopulatePatchCollections();      patchActivated(patchCollections->currentIndex()); -    workingInstrument.setDirty(true); +    workingInstrument->setDirty(true);    }  } @@ -454,7 +600,7 @@ void EditInstrument::copyPatchCollection()    int idx=patchCollections->currentIndex().row(); -  std::list<patch_drummap_mapping_t>* tmp = workingInstrument.get_patch_drummap_mapping(); +  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); @@ -465,14 +611,14 @@ void EditInstrument::copyPatchCollection()    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); +  workingInstrument->setDirty(true);  }  void EditInstrument::patchCollectionUp()  {    using MusECore::patch_drummap_mapping_t; -  std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); +  std::list<patch_drummap_mapping_t>* pdm = workingInstrument->get_patch_drummap_mapping();    int idx=patchCollections->currentIndex().row();    if (idx>=1) @@ -492,7 +638,7 @@ void EditInstrument::patchCollectionUp()      patchCollections->setCurrentIndex(patch_coll_model->index(idx-1));      patchActivated(patchCollections->currentIndex()); -    workingInstrument.setDirty(true); +    workingInstrument->setDirty(true);    }  } @@ -500,7 +646,7 @@ void EditInstrument::patchCollectionDown()  {    using MusECore::patch_drummap_mapping_t; -  std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); +  std::list<patch_drummap_mapping_t>* pdm = workingInstrument->get_patch_drummap_mapping();    int idx=patchCollections->currentIndex().row();    if ((unsigned)idx<pdm->size()-1) @@ -520,7 +666,7 @@ void EditInstrument::patchCollectionDown()      patchCollections->setCurrentIndex(patch_coll_model->index(idx+1));      patchActivated(patchCollections->currentIndex()); -    workingInstrument.setDirty(true); +    workingInstrument->setDirty(true);    }  } @@ -531,7 +677,7 @@ void EditInstrument::repopulatePatchCollections()    int idx=patchCollections->currentIndex().row();    QStringList strlist; -  std::list<patch_drummap_mapping_t>* pdm = workingInstrument.get_patch_drummap_mapping(); +  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(); @@ -572,7 +718,7 @@ void EditInstrument::fileNew()                          MusECore::MidiInstrument* oi = 0;                          if(oldMidiInstrument)                            oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>(); -                        MusECore::MidiInstrument* wip = &workingInstrument; +                        MusECore::MidiInstrument* wip = workingInstrument;                          if(checkDirty(wip)) // No save was chosen. Restore the actual instrument name.                          {                            if(oi) @@ -586,13 +732,13 @@ void EditInstrument::fileNew()                            }                            } -                        workingInstrument.setDirty(false); +                        workingInstrument->setDirty(false);                    MusECore::MidiInstrument* ni = new MusECore::MidiInstrument(s);                    MusECore::midiInstruments.push_back(ni);                    QListWidgetItem* item = new QListWidgetItem(ni->iname()); -                  workingInstrument.assign( *ni ); +                  workingInstrument->assign( *ni );                    QVariant v = qVariantFromValue((void*)(ni));                    item->setData(Qt::UserRole, v); @@ -607,7 +753,7 @@ void EditInstrument::fileNew()                    changeInstrument();                    // We have our new instrument! So set dirty to true. -                  workingInstrument.setDirty(true); +                  workingInstrument->setDirty(true);                    break;                    } @@ -629,21 +775,21 @@ void EditInstrument::fileOpen() //DELETETHIS?  void EditInstrument::fileSave()  { -      if (workingInstrument.filePath().isEmpty()) +      if (workingInstrument->filePath().isEmpty())        {          saveAs();          return;        }              // Do not allow a direct overwrite of a 'built-in' muse instrument. -      QFileInfo qfi(workingInstrument.filePath()); +      QFileInfo qfi(workingInstrument->filePath());        if(qfi.absolutePath() == MusEGlobal::museInstruments)        {          saveAs();          return;        } -      FILE* f = fopen(workingInstrument.filePath().toLatin1().constData(), "w"); +      FILE* f = fopen(workingInstrument->filePath().toLatin1().constData(), "w");        if(f == 0)        {          saveAs(); @@ -657,14 +803,14 @@ void EditInstrument::fileSave()        if(fclose(f) != 0)        { -        QString s = QString("Creating file:\n") + workingInstrument.filePath() + QString("\nfailed: ") +        QString s = QString("Creating file:\n") + workingInstrument->filePath() + QString("\nfailed: ")            + QString(strerror(errno) );          QMessageBox::critical(this, tr("MusE: Create file failed"), s);          return;        } -      if(fileSave(&workingInstrument, workingInstrument.filePath())) -        workingInstrument.setDirty(false); +      if(fileSave(workingInstrument, workingInstrument->filePath())) +        workingInstrument->setDirty(false);  }  //--------------------------------------------------------- @@ -695,7 +841,7 @@ bool EditInstrument::fileSave(MusECore::MidiInstrument* instrument, const QStrin          MusECore::MidiInstrument* oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();          if(oi)          { -          oi->assign(workingInstrument); +          oi->assign(*workingInstrument);            // Now signal the rest of the app so stuff can change...            MusEGlobal::song->update(SC_CONFIG | SC_MIDI_CONTROLLER); @@ -732,10 +878,10 @@ void EditInstrument::saveAs()          //path = MusEGlobal::configPath;          } -      if (workingInstrument.filePath().isEmpty()) -            path += QString("/%1.idf").arg(workingInstrument.iname()); +      if (workingInstrument->filePath().isEmpty()) +            path += QString("/%1.idf").arg(workingInstrument->iname());        else { -            QFileInfo fi(workingInstrument.filePath()); +            QFileInfo fi(workingInstrument->filePath());              // Prompt for a new instrument name if the name has not been changed, to avoid duplicates.              if(oldMidiInstrument) @@ -743,13 +889,13 @@ void EditInstrument::saveAs()                MusECore::MidiInstrument* oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();                if(oi)                { -                if(oi->iname() == workingInstrument.iname()) +                if(oi->iname() == workingInstrument->iname())                  {                    // Prompt only if it's a user instrument, to avoid duplicates in the user instrument dir.                    // This will still allow a user instrument to override a built-in instrument with the same name.                    if(fi.absolutePath() != MusEGlobal::museInstruments)                    { -                    printf("EditInstrument::saveAs Error: Instrument name %s already used!\n", workingInstrument.iname().toLatin1().constData()); +                    printf("EditInstrument::saveAs Error: Instrument name %s already used!\n", workingInstrument->iname().toLatin1().constData());                      return;                        }                    } @@ -762,10 +908,10 @@ void EditInstrument::saveAs()           path, tr("Instrument Definition (*.idf)"));        if (s.isEmpty())              return; -      workingInstrument.setFilePath(s); +      workingInstrument->setFilePath(s); -      if(fileSave(&workingInstrument, s)) -        workingInstrument.setDirty(false); +      if(fileSave(workingInstrument, s)) +        workingInstrument->setDirty(false);      }  //--------------------------------------------------------- @@ -775,7 +921,7 @@ void EditInstrument::saveAs()  void EditInstrument::fileSaveAs()      {        // Is this a new unsaved instrument? Just do a normal save. -      if(workingInstrument.filePath().isEmpty()) +      if(workingInstrument->filePath().isEmpty())        {          saveAs();          return; @@ -790,12 +936,12 @@ void EditInstrument::fileSaveAs()        if(oldMidiInstrument)          oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>(); -      int res = checkDirty(&workingInstrument, true); +      int res = checkDirty(workingInstrument, true);        switch(res)        {          // No save:          case 1: -          workingInstrument.setDirty(false); +          workingInstrument->setDirty(false);            if(oi)            {              oldMidiInstrument->setText(oi->iname()); @@ -821,16 +967,16 @@ void EditInstrument::fileSaveAs()          // Save:          case 0: -            workingInstrument.setDirty(false); +            workingInstrument->setDirty(false);          break;        }        bool isuser = false;        QString so; -      if(workingInstrument.iname().isEmpty()) +      if(workingInstrument->iname().isEmpty())          so = QString("Instrument");        else   -        so = workingInstrument.iname(); +        so = workingInstrument->iname();        for(int i = 1;; ++i)         { @@ -872,7 +1018,7 @@ void EditInstrument::fileSaveAs()            if((*imi)->iname() == s)             {              // If it's not the same name as the working instrument, and it's not an internal instrument (soft synth etc.)... -            if(s != workingInstrument.iname() && !(*imi)->filePath().isEmpty()) +            if(s != workingInstrument->iname() && !(*imi)->filePath().isEmpty())              {                QFileInfo fi((*imi)->filePath());                // Allow override of built-in and user instruments: @@ -889,7 +1035,7 @@ void EditInstrument::fileSaveAs()                      Qt::NoButton) == QMessageBox::Ok)                  {                    // Set the working instrument's file path to the found instrument's path. -                  workingInstrument.setFilePath((*imi)->filePath()); +                  workingInstrument->setFilePath((*imi)->filePath());                    // Mark as overwriting a user instrument.                    isuser = true;                  }   @@ -901,7 +1047,7 @@ void EditInstrument::fileSaveAs()                }                // Assign the found instrument name to the working instrument name. -              workingInstrument.setIName(s); +              workingInstrument->setIName(s);                // Find the instrument in the list and set the old instrument to the item.                oldMidiInstrument = instrumentList->findItems(s, Qt::MatchExactly)[0]; @@ -927,13 +1073,13 @@ void EditInstrument::fileSaveAs()          if(!builtin)          {            MusECore::MidiInstrument* ni = new MusECore::MidiInstrument(); -          ni->assign(workingInstrument); +          ni->assign(*workingInstrument);            ni->setIName(so);            ni->setFilePath(QString());            MusECore::midiInstruments.push_back(ni);            QListWidgetItem* item = new QListWidgetItem(so); -          workingInstrument.assign( *ni ); +          workingInstrument->assign( *ni );            QVariant v = qVariantFromValue((void*)(ni));            item->setData(Qt::UserRole, v); @@ -948,7 +1094,7 @@ void EditInstrument::fileSaveAs()            changeInstrument();            // We have our new instrument! So set dirty to true. -          workingInstrument.setDirty(true); +          workingInstrument->setDirty(true);          }            break; @@ -975,11 +1121,11 @@ void EditInstrument::fileSaveAs()             path, tr("Instrument Definition (*.idf)"));          if (sfn.isEmpty())                return; -        workingInstrument.setFilePath(sfn); +        workingInstrument->setFilePath(sfn);        }   -      if(fileSave(&workingInstrument, sfn)) -        workingInstrument.setDirty(false); +      if(fileSave(workingInstrument, sfn)) +        workingInstrument->setDirty(false);      }  //--------------------------------------------------------- @@ -1006,12 +1152,12 @@ void EditInstrument::closeEvent(QCloseEvent* ev)          if(oldMidiInstrument)            oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>(); -        int res = checkDirty(&workingInstrument, true); +        int res = checkDirty(workingInstrument, true);          switch(res)          {            // No save:            case 1: -            workingInstrument.setDirty(false); +            workingInstrument->setDirty(false);              if(oi)              {                oldMidiInstrument->setText(oi->iname()); @@ -1037,7 +1183,7 @@ void EditInstrument::closeEvent(QCloseEvent* ev)            // Save:            case 0: -              workingInstrument.setDirty(false); +              workingInstrument->setDirty(false);            break;          } @@ -1060,9 +1206,9 @@ void EditInstrument::changeInstrument()    // Assignment    // Assign will 'delete' any existing patches, groups, or controllers. -  workingInstrument.assign( *((MusECore::MidiInstrument*)sel->data(Qt::UserRole).value<void*>()) ); +  workingInstrument->assign( *((MusECore::MidiInstrument*)sel->data(Qt::UserRole).value<void*>()) ); -  workingInstrument.setDirty(false); +  workingInstrument->setDirty(false);    // populate patch list    patchView->blockSignals(true); @@ -1076,12 +1222,12 @@ void EditInstrument::changeInstrument()    viewController->clear();    instrumentName->blockSignals(true); -  instrumentName->setText(workingInstrument.iname()); +  instrumentName->setText(workingInstrument->iname());    instrumentName->blockSignals(false);    nullParamSpinBoxH->blockSignals(true);    nullParamSpinBoxL->blockSignals(true); -  int nv = workingInstrument.nullSendValue(); +  int nv = workingInstrument->nullSendValue();    if(nv == -1)    {      nullParamSpinBoxH->setValue(-1); @@ -1105,7 +1251,9 @@ void EditInstrument::changeInstrument()    sysexList->blockSignals(true);    sysexList->clear(); -  foreach(const MusECore::SysEx* s, workingInstrument.sysex()) { +  foreach(const MusECore::SysEx* s, workingInstrument->sysex()) { +        if(!s) +          continue;          QListWidgetItem* item = new QListWidgetItem(s->name);          QVariant v = QVariant::fromValue((void*)s);          item->setData(Qt::UserRole, v); @@ -1115,8 +1263,10 @@ void EditInstrument::changeInstrument()      sysexList->item(0)->setSelected(true);    sysexList->blockSignals(false);    sysexChanged(sysexList->item(0), 0); + +  populateInitEventList(); -  MusECore::PatchGroupList* pg = workingInstrument.groups(); +  MusECore::PatchGroupList* pg = workingInstrument->groups();    for (MusECore::ciPatchGroup g = pg->begin(); g != pg->end(); ++g) {          MusECore::PatchGroup* pgp = *g;           if(pgp) @@ -1154,7 +1304,7 @@ void EditInstrument::changeInstrument()    patchChanged(); -  MusECore::MidiControllerList* cl = workingInstrument.controller(); +  MusECore::MidiControllerList* cl = workingInstrument->controller();    for (MusECore::ciMidiController ic = cl->begin(); ic != cl->end(); ++ic) {          MusECore::MidiController* c = ic->second;          addControllerToView(c); @@ -1205,7 +1355,7 @@ void EditInstrument::instrumentChanged()          MusECore::MidiInstrument* oi = 0;          if(oldMidiInstrument)            oi = (MusECore::MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>(); -        MusECore::MidiInstrument* wip = &workingInstrument; +        MusECore::MidiInstrument* wip = workingInstrument;          // Returns true if aborted.          if(checkDirty(wip))          { @@ -1224,7 +1374,7 @@ void EditInstrument::instrumentChanged()            }            } -        workingInstrument.setDirty(false); +        workingInstrument->setDirty(false);          changeInstrument();        } @@ -1267,8 +1417,8 @@ void EditInstrument::instrumentNameReturn()    }          item->setText(s); -  workingInstrument.setIName(s); -  workingInstrument.setDirty(true); +  workingInstrument->setIName(s); +  workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -1321,9 +1471,9 @@ void EditInstrument::tabChanged(QWidget* w)    {      // Don't bother calling patchChanged, just update the patch or group.      if(oldPatchItem->QTreeWidgetItem::parent()) -      updatePatch(&workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +      updatePatch(workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());      else -      updatePatchGroup(&workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +      updatePatchGroup(workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());    }    // We're still on the same item. No need to set oldPatchItem as in patchChanged... @@ -1362,7 +1512,7 @@ void EditInstrument::patchNameReturn()    if(item->text(0) == s)      return; -  MusECore::PatchGroupList* pg = workingInstrument.groups(); +  MusECore::PatchGroupList* pg = workingInstrument->groups();    for(MusECore::iPatchGroup g = pg->begin(); g != pg->end(); ++g)     {      MusECore::PatchGroup* pgp = *g; @@ -1414,7 +1564,7 @@ void EditInstrument::patchNameReturn()    }      item->setText(0, s); -    workingInstrument.setDirty(true); +    workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -1425,9 +1575,9 @@ void EditInstrument::patchChanged()        if(oldPatchItem)        {              if(oldPatchItem->parent()) -                    updatePatch(&workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +                    updatePatch(workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());              else -                    updatePatchGroup(&workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +                    updatePatchGroup(workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());        }        QTreeWidgetItem* sel = patchView->selectedItems().size() ? patchView->selectedItems()[0] : 0; @@ -1439,7 +1589,8 @@ void EditInstrument::patchChanged()          spinBoxHBank->setEnabled(false);          spinBoxLBank->setEnabled(false);          spinBoxProgram->setEnabled(false); -        checkBoxDrum->setEnabled(false); +        showPatchInMidiButton->setEnabled(false); +        showPatchInDrumsButton->setEnabled(false);          // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.          //checkBoxGM->setEnabled(false);          //checkBoxGS->setEnabled(false); @@ -1455,7 +1606,8 @@ void EditInstrument::patchChanged()          spinBoxHBank->setEnabled(true);          spinBoxLBank->setEnabled(true);          spinBoxProgram->setEnabled(true); -        checkBoxDrum->setEnabled(true); +        showPatchInMidiButton->setEnabled(true); +        showPatchInDrumsButton->setEnabled(true);          // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.          //checkBoxGM->setEnabled(true);          //checkBoxGS->setEnabled(true); @@ -1467,7 +1619,8 @@ void EditInstrument::patchChanged()          spinBoxHBank->setValue(hb);          spinBoxLBank->setValue(lb);          spinBoxProgram->setValue(pr); -        checkBoxDrum->setChecked(p->drum); +        showPatchInMidiButton->setChecked(!p->drum); +        showPatchInDrumsButton->setChecked(p->drum);          // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.          //checkBoxGM->setChecked(p->typ & 1);          //checkBoxGS->setChecked(p->typ & 2); @@ -1480,7 +1633,8 @@ void EditInstrument::patchChanged()          spinBoxHBank->setEnabled(false);          spinBoxLBank->setEnabled(false);          spinBoxProgram->setEnabled(false); -        checkBoxDrum->setEnabled(false); +        showPatchInMidiButton->setEnabled(false); +        showPatchInDrumsButton->setEnabled(false);          // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.          //checkBoxGM->setEnabled(false);          //checkBoxGS->setEnabled(false); @@ -1508,7 +1662,7 @@ void EditInstrument::defPatchChanged(int)        setDefaultPatchName(val);        item->setText(COL_DEF, getPatchItemText(val)); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -1519,7 +1673,7 @@ void EditInstrument::patchButtonClicked()  {        QMenu* patchpopup = new QMenu; -      MusECore::PatchGroupList* pg = workingInstrument.groups(); +      MusECore::PatchGroupList* pg = workingInstrument->groups();        if (pg->size() > 1) {              for (MusECore::ciPatchGroup i = pg->begin(); i != pg->end(); ++i) { @@ -1578,7 +1732,7 @@ void EditInstrument::patchButtonClicked()            item->setText(COL_DEF, getPatchItemText(rv));          } -        workingInstrument.setDirty(true); +        workingInstrument->setDirty(true);        }  } @@ -1856,7 +2010,7 @@ void EditInstrument::ctrlNameReturn()        QString cName = ctrlName->text(); -      MusECore::MidiControllerList* cl = workingInstrument.controller(); +      MusECore::MidiControllerList* cl = workingInstrument->controller();        for(MusECore::ciMidiController ic = cl->begin(); ic != cl->end(); ++ic)         {          MusECore::MidiController* mc = ic->second; @@ -1882,7 +2036,7 @@ void EditInstrument::ctrlNameReturn()        c->setName(ctrlName->text());        item->setText(COL_CNAME, ctrlName->text()); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -1948,7 +2102,7 @@ void EditInstrument::ctrlTypeChanged(int idx)              }              int new_num = MusECore::MidiController::genNum(t, hnum, lnum); -      MusECore::MidiControllerList* cl = workingInstrument.controller(); +      MusECore::MidiControllerList* cl = workingInstrument->controller();        // Check if either a per-note controller, or else a regular controller already exists.        if(!cl->ctrlAvailable(new_num, c))        { @@ -2097,7 +2251,7 @@ void EditInstrument::ctrlTypeChanged(int idx)            c->setInitVal(spinBoxDefault->value());        }   -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2123,7 +2277,7 @@ void EditInstrument::ctrlShowInMidiChanged(int state)          c->setShowInTracks(show & ~MusECore::MidiController::ShowInMidi);          item->setText(COL_SHOW_MIDI, "");        } -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2149,7 +2303,7 @@ void EditInstrument::ctrlShowInDrumChanged(int state)          c->setShowInTracks(show & ~MusECore::MidiController::ShowInDrum);          item->setText(COL_SHOW_DRUM, "");        } -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2195,7 +2349,7 @@ void EditInstrument::ctrlNumChanged()          return;        } -      MusECore::MidiControllerList* cl = workingInstrument.controller(); +      MusECore::MidiControllerList* cl = workingInstrument->controller();        MusECore::MidiController* c = (MusECore::MidiController*)item->data(0, Qt::UserRole).value<void*>();        // Check if either a per-note controller, or else a regular controller already exists. @@ -2234,7 +2388,7 @@ void EditInstrument::ctrlNumChanged()                    return;              }        item->setText(COL_TYPE, ctrlType->currentText()); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2320,7 +2474,7 @@ void EditInstrument::ctrlMinChanged(int val)        spinBoxDefault->blockSignals(false); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -2406,7 +2560,7 @@ void EditInstrument::ctrlMaxChanged(int val)        spinBoxDefault->blockSignals(false); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -2432,7 +2586,7 @@ void EditInstrument::ctrlDefaultChanged(int val)          c->setInitVal(val);          item->setText(COL_DEF, QString().setNum(val));        } -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -2460,10 +2614,10 @@ void EditInstrument::ctrlNullParamHChanged(int nvh)      }    }    if(nvh == -1 && nvl == -1) -    workingInstrument.setNullSendValue(-1); +    workingInstrument->setNullSendValue(-1);    else   -    workingInstrument.setNullSendValue((nvh << 8) | nvl); -  workingInstrument.setDirty(true); +    workingInstrument->setNullSendValue((nvh << 8) | nvl); +  workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -2491,10 +2645,10 @@ void EditInstrument::ctrlNullParamLChanged(int nvl)      }    }    if(nvh == -1 && nvl == -1) -    workingInstrument.setNullSendValue(-1); +    workingInstrument->setNullSendValue(-1);    else   -    workingInstrument.setNullSendValue((nvh << 8) | nvl); -  workingInstrument.setDirty(true); +    workingInstrument->setNullSendValue((nvh << 8) | nvl); +  workingInstrument->setDirty(true);  }  //--------------------------------------------------------- @@ -2537,7 +2691,7 @@ void EditInstrument::sysexChanged(QListWidgetItem* sel, QListWidgetItem* old)        {        if (old) {              MusECore::SysEx* so = (MusECore::SysEx*)old->data(Qt::UserRole).value<void*>(); -            updateSysex(&workingInstrument, so); +            updateSysex(workingInstrument, so);              }        if (sel == 0) {              sysexName->setText(""); @@ -2568,9 +2722,9 @@ void EditInstrument::deleteSysexClicked()        if(item2 == 0)          return;        MusECore::SysEx* sysex  = (MusECore::SysEx*)item2->data(Qt::UserRole).value<void*>(); -      workingInstrument.removeSysex(sysex); +      workingInstrument->removeSysex(sysex);        delete item2; -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2584,7 +2738,7 @@ void EditInstrument::newSysexClicked()              sysexName = QString("Sysex-%1").arg(i);              bool found = false; -            foreach(const MusECore::SysEx* s, workingInstrument.sysex()) { +            foreach(const MusECore::SysEx* s, workingInstrument->sysex()) {                    if (s->name == sysexName) {                          found = true;                          break; @@ -2595,14 +2749,14 @@ void EditInstrument::newSysexClicked()              }        MusECore::SysEx* nsysex = new MusECore::SysEx;        nsysex->name = sysexName; -      workingInstrument.addSysex(nsysex); +      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); +      workingInstrument->setDirty(true);        } @@ -2640,7 +2794,7 @@ void EditInstrument::deletePatchClicked()          if(group)          { -          MusECore::PatchGroupList* pg = workingInstrument.groups(); +          MusECore::PatchGroupList* pg = workingInstrument->groups();            for(MusECore::iPatchGroup ipg = pg->begin(); ipg != pg->end(); ++ipg)            { @@ -2676,7 +2830,7 @@ void EditInstrument::deletePatchClicked()        oldPatchItem = 0;        patchChanged(); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2688,12 +2842,12 @@ void EditInstrument::newPatchClicked()        if(oldPatchItem)        {          if(oldPatchItem->parent()) -          updatePatch(&workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +          updatePatch(workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());          else   -          updatePatchGroup(&workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +          updatePatchGroup(workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());        }   -      MusECore::PatchGroupList* pg = workingInstrument.groups(); +      MusECore::PatchGroupList* pg = workingInstrument->groups();        QString patchName;        for (int i = 1;; ++i) {              patchName = QString("Patch-%1").arg(i); @@ -2834,7 +2988,8 @@ void EditInstrument::newPatchClicked()        spinBoxHBank->setEnabled(true);        spinBoxLBank->setEnabled(true);        spinBoxProgram->setEnabled(true); -      checkBoxDrum->setEnabled(true); +      showPatchInMidiButton->setEnabled(true); +      showPatchInDrumsButton->setEnabled(true);        // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.        //checkBoxGM->setEnabled(true);        //checkBoxGS->setEnabled(true); @@ -2843,7 +2998,7 @@ void EditInstrument::newPatchClicked()        oldPatchItem = 0;        patchChanged(); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2855,12 +3010,12 @@ void EditInstrument::newGroupClicked()        if(oldPatchItem)        {          if(oldPatchItem->parent()) -          updatePatch(&workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +          updatePatch(workingInstrument, (MusECore::Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());          else   -          updatePatchGroup(&workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>()); +          updatePatchGroup(workingInstrument, (MusECore::PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());        }   -      MusECore::PatchGroupList* pg = workingInstrument.groups(); +      MusECore::PatchGroupList* pg = workingInstrument->groups();        QString groupName;        for (int i = 1;; ++i) {              groupName = QString("Group-%1").arg(i); @@ -2903,13 +3058,14 @@ void EditInstrument::newGroupClicked()        spinBoxHBank->setEnabled(false);        spinBoxLBank->setEnabled(false);        spinBoxProgram->setEnabled(false); -      checkBoxDrum->setEnabled(false); +      showPatchInMidiButton->setEnabled(false); +      showPatchInDrumsButton->setEnabled(false);        // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.        //checkBoxGM->setEnabled(false);        //checkBoxGS->setEnabled(false);        //checkBoxXG->setEnabled(false); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2927,7 +3083,7 @@ void EditInstrument::deleteControllerClicked()        if(!ctrl)          return; -      workingInstrument.controller()->erase(ctrl->num());    +      workingInstrument->controller()->erase(ctrl->num());           // Now delete the controller.        delete ctrl; @@ -2941,7 +3097,7 @@ void EditInstrument::deleteControllerClicked()        controllerChanged(); -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -2951,7 +3107,7 @@ void EditInstrument::deleteControllerClicked()  void EditInstrument::newControllerClicked()        {              QString cName; -      MusECore::MidiControllerList* cl = workingInstrument.controller(); +      MusECore::MidiControllerList* cl = workingInstrument->controller();        for (int i = 1;; ++i) {              cName = QString("Controller-%1").arg(i);              bool found = false; @@ -3069,7 +3225,7 @@ void EditInstrument::newControllerClicked()        ctrl->setName(cName); -      workingInstrument.controller()->add(ctrl);    +      workingInstrument->controller()->add(ctrl);           QTreeWidgetItem* item = addControllerToView(ctrl);        if(viewController->currentItem() != item) @@ -3080,7 +3236,7 @@ void EditInstrument::newControllerClicked()          controllerChanged();        } -      workingInstrument.setDirty(true); +      workingInstrument->setDirty(true);        }  //--------------------------------------------------------- @@ -3091,7 +3247,7 @@ void EditInstrument::addControllerClicked()  {    // Add Common Controls not already found in instrument:    PopupMenu* pup = new PopupMenu(true);  // true = enable stay open. Don't bother with parent. -  MusECore::MidiControllerList* cl = workingInstrument.controller(); +  MusECore::MidiControllerList* cl = workingInstrument->controller();    for(int num = 0; num < 127; ++num)    {      // If it's not already in the parent menu... @@ -3112,7 +3268,7 @@ void EditInstrument::ctrlPopupTriggered(QAction* act)    if(!act || (act->data().toInt() == -1))      return;    int rv = act->data().toInt(); -  MusECore::MidiControllerList* cl = workingInstrument.controller(); +  MusECore::MidiControllerList* cl = workingInstrument->controller();    if(cl->find(rv) == cl->end())    {      int num = rv; // = MusECore::MidiController::genNum(MusECore::MidiController::Controller7, 0, rv); @@ -3123,7 +3279,7 @@ void EditInstrument::ctrlPopupTriggered(QAction* act)      ctrl->setInitVal(MusECore::CTRL_VAL_UNKNOWN);      ctrl->setName(MusECore::midiCtrlName(num, false)); -    workingInstrument.controller()->add(ctrl); +    workingInstrument->controller()->add(ctrl);      QTreeWidgetItem* item = addControllerToView(ctrl); @@ -3135,7 +3291,7 @@ void EditInstrument::ctrlPopupTriggered(QAction* act)        controllerChanged();      } -    workingInstrument.setDirty(true); +    workingInstrument->setDirty(true);    }  } @@ -3185,11 +3341,11 @@ void EditInstrument::updatePatch(MusECore::MidiInstrument* instrument, MusECore:              instrument->setDirty(true);              } -      if (p->drum != checkBoxDrum->isChecked()) { -            p->drum = checkBoxDrum->isChecked(); +      if (p->drum != showPatchInDrumsButton->isChecked()) {  // Midi and drums radio buttons are exclusive. +            p->drum = showPatchInDrumsButton->isChecked();              instrument->setDirty(true);              } -       +                    // there is no logical xor in c++  // REMOVE Tim. OBSOLETE. When gui boxes are finally removed.  //       bool a = p->typ & 1; @@ -3488,7 +3644,7 @@ QString EditInstrument::getPatchName(int prog)        int hbank = (prog >> 16) & 0xff;        int lbank = (prog >> 8) & 0xff; -      MusECore::PatchGroupList* pg = workingInstrument.groups(); +      MusECore::PatchGroupList* pg = workingInstrument->groups();        for(MusECore::ciPatchGroup i = pg->begin(); i != pg->end(); ++i) {              const MusECore::PatchList& pl = (*i)->patches; @@ -3509,4 +3665,102 @@ QString EditInstrument::getPatchName(int prog)        return "---";  } +//--------------------------------------------------------- +// populateInitEventList +//--------------------------------------------------------- + +void EditInstrument::populateInitEventList() +{ +  initEventList->blockSignals(true); +  initEventList->clear(); +  MusECore::EventList* el = workingInstrument->midiInit(); +  for(MusECore::iEvent ie = el->begin(); ie != el->end(); ++ie) +  { +    InitListItem* item = new InitListItem(initEventList, ie->second, workingInstrument); +    initEventList->addTopLevelItem(item); +  } +  if(initEventList->topLevelItem(0)) +    initEventList->topLevelItem(0)->setSelected(true); +  initEventList->blockSignals(false); +} + +//--------------------------------------------------------- +// initListChangeClicked +//--------------------------------------------------------- + +void EditInstrument::initListChangeClicked() +{ +  InitListItem* item = static_cast<InitListItem*>(initEventList->currentItem());   +  if(!item) +    return; +  editInitListItem(item); +} + +//--------------------------------------------------------- +// editInitListItem +//--------------------------------------------------------- + +void EditInstrument::editInitListItem(QTreeWidgetItem* item) +{ +  InitListItem* ev = (InitListItem*)item; +  if(ev->_event.type() != MusECore::Sysex) +    return; +  int tick = ev->_event.tick(); +  MusECore::Event nevent = EditSysexDialog::getEvent(tick, ev->_event, this, workingInstrument); +  if(!nevent.empty()) +  { +    MusECore::EventList* el = workingInstrument->midiInit(); +    MusECore::iEvent ie = el->find(ev->_event); +    if(ie != el->end()) +      el->erase(ie); +    el->add(nevent); +    //delete item; +    //item = new InitListItem(initEventList, nevent, &workingInstrument); +    //initEventList->addTopLevelItem(item); +    //initEventList->setCurrentItem(item); +    populateInitEventList(); +    workingInstrument->setDirty(true); +  } +} + +//--------------------------------------------------------- +//   initListAddClicked +//--------------------------------------------------------- + +void EditInstrument::initListAddClicked() +{ +  //MusECore::Event event = EditSysexDialog::getEvent(curPart->tick(), MusECore::Event(), this); +  // TODO Get current item tick, if any +  MusECore::Event event = EditSysexDialog::getEvent(0, MusECore::Event(), this, workingInstrument);   +  if(!event.empty())  +  { +    workingInstrument->midiInit()->add(event); +    //InitListItem* item = new InitListItem(initEventList, event, &workingInstrument); +    //initEventList->addTopLevelItem(item); +    //initEventList->setCurrentItem(item); +    populateInitEventList(); +    workingInstrument->setDirty(true); +  } +} + +//--------------------------------------------------------- +// initListDeleteClicked +//--------------------------------------------------------- + +void EditInstrument::initListDeleteClicked() +{ +  InitListItem* item = static_cast<InitListItem*>(initEventList->currentItem());   +  if(!item) +    return; +  MusECore::EventList* el = workingInstrument->midiInit(); +  MusECore::iEvent ie = el->find(item->_event); +  if(ie != el->end()) +  { +    el->erase(ie); +    populateInitEventList(); +  } +  //delete item; +  workingInstrument->setDirty(true); +} +  } // namespace MusEGui diff --git a/muse2/muse/instruments/editinstrument.h b/muse2/muse/instruments/editinstrument.h index ff156988..1a753bf0 100644 --- a/muse2/muse/instruments/editinstrument.h +++ b/muse2/muse/instruments/editinstrument.h @@ -26,8 +26,8 @@  #define __EDITINSTRUMENT_H__  #include "ui_editinstrumentbase.h" -#include "minstrument.h" -#include "midictrl.h" + +#include "globaldefs.h"  class QDialog;  class QMenu; @@ -37,6 +37,15 @@ class QStringListModel;  class QString;  class QAction; +namespace MusECore { + +class MidiInstrument; +class MidiController; +class Patch; +class PatchGroup; +class SysEx; +} +  namespace MusEGui {  class Header; @@ -49,7 +58,7 @@ class DList;  class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {      Q_OBJECT -      MusECore::MidiInstrument workingInstrument; +      MusECore::MidiInstrument* workingInstrument;        QListWidgetItem*  oldMidiInstrument;        QTreeWidgetItem* oldPatchItem; @@ -70,6 +79,7 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {        void updatePatchGroup(MusECore::MidiInstrument*, MusECore::PatchGroup*);        void updateSysex(MusECore::MidiInstrument*, MusECore::SysEx*);        void changeInstrument(); +      void populateInitEventList();        QTreeWidgetItem* addControllerToView(MusECore::MidiController* mctrl);        QString getPatchItemText(int);        void enableDefaultControls(bool, bool); @@ -116,6 +126,10 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {        void newSysexClicked();        void ctrlNullParamHChanged(int);        void ctrlNullParamLChanged(int); +      void editInitListItem(QTreeWidgetItem* item); +      void initListDeleteClicked(); +      void initListAddClicked(); +      void initListChangeClicked();        void patchCollectionSpinboxChanged(int);        void patchCollectionCheckboxChanged(bool); @@ -130,11 +144,10 @@ class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {        void fetchPatchCollection();     public: -      enum TabType { Patches=0, DrumMaps=1, Controllers=2, Sysex=3 }; -              EditInstrument(QWidget* parent = 0, Qt::WFlags fl = Qt::Window); +      virtual ~EditInstrument();        void findInstrument(const QString& find_instrument); -      void showTab(TabType); +      void showTab(EditInstrumentTabType);        };  } // namespace MusEGui diff --git a/muse2/muse/instruments/editinstrumentbase.ui b/muse2/muse/instruments/editinstrumentbase.ui index 5140b27d..471f1318 100644 --- a/muse2/muse/instruments/editinstrumentbase.ui +++ b/muse2/muse/instruments/editinstrumentbase.ui @@ -7,7 +7,7 @@      <x>0</x>      <y>0</y>      <width>772</width> -    <height>421</height> +    <height>431</height>     </rect>    </property>    <property name="minimumSize"> @@ -289,22 +289,6 @@                  <item>                   <layout class="QHBoxLayout">                    <item> -                   <widget class="QCheckBox" name="checkBoxDrum"> -                    <property name="toolTip"> -                     <string>Drum patch</string> -                    </property> -                    <property name="whatsThis"> -                     <string>If set, the patch is available only for drum channels.</string> -                    </property> -                    <property name="text"> -                     <string>Drum</string> -                    </property> -                    <property name="shortcut"> -                     <string/> -                    </property> -                   </widget> -                  </item> -                  <item>                     <widget class="QCheckBox" name="checkBoxGM">                      <property name="toolTip">                       <string>GM patch</string> @@ -361,6 +345,44 @@                    </item>                   </layout>                  </item> +                <item> +                 <layout class="QHBoxLayout" name="horizontalLayout_9"> +                  <item> +                   <widget class="QLabel" name="label_11"> +                    <property name="text"> +                     <string>Show in tracks:</string> +                    </property> +                   </widget> +                  </item> +                  <item> +                   <widget class="QRadioButton" name="showPatchInMidiButton"> +                    <property name="text"> +                     <string>Midi</string> +                    </property> +                   </widget> +                  </item> +                  <item> +                   <widget class="QRadioButton" name="showPatchInDrumsButton"> +                    <property name="text"> +                     <string>Drum</string> +                    </property> +                   </widget> +                  </item> +                  <item> +                   <spacer name="horizontalSpacer_5"> +                    <property name="orientation"> +                     <enum>Qt::Horizontal</enum> +                    </property> +                    <property name="sizeHint" stdset="0"> +                     <size> +                      <width>40</width> +                      <height>20</height> +                     </size> +                    </property> +                   </spacer> +                  </item> +                 </layout> +                </item>                 </layout>                </widget>               </item> @@ -1799,6 +1821,67 @@ Caution! Watch out for controllers such as           </item>          </layout>         </widget> +       <widget class="QWidget" name="initTab"> +        <attribute name="title"> +         <string>&Initialization</string> +        </attribute> +        <layout class="QVBoxLayout" name="verticalLayout_5"> +         <item> +          <widget class="QLabel" name="label_4"> +           <property name="text"> +            <string>Instrument initialization sequence:</string> +           </property> +          </widget> +         </item> +         <item> +          <widget class="QTreeWidget" name="initEventList"> +           <column> +            <property name="text"> +             <string notr="true">1</string> +            </property> +           </column> +          </widget> +         </item> +         <item> +          <layout class="QHBoxLayout" name="horizontalLayout_8"> +           <item> +            <spacer name="horizontalSpacer_4"> +             <property name="orientation"> +              <enum>Qt::Horizontal</enum> +             </property> +             <property name="sizeHint" stdset="0"> +              <size> +               <width>40</width> +               <height>20</height> +              </size> +             </property> +            </spacer> +           </item> +           <item> +            <widget class="QToolButton" name="initAddButton"> +             <property name="text"> +              <string>&Add...</string> +             </property> +            </widget> +           </item> +           <item> +            <widget class="QToolButton" name="initChangeButton"> +             <property name="text"> +              <string>&Change...</string> +             </property> +            </widget> +           </item> +           <item> +            <widget class="QToolButton" name="initDeleteButton"> +             <property name="text"> +              <string>&Delete</string> +             </property> +            </widget> +           </item> +          </layout> +         </item> +        </layout> +       </widget>        </widget>       </widget>      </item> @@ -1825,7 +1908,7 @@ Caution! Watch out for controllers such as       <x>0</x>       <y>0</y>       <width>772</width> -     <height>23</height> +     <height>21</height>      </rect>     </property>     <property name="defaultUp"> @@ -1959,7 +2042,6 @@ Caution! Watch out for controllers such as    <tabstop>spinBoxHBank</tabstop>    <tabstop>spinBoxLBank</tabstop>    <tabstop>spinBoxProgram</tabstop> -  <tabstop>checkBoxDrum</tabstop>    <tabstop>checkBoxGM</tabstop>    <tabstop>checkBoxGS</tabstop>    <tabstop>checkBoxXG</tabstop> diff --git a/muse2/muse/instruments/minstrument.cpp b/muse2/muse/instruments/minstrument.cpp index ecfc2da4..a85f1c02 100644 --- a/muse2/muse/instruments/minstrument.cpp +++ b/muse2/muse/instruments/minstrument.cpp @@ -457,6 +457,8 @@ MType MidiInstrument::midiType() const  {    if(_name == "GM")      return MT_GM; +  if(_name == "GM2") +    return MT_GM2;    if(_name == "GS")      return MT_GS;    if(_name == "XG") diff --git a/muse2/muse/liste/CMakeLists.txt b/muse2/muse/liste/CMakeLists.txt index c846d665..fce9974b 100644 --- a/muse2/muse/liste/CMakeLists.txt +++ b/muse2/muse/liste/CMakeLists.txt @@ -25,33 +25,13 @@  ## Expand Qt macros in source files  ##  QT4_WRAP_CPP ( liste_mocs -      # listedit.h -      # ctrllistedit.h -      # tracklistedit.h -      # partlistedit.h -      # ieventdialog.h -      editevent.h              listedit.h         )  ## -## UI files -## -file (GLOB liste_ui_files -      editctrlbase.ui -      ) -QT4_WRAP_UI ( liste_uis ${liste_ui_files} ) - -##  ## List of source files to compile  ##  file (GLOB liste_source_files -      # listedit.cpp -      # ctrllistedit.cpp -      # partlistedit.cpp -      # tracklistedit.cpp -      # ieventdialog.cpp -      editevent.cpp        listedit.cpp        ) @@ -61,7 +41,6 @@ file (GLOB liste_source_files  add_library ( liste ${MODULES_BUILD}        ${liste_source_files}        ${liste_mocs} -      ${liste_uis}        )  ## @@ -70,7 +49,6 @@ add_library ( liste ${MODULES_BUILD}  set (FILES_TO_TRANSLATE        ${FILES_TO_TRANSLATE}        ${liste_source_files} -      ${liste_ui_files}        CACHE INTERNAL ""        ) @@ -88,7 +66,6 @@ set_target_properties( liste  target_link_libraries ( liste        ${QT_LIBRARIES}        awl -      widgets        )  ## diff --git a/muse2/muse/liste/listedit.cpp b/muse2/muse/liste/listedit.cpp index 730ab5d8..79f10b4b 100644 --- a/muse2/muse/liste/listedit.cpp +++ b/muse2/muse/liste/listedit.cpp @@ -45,6 +45,7 @@  #include "event.h"  #include "midiport.h"  #include "midictrl.h" +#include "minstrument.h"  #include "app.h"  #include "gconfig.h" @@ -201,7 +202,8 @@ void ListEdit::songChanged(MusECore::SongChangedFlags_t type)        if (type == 0)              return; -      if (type & (SC_PART_REMOVED | SC_PART_MODIFIED +      if (type & (// SC_MIDI_TRACK_PROP  FIXME Needed, but might make it slow! +           SC_PART_REMOVED | SC_PART_MODIFIED            | SC_PART_INSERTED | SC_EVENT_REMOVED | SC_EVENT_MODIFIED           | SC_EVENT_INSERTED | SC_SELECTION)) {              if (type & (SC_PART_REMOVED | SC_PART_INSERTED | SC_PART_MODIFIED)) @@ -285,7 +287,6 @@ void ListEdit::songChanged(MusECore::SongChangedFlags_t type)  QString EventListItem::text(int col) const        {        QString s; -      QString commentLabel;        switch(col) {              case 0:                    s.setNum(event.tick()); @@ -324,30 +325,9 @@ QString EventListItem::text(int col) const                                }                                break;                          case MusECore::Sysex: -                              { -                              commentLabel = QString("len "); -                              QString k; -                              k.setNum(event.dataLen()); -                              commentLabel += k; -                              commentLabel += QString(" "); - -                              commentLabel += MusECore::nameSysex(event.dataLen(), event.data()); -                              int i; -                              for (i = 0; i < 10; ++i) { -                                    if (i >= event.dataLen()) -                                          break; -                                    commentLabel += QString(" 0x"); -                                    QString k; -                                    k.setNum(event.data()[i] & 0xff, 16); -                                    commentLabel += k; -                                    } -                              if (i == 10) -                                    commentLabel += QString("..."); -                              }                                s = QString("SysEx");                                break;                          case MusECore::Meta: -                              commentLabel = midiMetaComment(event);                                s = QString("Meta");                                break;                          case MusECore::Wave: @@ -357,7 +337,14 @@ QString EventListItem::text(int col) const                          }                    break;              case 3: -                  s.setNum(part->track()->outChannel() + 1); +                  switch(event.type()) { +                    case MusECore::Sysex: +                    case MusECore::Meta: +                      break; +                       +                    default: +                       s.setNum(part->track()->outChannel() + 1); +                  }                    break;              case 4:                    if (event.isNote()) @@ -365,7 +352,16 @@ QString EventListItem::text(int col) const                    else if (event.type() == MusECore::Controller)                          s.setNum(event.dataA() & 0xffff);  // mask off type bits                    else -                        s.setNum(event.dataA()); +                  { +                    switch(event.type()) { +                      case MusECore::Sysex: +                      case MusECore::Meta: +                        break; +                         +                    default: +                      s.setNum(event.dataA()); +                    } +                  }                    break;              case 5:                    if(event.type() == MusECore::Controller && @@ -384,13 +380,41 @@ QString EventListItem::text(int col) const                      s.sprintf("%d-%d-%d", hb, lb, pr);                    }                    else         -                    s.setNum(event.dataB()); +                  { +                    switch(event.type()) { +                      case MusECore::Sysex: +                      case MusECore::Meta: +                        break; +                         +                    default: +                      s.setNum(event.dataB()); +                    } +                  }                    break;              case 6: -                  s.setNum(event.dataC()); +                  switch(event.type()) { +                    case MusECore::Sysex: +                    case MusECore::Meta: +                      break; +                       +                    default: +                      s.setNum(event.dataC()); +                  }                    break;              case 7: -                  s.setNum(event.lenTick()); +                  switch(event.type()) { +                        case MusECore::Sysex: +                        case MusECore::Meta: +                          s.setNum(event.dataLen()); +                        break; +                         +                        case MusECore::Controller: +                        break; +                         +                        default: +                          s.setNum(event.lenTick()); +                        break; +                  }                    break;              case 8:                    switch(event.type()) { @@ -402,14 +426,13 @@ QString EventListItem::text(int col) const                                }                                break;                          case MusECore::Sysex: +                        case MusECore::Meta:                                { -                              s = QString("len "); -                              QString k; -                              k.setNum(event.dataLen()); -                              s += k; -                              s += QString(" "); - -                              commentLabel += MusECore::nameSysex(event.dataLen(), event.data()); +                              if(event.type() == MusECore::Sysex) +                                s = MusECore::nameSysex(event.dataLen(), event.data(), +                                      MusEGlobal::midiPorts[part->track()->outPort()].instrument()) + QString(" "); +                              else if(event.type() == MusECore::Meta)   +                                s = midiMetaComment(event) + QString(" ");                                int i;                                for (i = 0; i < 10; ++i) {                                      if (i >= event.dataLen()) @@ -421,11 +444,9 @@ QString EventListItem::text(int col) const                                      }                                if (i == 10)                                      s += QString("..."); +                                                              }                                break; -                        case MusECore::Meta: -                              s = midiMetaComment(event); -                              break;                          default:                                break;                          } @@ -623,7 +644,10 @@ void ListEdit::editInsertSysEx()        if(!curPart)          return; -      MusECore::Event event = EditSysexDialog::getEvent(curPart->tick(), MusECore::Event(), this); +      MusECore::MidiInstrument* minstr = NULL; +      if(curPart->track()) +        minstr = MusEGlobal::midiPorts[curPart->track()->outPort()].instrument(); +      MusECore::Event event = EditSysexDialog::getEvent(curPart->tick(), MusECore::Event(), this, minstr);        if (!event.empty()) {              //No events before beginning of part + take Part offset into consideration              unsigned tick = event.tick(); @@ -699,7 +723,12 @@ void ListEdit::editEvent(MusECore::Event& event, MusECore::MidiPart* part)                    nevent = EditCtrlDialog::getEvent(tick, event, part, this);                    break;              case MusECore::Sysex: -                  nevent = EditSysexDialog::getEvent(tick, event, this); +                  { +                    MusECore::MidiInstrument* minstr = NULL; +                    if(part->track()) +                      minstr = MusEGlobal::midiPorts[part->track()->outPort()].instrument(); +                    nevent = EditSysexDialog::getEvent(tick, event, this, minstr); +                  }                    break;              case MusECore::Meta:                    nevent = EditMetaDialog::getEvent(tick, event, this); diff --git a/muse2/muse/midi.cpp b/muse2/muse/midi.cpp index d70b132c..24876813 100644 --- a/muse2/muse/midi.cpp +++ b/muse2/muse/midi.cpp @@ -33,6 +33,7 @@  #include "midictrl.h"  #include "marker/marker.h"  #include "midiport.h" +#include "minstrument.h"  #include "midictrl.h"  #include "sync.h"  #include "audio.h" @@ -52,11 +53,15 @@ extern void dump(const unsigned char* p, int n);  const unsigned char gmOnMsg[]   = { 0x7e, 0x7f, 0x09, 0x01 }; +const unsigned char gm2OnMsg[]  = { 0x7e, 0x7f, 0x09, 0x03 }; +const unsigned char gmOffMsg[]  = { 0x7e, 0x7f, 0x09, 0x02 };  const unsigned char gsOnMsg[]   = { 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7f, 0x00, 0x41 };  const unsigned char gsOnMsg2[]  = { 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x33, 0x50, 0x3c };  const unsigned char gsOnMsg3[]  = { 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x34, 0x50, 0x3b };  const unsigned char xgOnMsg[]   = { 0x43, 0x10, 0x4c, 0x00, 0x00, 0x7e, 0x00 };  const unsigned int  gmOnMsgLen  = sizeof(gmOnMsg); +const unsigned int  gm2OnMsgLen = sizeof(gm2OnMsg); +const unsigned int  gmOffMsgLen = sizeof(gmOffMsg);  const unsigned int  gsOnMsgLen  = sizeof(gsOnMsg);  const unsigned int  gsOnMsg2Len = sizeof(gsOnMsg2);  const unsigned int  gsOnMsg3Len = sizeof(gsOnMsg3); @@ -115,11 +120,12 @@ QString midiMetaName(int meta)  //   QString nameSysex  //--------------------------------------------------------- -QString nameSysex(unsigned int len, const unsigned char* buf) +QString nameSysex(unsigned int len, const unsigned char* buf, MidiInstrument* instr)        {        QString s;        if(len == 0)          return s; +              switch(buf[0]) {              case 0x00:                    if(len < 3) @@ -127,12 +133,12 @@ QString nameSysex(unsigned int len, const unsigned char* buf)                    if (buf[1] == 0 && buf[2] == 0x41)                          s = "Microsoft";                    break; -            case 0x01:  s = "Sequential Circuits: "; break; -            case 0x02:  s = "Big Briar: "; break; -            case 0x03:  s = "Octave / Plateau: "; break; -            case 0x04:  s = "Moog: "; break; -            case 0x05:  s = "Passport Designs: "; break; -            case 0x06:  s = "Lexicon: "; break; +            case 0x01:  s = "Sequential Circuits"; break; +            case 0x02:  s = "Big Briar"; break; +            case 0x03:  s = "Octave / Plateau"; break; +            case 0x04:  s = "Moog"; break; +            case 0x05:  s = "Passport Designs"; break; +            case 0x06:  s = "Lexicon"; break;              case 0x07:  s = "Kurzweil"; break;              case 0x08:  s = "Fender"; break;              case 0x09:  s = "Gulbransen"; break; @@ -142,18 +148,18 @@ QString nameSysex(unsigned int len, const unsigned char* buf)              case 0x0d:  s = "Techmar"; break;              case 0x0e:  s = "Matthews Research"; break;              case 0x10:  s = "Oberheim"; break; -            case 0x11:  s = "PAIA: "; break; -            case 0x12:  s = "Simmons: "; break; +            case 0x11:  s = "PAIA"; break; +            case 0x12:  s = "Simmons"; break;              case 0x13:  s = "DigiDesign"; break; -            case 0x14:  s = "Fairlight: "; break; +            case 0x14:  s = "Fairlight"; break;              case 0x15:  s = "JL Cooper"; break;              case 0x16:  s = "Lowery"; break;              case 0x17:  s = "Lin"; break;              case 0x18:  s = "Emu"; break;              case 0x1b:  s = "Peavy"; break; -            case 0x20:  s = "Bon Tempi: "; break; -            case 0x21:  s = "S.I.E.L: "; break; -            case 0x23:  s = "SyntheAxe: "; break; +            case 0x20:  s = "Bon Tempi"; break; +            case 0x21:  s = "S.I.E.L"; break; +            case 0x23:  s = "SyntheAxe"; break;              case 0x24:  s = "Hohner"; break;              case 0x25:  s = "Crumar"; break;              case 0x26:  s = "Solton"; break; @@ -163,28 +169,77 @@ QString nameSysex(unsigned int len, const unsigned char* buf)              case 0x2f:  s = "Elka"; break;              case 0x36:  s = "Cheetah"; break;              case 0x3e:  s = "Waldorf"; break; -            case 0x40:  s = "Kawai: "; break; -            case 0x41:  s = "Roland: "; break; -            case 0x42:  s = "Korg: "; break; -            case 0x43:  s = "Yamaha: "; break; +            case 0x40:  s = "Kawai"; break; +            case 0x41:  s = "Roland"; break; +            case 0x42:  s = "Korg"; break; +            case 0x43:  s = "Yamaha"; break;              case 0x44:  s = "Casio"; break;              case 0x45:  s = "Akai"; break;              case MUSE_SYNTH_SYSEX_MFG_ID:  s = "MusE Soft Synth"; break;                   case 0x7d:  s = "Educational Use"; break;              case 0x7e:  s = "Universal: Non Real Time"; break;              case 0x7f:  s = "Universal: Real Time"; break; -            default:    s = "??: "; break; +            default:    s = "??"; break;              } + +      if(instr) +      { +        // Check for user-defined sysex in instrument... +        foreach(const MusECore::SysEx* sx, instr->sysex())  +        { +          if(len == sx->dataLen && memcmp(buf, sx->data, len) == 0) +            return s + QString(": ") + sx->name; +        } +      } +              //        // following messages should not show up in event list        // they are filtered while importing midi files        //        if ((len == gmOnMsgLen) && memcmp(buf, gmOnMsg, gmOnMsgLen) == 0) -            s += "GM-ON"; +            s += ": GM-ON"; +      else if ((len == gm2OnMsgLen) && memcmp(buf, gm2OnMsg, gm2OnMsgLen) == 0) +            s += ": GM2-ON"; +      else if ((len == gmOffMsgLen) && memcmp(buf, gmOffMsg, gmOffMsgLen) == 0) +            s += ": GM-OFF"; +      else if ((len == gsOnMsgLen) && memcmp(buf, gsOnMsg, gsOnMsgLen) == 0) +            s += ": GS-ON"; +      else if ((len == xgOnMsgLen) && memcmp(buf, xgOnMsg, xgOnMsgLen) == 0) +            s += ": XG-ON"; +      return s; +      } + +//--------------------------------------------------------- +//   QString sysexComment +//--------------------------------------------------------- + +QString sysexComment(unsigned int len, const unsigned char* buf, MidiInstrument* instr) +      { +      QString s; +      if(len == 0) +        return s; +       +      if(instr) +      { +        // Check for user-defined sysex in instrument... +        foreach(const MusECore::SysEx* sx, instr->sysex())  +        { +          if(len == sx->dataLen && memcmp(buf, sx->data, len) == 0) +            return sx->comment; +        } +      } +       +      // These are the common ones we know about so far... +      if ((len == gmOnMsgLen) && memcmp(buf, gmOnMsg, gmOnMsgLen) == 0) +            s = QObject::tr("Switch on General Midi Level 1 mode"); +      else if ((len == gm2OnMsgLen) && memcmp(buf, gm2OnMsg, gm2OnMsgLen) == 0) +            s = QObject::tr("Switch on General Midi Level 2 mode"); +      else if ((len == gmOffMsgLen) && memcmp(buf, gmOffMsg, gmOffMsgLen) == 0) +            s = QObject::tr("Switch off General Midi Level 1 or 2");        else if ((len == gsOnMsgLen) && memcmp(buf, gsOnMsg, gsOnMsgLen) == 0) -            s += "GS-ON"; +            s = QObject::tr("Switch on Roland GS mode");        else if ((len == xgOnMsgLen) && memcmp(buf, xgOnMsg, xgOnMsgLen) == 0) -            s += "XG-ON"; +            s = QObject::tr("Switch on Yamaha XG mode");        return s;        } diff --git a/muse2/muse/midi.h b/muse2/muse/midi.h index c0f6e07f..41d9812a 100644 --- a/muse2/muse/midi.h +++ b/muse2/muse/midi.h @@ -97,6 +97,8 @@ enum AudioTickSound {  };  extern const unsigned char gmOnMsg[]; +extern const unsigned char gm2OnMsg[]; +extern const unsigned char gmOffMsg[];  extern const unsigned char gsOnMsg[];  extern const unsigned char gsOnMsg2[]; @@ -107,6 +109,8 @@ extern const unsigned char mmcStopMsg[];  extern const unsigned char mmcLocateMsg[];  extern const unsigned int gmOnMsgLen; +extern const unsigned int gm2OnMsgLen; +extern const unsigned int gmOffMsgLen;  extern const unsigned int gsOnMsgLen;  extern const unsigned int gsOnMsg2Len;  extern const unsigned int gsOnMsg3Len; @@ -115,7 +119,9 @@ extern const unsigned int mmcDeferredPlayMsgLen;  extern const unsigned int mmcStopMsgLen;  extern const unsigned int mmcLocateMsgLen; -QString nameSysex(unsigned int len, const unsigned char* buf); +class MidiInstrument; +QString nameSysex(unsigned int len, const unsigned char* buf, MidiInstrument* instr = 0); +QString sysexComment(unsigned int len, const unsigned char* buf, MidiInstrument* instr = 0);  QString midiMetaName(int);  // Use these in all the synths and their guis. diff --git a/muse2/muse/midiedit/drumedit.cpp b/muse2/muse/midiedit/drumedit.cpp index b45c8be4..2f0ba12c 100644 --- a/muse2/muse/midiedit/drumedit.cpp +++ b/muse2/muse/midiedit/drumedit.cpp @@ -43,6 +43,7 @@  #include <QPoint>  #include <QRect> +#include "globaldefs.h"  #include "drumedit.h"  #include "dcanvas.h"  #include "mtscale.h" @@ -69,7 +70,6 @@  #include "popupmenu.h"  #include "menutitleitem.h"  #include "widgets/function_dialogs/quantize.h" -#include "editinstrument.h"  namespace MusEGui { @@ -1350,7 +1350,7 @@ void DrumEdit::ctrlPopupTriggered(QAction* act)          }    else if (rv == edit_ins) {             // edit instrument          MusECore::MidiInstrument* instr = port->instrument(); -        MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrument::Controllers); +        MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrumentControllers);          }    else {                           // Select a control          if(cll->find(channel, rv) == cll->end()) diff --git a/muse2/muse/midiedit/pianoroll.cpp b/muse2/muse/midiedit/pianoroll.cpp index 7f281712..539818f8 100644 --- a/muse2/muse/midiedit/pianoroll.cpp +++ b/muse2/muse/midiedit/pianoroll.cpp @@ -49,6 +49,7 @@  #include <stdio.h> +#include "globaldefs.h"  #include "xml.h"  #include "mtscale.h"  #include "prcanvas.h" @@ -69,8 +70,6 @@  #include "helper.h"  #include "popupmenu.h"  #include "menutitleitem.h" -#include "editinstrument.h" -  #include "cmd.h"  #include "shortcuts.h" @@ -868,7 +867,7 @@ void PianoRoll::ctrlPopupTriggered(QAction* act)          }    else if (rv == edit_ins) {             // edit instrument          MusECore::MidiInstrument* instr = port->instrument(); -        MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrument::Controllers); +        MusEGlobal::muse->startEditInstrument(instr ? instr->iname() : QString(), EditInstrumentControllers);          }    else {                           // Select a control          if(cll->find(channel, rv) == cll->end()) diff --git a/muse2/muse/midifile.cpp b/muse2/muse/midifile.cpp index 39b2e51d..424edd72 100644 --- a/muse2/muse/midifile.cpp +++ b/muse2/muse/midifile.cpp @@ -419,6 +419,10 @@ int MidiFile::readEvent(MidiPlayEvent* event, MidiFileTrack* t)                          lastMtype = MT_GM;                          return -1;                          } +                  if (((unsigned)len == gm2OnMsgLen) && memcmp(buffer, gm2OnMsg, gm2OnMsgLen) == 0) { +                        lastMtype = MT_GM2; +                        return -1; +                        }                    if (((unsigned)len == gsOnMsgLen) && memcmp(buffer, gsOnMsg, gsOnMsgLen) == 0) {                          lastMtype = MT_GS;                          return -1; diff --git a/muse2/muse/widgets/CMakeLists.txt b/muse2/muse/widgets/CMakeLists.txt index a4db13af..9ca9bcd7 100644 --- a/muse2/muse/widgets/CMakeLists.txt +++ b/muse2/muse/widgets/CMakeLists.txt @@ -37,6 +37,7 @@ QT4_WRAP_CPP (widget_mocs        bigtime.h          canvas.h          checkbox.h +      choose_sysex.h        colorframe.h        comboQuant.h          combobox.h   @@ -48,6 +49,7 @@ QT4_WRAP_CPP (widget_mocs        didyouknow.h        doublelabel.h          doublespinbox.h   +      editevent.h              filedialog.h          genset.h          mdisettings.h   @@ -117,11 +119,13 @@ file (GLOB widgets_ui_files        aboutbox.ui          arrangercolumnsbase.ui         appearancebase.ui  +      choose_sysex_base.ui        cliplisteditorbase.ui          commentbase.ui          configmidifilebase.ui        copy_on_write_base.ui        didyouknow.ui   +      editctrlbase.ui          editnotedialogbase.ui          editsysexdialogbase.ui          fdialogbuttons.ui   @@ -158,6 +162,7 @@ file (GLOB widgets_source_files        bigtime.cpp         canvas.cpp         checkbox.cpp  +      choose_sysex.cpp        citem.cpp        colorframe.cpp        comboQuant.cpp  @@ -171,6 +176,7 @@ file (GLOB widgets_source_files        doublelabel.cpp         doublespinbox.cpp        drange.cpp +      editevent.cpp        filedialog.cpp         genset.cpp         mdisettings.cpp  @@ -272,7 +278,6 @@ set_target_properties( widgets  target_link_libraries ( widgets        ${QT_LIBRARIES}        icons -      instruments        )  ## diff --git a/muse2/muse/liste/editctrlbase.ui b/muse2/muse/widgets/editctrlbase.ui index c63e1c22..c63e1c22 100644 --- a/muse2/muse/liste/editctrlbase.ui +++ b/muse2/muse/widgets/editctrlbase.ui diff --git a/muse2/muse/liste/editevent.cpp b/muse2/muse/widgets/editevent.cpp index 14bd0d8a..873c60f6 100644 --- a/muse2/muse/liste/editevent.cpp +++ b/muse2/muse/widgets/editevent.cpp @@ -51,6 +51,7 @@  #include "instruments/minstrument.h"  #include "midi.h"  #include "popupmenu.h" +#include "choose_sysex.h"  namespace MusEGui { @@ -77,7 +78,7 @@ QString string2hex(const unsigned char* data, int len)  //   hex2string  //--------------------------------------------------------- -char* hex2string(QWidget* parent, const char* src, int& len) +char* hex2string(QWidget* parent, const char* src, int& len, bool warn = true)        {        char buffer[2048];        char* dst = buffer; @@ -88,17 +89,19 @@ char* hex2string(QWidget* parent, const char* src, int& len)              char* ep;              long val =  strtol(src, &ep, 16);              if (ep == src) { -                  QMessageBox::information(parent, -                     QString("MusE"), -                     QWidget::tr("Cannot convert sysex string")); +                  if(warn) +                    QMessageBox::information(parent, +                      QString("MusE"), +                      QWidget::tr("Cannot convert sysex string"));                    return 0;                    }              src    = ep;              *dst++ = val;              if (dst - buffer >= 2048) { -                  QMessageBox::information(parent, -                     QString("MusE"), -                     QWidget::tr("Hex String too long (2048 bytes limit)")); +                  if(warn) +                    QMessageBox::information(parent, +                      QString("MusE"), +                      QWidget::tr("Hex String too long (2048 bytes limit)"));                    return 0;                    }              } @@ -126,9 +129,9 @@ MusECore::Event EditNoteDialog::getEvent(int tick, const MusECore::Event& event,        return nevent;        } -MusECore::Event EditSysexDialog::getEvent(int tick, const MusECore::Event& event, QWidget* parent) +MusECore::Event EditSysexDialog::getEvent(int tick, const MusECore::Event& event, QWidget* parent, MusECore::MidiInstrument* instr)        { -      EditSysexDialog* dlg = new EditSysexDialog(tick, event, parent); +      EditSysexDialog* dlg = new EditSysexDialog(tick, event, parent, instr);        MusECore::Event nevent;        if (dlg->exec() == QDialog::Accepted) {              nevent = dlg->event(); @@ -224,18 +227,26 @@ MusECore::Event EditNoteDialog::event()  //---------------------------------------------------------  EditSysexDialog::EditSysexDialog(int tick, const MusECore::Event& event, -   QWidget* parent) +   QWidget* parent, MusECore::MidiInstrument* instr)     : QDialog(parent)        {        setupUi(this);        sysex = 0; +      _instr = instr;        if (!event.empty()) {              epos->setValue(tick);              edit->setText(string2hex(event.data(), event.dataLen())); +            if(_instr) +            { +              typeLabel->setText(MusECore::nameSysex(event.dataLen(), event.data(), _instr));               +              commentLabel->setText(MusECore::sysexComment(event.dataLen(), event.data(), _instr));               +            }              }        else {              epos->setValue(tick);              } +      connect(edit, SIGNAL(textChanged()), SLOT(editChanged()));       +      connect(buttonSelect, SIGNAL(clicked(bool)), SLOT(selectSysex()));              }  //--------------------------------------------------------- @@ -276,6 +287,53 @@ void EditSysexDialog::accept()        }  //--------------------------------------------------------- +//   editChanged +//--------------------------------------------------------- + +void EditSysexDialog::editChanged() +{ +  if(!_instr) +    return; +   +  QString qsrc = edit->toPlainText(); +  QByteArray ba = qsrc.toLatin1(); +  const char* src = ba.constData(); + +  int l; +  unsigned char* data = (unsigned char*)hex2string(this, src, l, false); // false = Don't warn with popups +  if(data && l > 0) +  { +    typeLabel->setText(MusECore::nameSysex(l, data, _instr)); +    commentLabel->setText(MusECore::sysexComment(l, data, _instr));               +  } +  else +  { +   typeLabel->clear(); +   commentLabel->clear(); +  } +} +       +//--------------------------------------------------------- +//   selectSysex +//--------------------------------------------------------- + +void EditSysexDialog::selectSysex() +{ +  ChooseSysexDialog* dlg = new ChooseSysexDialog(this, _instr); +  if(dlg->exec() == QDialog::Accepted)  +  { +    MusECore::SysEx* s = dlg->sysex(); +    if(s) +    { +      edit->setText(string2hex(s->data, s->dataLen)); +      typeLabel->setText(s->name); +      commentLabel->setText(s->comment);               +    } +  } +  delete dlg; +} + +//---------------------------------------------------------  //   EditMetaDialog  //--------------------------------------------------------- diff --git a/muse2/muse/liste/editevent.h b/muse2/muse/widgets/editevent.h index 0674fe30..9a5732ce 100644 --- a/muse2/muse/liste/editevent.h +++ b/muse2/muse/widgets/editevent.h @@ -26,7 +26,6 @@  #include "ui_editnotedialogbase.h"  #include "ui_editsysexdialogbase.h"  #include "ui_editctrlbase.h" -#include "event.h"  class QDialog;  class QLabel; @@ -41,7 +40,9 @@ namespace Awl {        };  namespace MusECore { +class Event;  class MidiPart; +class MidiInstrument;  }  namespace MusEGui { @@ -49,7 +50,6 @@ namespace MusEGui {  class IntLabel;  class PitchEdit; -  //---------------------------------------------------------  //   EditEventDialog  //--------------------------------------------------------- @@ -87,6 +87,7 @@ class EditNoteDialog : public QDialog, public Ui::EditNoteDialogBase {  class EditSysexDialog : public QDialog, public Ui::EditSysexDialogBase {        Q_OBJECT +      MusECore::MidiInstrument* _instr;        unsigned char* sysex;        int len; @@ -95,13 +96,15 @@ class EditSysexDialog : public QDialog, public Ui::EditSysexDialogBase {     private slots:        virtual void accept(); +      virtual void editChanged(); +      virtual void selectSysex();     public:        EditSysexDialog(int tick, const MusECore::Event&, -         QWidget* parent=0); +         QWidget* parent=0, MusECore::MidiInstrument* instr = 0);        ~EditSysexDialog();        static MusECore::Event getEvent(int tick, const MusECore::Event&, -         QWidget* parent = 0); +         QWidget* parent = 0, MusECore::MidiInstrument* instr = 0);        virtual MusECore::Event event();        }; diff --git a/muse2/muse/widgets/editsysexdialogbase.ui b/muse2/muse/widgets/editsysexdialogbase.ui index adf5b186..7c7a3491 100644 --- a/muse2/muse/widgets/editsysexdialogbase.ui +++ b/muse2/muse/widgets/editsysexdialogbase.ui @@ -42,7 +42,7 @@        </widget>       </item>       <item> -      <widget class="Awl::PosEdit" name="epos"/> +      <widget class="Awl::PosEdit" name="epos" native="true"/>       </item>       <item>        <spacer name="Spacer2"> @@ -82,6 +82,26 @@     <item>      <widget class="QLabel" name="TextLabel2">       <property name="text"> +      <string>Name:</string> +     </property> +     <property name="wordWrap"> +      <bool>false</bool> +     </property> +    </widget> +   </item> +   <item> +    <widget class="QLabel" name="typeLabel"> +     <property name="frameShape"> +      <enum>QFrame::Panel</enum> +     </property> +     <property name="frameShadow"> +      <enum>QFrame::Sunken</enum> +     </property> +    </widget> +   </item> +   <item> +    <widget class="QLabel" name="TextLabel3"> +     <property name="text">        <string>Comment:</string>       </property>       <property name="wordWrap"> @@ -90,7 +110,14 @@      </widget>     </item>     <item> -    <widget class="QTextEdit" name="comment"/> +    <widget class="QLabel" name="commentLabel"> +     <property name="frameShape"> +      <enum>QFrame::Panel</enum> +     </property> +     <property name="frameShadow"> +      <enum>QFrame::Sunken</enum> +     </property> +    </widget>     </item>     <item>      <layout class="QHBoxLayout"> @@ -117,9 +144,16 @@        </spacer>       </item>       <item> +      <widget class="QPushButton" name="buttonSelect"> +       <property name="text"> +        <string>&Select...</string> +       </property> +      </widget> +     </item> +     <item>        <widget class="QPushButton" name="buttonOk">         <property name="text"> -        <string>OK</string> +        <string>&OK</string>         </property>         <property name="shortcut">          <number>0</number> @@ -135,7 +169,7 @@       <item>        <widget class="QPushButton" name="buttonCancel">         <property name="text"> -        <string>Cancel</string> +        <string>&Cancel</string>         </property>         <property name="shortcut">          <number>0</number> @@ -155,7 +189,6 @@     <class>Awl::PosEdit</class>     <extends>QWidget</extends>     <header>awl/posedit.h</header> -   <container>0</container>    </customwidget>   </customwidgets>   <resources/>  | 
