QMenu* midiPortsPopup(QWidget* parent, int checkPort) { QMenu* p = new QMenu(parent); for (int i = 0; i < MIDI_PORTS; ++i) { MidiPort* port = &midiPorts[i]; QString name; name.sprintf("%d:%s", port->portno() + 1, port->portname().toLatin1().constData()); QAction *act = p->addAction(name); act->setData(i); if (i == checkPort) act->setChecked(true); } return p; }
static void writeSeqConfiguration(int level, Xml& xml, bool writePortInfo)/*{{{*/ { xml.tag(level++, "sequencer"); if (writePortInfo) { // // write information about all midi ports, their assigned // instruments and all managed midi controllers // for (int i = 0; i < MIDI_PORTS; ++i) { bool used = false; 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. // Dont write the config for the global inputs list they will be auto created with each startup if (mport->defaultInChannels() || mport->defaultOutChannels() || (mport->instrument() && !mport->instrument()->iname().isEmpty() && mport->instrument()->iname() != "GM") /*|| !mport->syncInfo().isDefault()*/ ) { used = true; } else {//Put the ID of this track into a list 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; bool isGlobal = gInputListPorts.contains(mport->portno()); xml.tag(level++, "midiport portId=\"%lld\" isGlobalInput=\"%d\"", mport->id(), isGlobal); if (mport->defaultInChannels()) xml.intTag(level, "defaultInChans", mport->defaultInChannels()); if (mport->defaultOutChannels()) xml.intTag(level, "defaultOutChans", mport->defaultOutChannels()); if (mport->instrument() && !mport->instrument()->iname().isEmpty() && (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()); xml.intTag(level, "cacheNRPN", (int)dev->cacheNRPN()); if (dev->deviceType() != MidiDevice::ALSA_MIDI) xml.intTag(level, "type", dev->deviceType()); xml.intTag(level, "openFlags", dev->openFlags()); } // write out registered controller for all channels MidiCtrlValListList* vll = mport->controller(); for (int k = 0; k < MIDI_CHANNELS; ++k) { int min = k << 24; int max = min + 0x100000; xml.tag(level++, "channel idx=\"%d\"", k); iMidiCtrlValList s = vll->lower_bound(min); iMidiCtrlValList e = vll->lower_bound(max); if (s != e) { for (iMidiCtrlValList i = s; i != e; ++i) { if(i->second->num() != 262145) { xml.tag(level++, "controller id=\"%d\"", i->second->num()); if (i->second->hwVal() != CTRL_VAL_UNKNOWN) xml.intTag(level, "val", i->second->hwVal()); xml.etag(--level, "controller"); } } } xml.etag(--level, "channel"); } QList<PatchSequence*> *patchSequences = mport->patchSequences(); if (patchSequences && !patchSequences->isEmpty()) { for (int p = 0; p < patchSequences->size(); ++p) { PatchSequence* ps = patchSequences->at(p); QString pm = ps->name.replace('\n', " "); xml.put(level, "<patchSequence id=\"%d\" name=\"%s\" checked=\"%d\" />", ps->id, pm.toLatin1().constData(), ps->selected); } } if(!mport->presets()->isEmpty()) { QHashIterator<int, QString> iter(*mport->presets()); while(iter.hasNext()) { iter.next(); xml.put(level, "<midiPreset id=\"%d\" sysex=\"%s\"/>", iter.key(), iter.value().toLatin1().constData()); } } xml.etag(--level, "midiport"); } } xml.tag(--level, "/sequencer"); }/*}}}*/
void Route::read(Xml& xml)/*{{{*/ { QString s; int dtype = MidiDevice::ALSA_MIDI; int port = -1; unsigned char rtype = Route::TRACK_ROUTE; for (;;) { const QString& tag = xml.s1(); Xml::Token token = xml.parse(); switch (token) { case Xml::Error: case Xml::End: return; case Xml::Attribut: #ifdef ROUTE_DEBUG printf("Route::read(): attribute:%s\n", tag.toLatin1().constData()); #endif if (tag == "type") rtype = xml.s2().toInt(); else if (tag == "devtype") { dtype = xml.s2().toInt(); rtype = Route::MIDI_DEVICE_ROUTE; } else if (tag == "name") s = xml.s2(); else if(tag == "trackId") { trackId = xml.s2().toLongLong(); rtype = Route::TRACK_ROUTE; } else if (tag == "mport") // p3.3.49 { port = xml.s2().toInt(); rtype = Route::MIDI_PORT_ROUTE; } else if(tag == "mportId") { midiPortId = xml.s2().toLongLong(); rtype = Route::MIDI_PORT_ROUTE; } else printf("Route::read(): unknown attribute:%s\n", tag.toLatin1().constData()); break; case Xml::TagEnd: #ifdef ROUTE_DEBUG printf("Route::read(): tag end type:%d channel:%d name:%s\n", rtype, channel, s.toLatin1().constData()); #endif if (rtype == MIDI_PORT_ROUTE) { if(midiPortId > 0) { //qDebug("Route::read(): MIDI_PORT_ROUTE Finding midiport from id"); type = rtype; MidiPort *mp = oomMidiPorts.value(midiPortId); if(mp) { midiPort = mp->portno(); //qDebug("Route::read(): Found midiport from id: %d", midiPort); } } else if (port >= 0 && port < MIDI_PORTS) { type = rtype; midiPort = port; MidiPort *mp = &midiPorts[midiPort]; midiPortId = mp->id(); } else printf("Route::read(): midi port <%d> out of range\n", port); } else if (!s.isEmpty()) { if (rtype == TRACK_ROUTE) { if(trackId > 0) { track = song->findTrackById(trackId); type = rtype; } else { TrackList* tl = song->tracks(); iTrack i = tl->begin(); for (; i != tl->end(); ++i) { Track* t = *i; if (t->name() == s) { track = t; type = rtype; trackId = t->id(); break; } } if (i == tl->end()) printf("Route::read(): track <%s> not found\n", s.toLatin1().constData()); } } else if (rtype == JACK_ROUTE) { void* jport = 0; if (audioDevice) //Fix from Robert at muse jport = audioDevice->findPort(s.toLatin1().constData()); if (jport == 0) printf("Route::read(): jack port <%s> not found audioDevice(%p)\n", s.toLatin1().constData(), audioDevice); else { jackPort = jport; type = rtype; } } else if (rtype == MIDI_DEVICE_ROUTE) { iMidiDevice imd = midiDevices.begin(); for (; imd != midiDevices.end(); ++imd) { MidiDevice* md = *imd; if (md->name() == s && md->deviceType() == dtype) { // We found a device, but if it is not in use by the song (port is -1), ignore it. // This prevents loading and propagation of bogus routes in the oom file. if (md->midiPort() == -1) break; device = md; type = rtype; break; } } if (imd == midiDevices.end()) printf("Route::read(): midi device <%s> not found\n", s.toLatin1().constData()); } } return; default: break; } } }/*}}}*/