diff options
| author | Tim E. Real <termtech@rogers.com> | 2010-12-11 08:46:41 +0000 | 
|---|---|---|
| committer | Tim E. Real <termtech@rogers.com> | 2010-12-11 08:46:41 +0000 | 
| commit | aae64c142b4492c4613f483e0d961897deb06233 (patch) | |
| tree | f233de4f13a5002455182ab358d5b8604b7607b8 /muse2/muse | |
| parent | 0939a78104241b6a3d2a97d6f1dfda4614cc7e49 (diff) | |
Feature: Added default midi track in/out channels to midi ports list. See ChangeLog.
Diffstat (limited to 'muse2/muse')
| -rw-r--r-- | muse2/muse/arranger/trackinfo.cpp | 11 | ||||
| -rw-r--r-- | muse2/muse/conf.cpp | 69 | ||||
| -rw-r--r-- | muse2/muse/confmport.cpp | 53 | ||||
| -rw-r--r-- | muse2/muse/midiport.cpp | 5 | ||||
| -rw-r--r-- | muse2/muse/midiport.h | 7 | ||||
| -rw-r--r-- | muse2/muse/song.cpp | 61 | ||||
| -rw-r--r-- | muse2/muse/sync.cpp | 16 | ||||
| -rw-r--r-- | muse2/muse/sync.h | 1 | ||||
| -rw-r--r-- | muse2/muse/widgets/mtrackinfobase.ui | 12 | 
9 files changed, 199 insertions, 36 deletions
| diff --git a/muse2/muse/arranger/trackinfo.cpp b/muse2/muse/arranger/trackinfo.cpp index 13197f50..20673b25 100644 --- a/muse2/muse/arranger/trackinfo.cpp +++ b/muse2/muse/arranger/trackinfo.cpp @@ -1192,10 +1192,12 @@ void Arranger::genMidiTrackInfo()        //midiTrackInfo->iChanDetectLabel->setPixmap(*darkgreendotIcon);        midiTrackInfo->iChanDetectLabel->setPixmap(*darkRedLedIcon); -      QIcon recEchoIconSet; -      recEchoIconSet.addPixmap(*recEchoIconOn, QIcon::Normal, QIcon::On); -      recEchoIconSet.addPixmap(*recEchoIconOff, QIcon::Normal, QIcon::Off); -      midiTrackInfo->recEchoButton->setIcon(recEchoIconSet); +      //QIcon recEchoIconSet; +      //recEchoIconSet.addPixmap(*recEchoIconOn, QIcon::Normal, QIcon::On); +      //recEchoIconSet.addPixmap(*recEchoIconOff, QIcon::Normal, QIcon::Off); +      //midiTrackInfo->recEchoButton->setIcon(recEchoIconSet); +      midiTrackInfo->recEchoButton->setIcon(QIcon(*edit_midiIcon)); +      midiTrackInfo->recEchoButton->setIconSize(edit_midiIcon->size());          // MusE-2: AlignCenter and WordBreak are set in the ui(3) file, but not supported by QLabel. Turn them on here. @@ -1258,6 +1260,7 @@ void Arranger::genMidiTrackInfo()        // TODO: Works OK, but disabled for now, until we figure out what to do about multiple out routes and display values...        midiTrackInfo->oRButton->setEnabled(false); +      midiTrackInfo->oRButton->setVisible(false);        connect(midiTrackInfo->oRButton, SIGNAL(pressed()), SLOT(outRoutesPressed()));        connect(heartBeatTimer, SIGNAL(timeout()), SLOT(midiTrackInfoHeartBeat())); diff --git a/muse2/muse/conf.cpp b/muse2/muse/conf.cpp index 9ab9e594..315ce9cd 100644 --- a/muse2/muse/conf.cpp +++ b/muse2/muse/conf.cpp @@ -200,9 +200,20 @@ static void readConfigMidiPort(Xml& xml)        {        int idx = 0;        QString device; -      QString instrument; +       +      //QString instrument; +      // Changed by Tim.  +      //QString instrument("generic midi");  +      // Let's be bold. New users have been confused by generic midi not enabling any patches and controllers. +      // I had said this may cause HW problems by sending out GM sysEx when really the HW might not be GM. +      // But this really needs to be done, one way or another.  +      // FIXME: TODO: Make this user-configurable! +      QString instrument("GM");  +              int openFlags = 1;        bool thruFlag = false; +      int dic = 0; +      int doc = 0;        MidiSyncInfo tmpSi;        int type = MidiDevice::ALSA_MIDI; @@ -224,13 +235,18 @@ static void readConfigMidiPort(Xml& xml)                                }                          else if (tag == "openFlags")                                openFlags = xml.parseInt(); +                        else if (tag == "defaultInChans") +                              dic = xml.parseInt();  +                        else if (tag == "defaultOutChans") +                              doc = xml.parseInt();                           else if (tag == "midiSyncInfo")                                tmpSi.read(xml);                          else if (tag == "instrument") {                                instrument = xml.parse1(); -                              midiPorts[idx].setInstrument( -                                 registerMidiInstrument(instrument) -                                 ); +                              // Moved by Tim. +                              //midiPorts[idx].setInstrument( +                              //   registerMidiInstrument(instrument) +                              //   );                                }                          else if (tag == "midithru")                                thruFlag = xml.parseInt(); // obsolete @@ -271,6 +287,11 @@ static void readConfigMidiPort(Xml& xml)                                  fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.toLatin1().constData());                                MidiPort* mp = &midiPorts[idx]; +                               +                              mp->setInstrument(registerMidiInstrument(instrument));  // By Tim. +                              mp->setDefaultInChannels(dic); +                              mp->setDefaultOutChannels(doc); +                                                              mp->syncInfo().copyParams(tmpSi);                                // p3.3.50 Indicate the port was found in the song file, even if no device is assigned to it.                                mp->setFoundInSongFile(true); @@ -946,20 +967,42 @@ static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo)              //              for (int i = 0; i < MIDI_PORTS; ++i) {                    bool used = false; -                  MidiTrackList* tl = song->midis(); -                  for (iMidiTrack it = tl->begin(); it != tl->end(); ++it) { -                        MidiTrack* t = *it; -                        if (t->outPort() == i) { -                              used = true; -                              break; -                              } -                        }                    MidiPort* mport = &midiPorts[i]; +                  // Route check by Tim. Port can now be used for routing even if no device. +                  // Also, check for other non-defaults and save port, to preserve settings even if no device. +                  if(!mport->noInRoute() || !mport->noOutRoute() ||  +                     mport->defaultInChannels() || mport->defaultOutChannels() || +                     (!mport->instrument()->iname().isEmpty() && mport->instrument()->iname() != "GM") || +                     !mport->syncInfo().isDefault())  +                    used = true;   +                  else   +                  { +                    MidiTrackList* tl = song->midis(); +                    for (iMidiTrack it = tl->begin(); it != tl->end(); ++it)  +                    { +                      MidiTrack* t = *it; +                      if (t->outPort() == i)  +                      { +                        used = true; +                        break; +                      } +                    } +                  }   +                                      MidiDevice* dev = mport->device();                    if (!used && !dev)                          continue;                    xml.tag(level++, "midiport idx=\"%d\"", i); -                  xml.strTag(level, "instrument", mport->instrument()->iname()); +                   +                  if(mport->defaultInChannels()) +                    xml.intTag(level, "defaultInChans", mport->defaultInChannels()); +                  if(mport->defaultOutChannels()) +                    xml.intTag(level, "defaultOutChans", mport->defaultOutChannels()); +                   +                  if(!mport->instrument()->iname().isEmpty() &&                      // Tim. +                     (mport->instrument()->iname() != "GM"))                         // FIXME: TODO: Make this user configurable. +                    xml.strTag(level, "instrument", mport->instrument()->iname()); +                                        if (dev) {                          xml.strTag(level, "name",   dev->name()); diff --git a/muse2/muse/confmport.cpp b/muse2/muse/confmport.cpp index 203e0a63..30318f03 100644 --- a/muse2/muse/confmport.cpp +++ b/muse2/muse/confmport.cpp @@ -36,13 +36,15 @@  #include "driver/jackmidi.h"  #include "audiodev.h"  #include "menutitleitem.h" +#include "utils.h"  extern std::vector<Synth*> synthis;  enum { DEVCOL_NO = 0, DEVCOL_GUI, DEVCOL_REC, DEVCOL_PLAY, DEVCOL_INSTR, DEVCOL_NAME,         //DEVCOL_STATE };         //DEVCOL_ROUTES, DEVCOL_STATE }; -       DEVCOL_INROUTES, DEVCOL_OUTROUTES, DEVCOL_STATE };  // p3.3.55 +       //DEVCOL_INROUTES, DEVCOL_OUTROUTES, DEVCOL_STATE };  // p3.3.55 +       DEVCOL_INROUTES, DEVCOL_OUTROUTES, DEVCOL_DEF_IN_CHANS, DEVCOL_DEF_OUT_CHANS, DEVCOL_STATE };    //---------------------------------------------------------  //   mdevViewItemRenamed @@ -57,6 +59,26 @@ void MPConfig::mdevViewItemRenamed(QTableWidgetItem* item)      return;    switch(col)    { +    case DEVCOL_DEF_IN_CHANS: +    { +      QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text(); +      int no = atoi(id.toLatin1().constData()) - 1; +      if(no < 0 || no >= MIDI_PORTS) +        return; +      midiPorts[no].setDefaultInChannels(string2bitmap(s)); +      song->update(); +    } +    break;     +    case DEVCOL_DEF_OUT_CHANS: +    { +      QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text(); +      int no = atoi(id.toLatin1().constData()) - 1; +      if(no < 0 || no >= MIDI_PORTS) +        return; +      midiPorts[no].setDefaultOutChannels(string2bitmap(s)); +      song->update(); +    } +    break;          case DEVCOL_NAME:      {        QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text(); @@ -358,6 +380,13 @@ void MPConfig::rbClicked(QTableWidgetItem* item)                    //break;                    return; +            case DEVCOL_DEF_IN_CHANS: +            case DEVCOL_DEF_OUT_CHANS: +                  { +                  } +                  //break; +                  return; +                                case DEVCOL_NAME:                    {                      //printf("MPConfig::rbClicked DEVCOL_NAME\n"); @@ -623,6 +652,8 @@ void MPConfig::setToolTip(QTableWidgetItem *item, int col)              //case DEVCOL_ROUTES: item->setToolTip(tr("Jack midi ports")); break;              case DEVCOL_INROUTES:  item->setToolTip(tr("Connections from Jack Midi outputs")); break;              case DEVCOL_OUTROUTES: item->setToolTip(tr("Connections to Jack Midi inputs")); break; +            case DEVCOL_DEF_IN_CHANS:   item->setToolTip(tr("Connect these to new midi tracks")); break; +            case DEVCOL_DEF_OUT_CHANS:  item->setToolTip(tr("Connect new midi tracks to this (first listed only)")); break;              case DEVCOL_STATE:  item->setToolTip(tr("Device state")); break;              default: return;              } @@ -654,6 +685,18 @@ void MPConfig::setWhatsThis(QTableWidgetItem *item, int col)                    item->setWhatsThis(tr("Connections from Jack Midi output ports")); break;              case DEVCOL_OUTROUTES:                    item->setWhatsThis(tr("Connections to Jack Midi input ports")); break; +            case DEVCOL_DEF_IN_CHANS: +                  item->setWhatsThis(tr("Connect these channels, on this port, to new midi tracks.\n" +                                        "Example:\n" +                                        " 1 2 3    channel 1 2 and 3\n" +                                        " 1-3      same\n" +                                        " 1-3 5    channel 1 2 3 and 5\n" +                                        " all      all channels\n" +                                        " none     no channels")); break; +            case DEVCOL_DEF_OUT_CHANS: +                  item->setWhatsThis(tr("Connect new midi tracks to these channels, on this port.\n" +                                        "See default in channels.\n" +                                        "NOTE: Currently only one output port and channel supported (first found)")); break;              case DEVCOL_STATE:                    item->setWhatsThis(tr("State: result of opening the device")); break;              default: @@ -700,6 +743,8 @@ MPConfig::MPConfig(QWidget* parent)  		  << tr("Device Name")  		  << tr("In routes")  		  << tr("Out routes") +                  << tr("Def in ch") +                  << tr("Def out ch")  		  << tr("State");        mdevView->setColumnCount(columnnames.size()); @@ -804,6 +849,12 @@ void MPConfig::songChanged(int flags)  	    QTableWidgetItem* itemin = new QTableWidgetItem;  	    addItem(i, DEVCOL_INROUTES, itemin, mdevView);  	    itemin->setFlags(Qt::ItemIsEnabled); +            QTableWidgetItem* itemdefin = new QTableWidgetItem(bitmap2String(port->defaultInChannels())); +            addItem(i, DEVCOL_DEF_IN_CHANS, itemdefin, mdevView); +            itemdefin->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled); +            QTableWidgetItem* itemdefout = new QTableWidgetItem(bitmap2String(port->defaultOutChannels())); +            addItem(i, DEVCOL_DEF_OUT_CHANS, itemdefout, mdevView); +            itemdefout->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled);  	    mdevView->blockSignals(false); diff --git a/muse2/muse/midiport.cpp b/muse2/muse/midiport.cpp index c6601591..0df08a59 100644 --- a/muse2/muse/midiport.cpp +++ b/muse2/muse/midiport.cpp @@ -37,7 +37,8 @@ void initMidiPorts()        {        for (int i = 0; i < MIDI_PORTS; ++i) {              MidiPort* port = &midiPorts[i]; -            port->setInstrument(genericMidiInstrument); +            ///port->setInstrument(genericMidiInstrument); +            port->setInstrument(registerMidiInstrument("GM")); // Changed by Tim.               port->syncInfo().setPort(i);              }        } @@ -49,6 +50,8 @@ void initMidiPorts()  MidiPort::MidiPort()     : _state("not configured")        { +      _defaultInChannels  = 0; +      _defaultOutChannels = 0;        _device     = 0;        _instrument = 0;        _controller = new MidiCtrlValListList(); diff --git a/muse2/muse/midiport.h b/muse2/muse/midiport.h index 5ba08d67..7ee83cc9 100644 --- a/muse2/muse/midiport.h +++ b/muse2/muse/midiport.h @@ -36,6 +36,9 @@ class MidiPort {        MidiSyncInfo _syncInfo;        // p3.3.50 Just a flag to say the port was found in the song file, even if it has no device right now.        bool _foundInSongFile; +      // When creating a new midi track, add these global default channel routes to/from this port. Ignored if 0. +      int _defaultInChannels;    // These are bit-wise channel masks. +      int _defaultOutChannels;   //        RouteList _inRoutes, _outRoutes; @@ -84,6 +87,10 @@ class MidiPort {        int nullSendValue();        void setNullSendValue(int v); +      int defaultInChannels() const { return _defaultInChannels; } +      int defaultOutChannels() const { return _defaultOutChannels; } +      void setDefaultInChannels(int c) { _defaultInChannels = c; } +      void setDefaultOutChannels(int c) { _defaultOutChannels = c; }        RouteList* inRoutes()    { return &_inRoutes; }        RouteList* outRoutes()   { return &_outRoutes; }        bool noInRoute() const   { return _inRoutes.empty();  } diff --git a/muse2/muse/song.cpp b/muse2/muse/song.cpp index 64287e14..407b8dce 100644 --- a/muse2/muse/song.cpp +++ b/muse2/muse/song.cpp @@ -254,6 +254,52 @@ Track* Song::addTrack(int t)        msgInsertTrack(track, -1, true);        insertTrack3(track, -1); +      // Add default track <-> midiport routes.  +      if(track->isMidiTrack())  +      { +        MidiTrack* mt = (MidiTrack*)track; +        int c, cbi, ch; +        bool defOutFound = false;                /// TODO: Remove this when multiple out routes supported. +        for(int i = 0; i < MIDI_PORTS; ++i) +        { +          MidiPort* mp = &midiPorts[i]; +           +          c = mp->defaultInChannels(); +          if(c) +          { +            audio->msgAddRoute(Route(i, c), Route(track, c)); +            updateFlags |= SC_ROUTE; +          } +           +          if(!defOutFound)                       /// +          { +            c = mp->defaultOutChannels(); +            if(c) +            { +               +        /// TODO: Switch when multiple out routes supported. +        #if 0 +              audio->msgAddRoute(Route(track, c), Route(i, c)); +              updateFlags |= SC_ROUTE; +        #else  +              for(ch = 0; ch < MIDI_CHANNELS; ++ch)    +              { +                cbi = 1 << ch; +                if(c & cbi) +                { +                  defOutFound = true; +                  mt->setOutPort(i); +                  mt->setOutChannel(ch); +                  updateFlags |= SC_ROUTE; +                  break;                +                } +              } +        #endif +            } +          }   +        } +      } +                          //        //  add default route to master        // @@ -261,14 +307,15 @@ Track* Song::addTrack(int t)        if (!ol->empty()) {              AudioOutput* ao = ol->front();              switch(type) { -                  case Track::MIDI: -                  case Track::DRUM: -                  case Track::AUDIO_OUTPUT: -                        break; +                  //case Track::MIDI: +                  //case Track::DRUM: +                  //case Track::AUDIO_OUTPUT: +                  //      break; +                                      case Track::WAVE: -                  case Track::AUDIO_GROUP: +                  //case Track::AUDIO_GROUP:  // Removed by Tim.                    case Track::AUDIO_AUX: -                  case Track::AUDIO_INPUT: +                  //case Track::AUDIO_INPUT:  // Removed by Tim.                    // p3.3.38                    //case Track::AUDIO_SOFTSYNTH:                          audio->msgAddRoute(Route((AudioTrack*)track, -1), Route(ao, -1)); @@ -279,6 +326,8 @@ Track* Song::addTrack(int t)                          audio->msgAddRoute(Route((AudioTrack*)track, 0, ((AudioTrack*)track)->channels()), Route(ao, 0, ((AudioTrack*)track)->channels()));                          updateFlags |= SC_ROUTE;                          break; +                  default: +                        break;                    }              }        audio->msgUpdateSoloStates(); diff --git a/muse2/muse/sync.cpp b/muse2/muse/sync.cpp index c1056e82..9fe5f4d3 100644 --- a/muse2/muse/sync.cpp +++ b/muse2/muse/sync.cpp @@ -402,6 +402,16 @@ void MidiSyncInfo::trigActDetect(const int ch)  }  //--------------------------------------------------------- +//   isDefault +//--------------------------------------------------------- + +bool MidiSyncInfo::isDefault() const +{ +  return(_idOut == 127 && _idIn == 127 && !_sendMC && !_sendMRT && !_sendMMC && !_sendMTC &&  +     /* !_sendContNotStart && */ !_recMC && !_recMRT && !_recMMC && !_recMTC && _recRewOnStart); +} + +//---------------------------------------------------------  //   read  //--------------------------------------------------------- @@ -462,8 +472,10 @@ void MidiSyncInfo::write(int level, Xml& xml)    //  return;    // All defaults? Nothing to write. -  if(_idOut == 127 && _idIn == 127 && !_sendMC && !_sendMRT && !_sendMMC && !_sendMTC &&  -     /* !_sendContNotStart && */ !_recMC && !_recMRT && !_recMMC && !_recMTC && _recRewOnStart) +  //if(_idOut == 127 && _idIn == 127 && !_sendMC && !_sendMRT && !_sendMMC && !_sendMTC &&  +  //   /* !_sendContNotStart && */ !_recMC && !_recMRT && !_recMMC && !_recMTC && _recRewOnStart) +  //  return; +  if(isDefault())        return;    xml.tag(level++, "midiSyncInfo"); diff --git a/muse2/muse/sync.h b/muse2/muse/sync.h index d6a08f0d..47acece8 100644 --- a/muse2/muse/sync.h +++ b/muse2/muse/sync.h @@ -120,6 +120,7 @@ class MidiSyncInfo      bool actDetect(const int ch) const;      void trigActDetect(const int ch); +    bool isDefault() const;      void read(Xml& xml);      //void write(int level, Xml& xml, MidiDevice* md);      void write(int level, Xml& xml); diff --git a/muse2/muse/widgets/mtrackinfobase.ui b/muse2/muse/widgets/mtrackinfobase.ui index 30b111c2..43cf6927 100644 --- a/muse2/muse/widgets/mtrackinfobase.ui +++ b/muse2/muse/widgets/mtrackinfobase.ui @@ -330,7 +330,7 @@          <string>input routing</string>         </property>         <property name="text"> -        <string>iR</string> +        <string>Inputs</string>         </property>        </widget>       </item> @@ -389,17 +389,11 @@           <verstretch>0</verstretch>          </sizepolicy>         </property> -       <property name="maximumSize"> -        <size> -         <width>14</width> -         <height>32767</height> -        </size> -       </property>         <property name="toolTip"> -        <string>Echo</string> +        <string>Midi thru</string>         </property>         <property name="whatsThis"> -        <string>Echo recording events to output.</string> +         <string>Pass input events through ('thru') to output.</string>         </property>         <property name="checkable">          <bool>true</bool> | 
