void MidiPort::setMidiDevice(MidiDevice* dev) { // close old device if (_device) { _device->setPort(-1); _device->close(); } // set-up new device if (dev) { for (int i = 0; i < kMaxMidiPorts; ++i) { MidiPort* mp = &midiPorts[i]; if (mp->device() == dev) { // move device _state = mp->state(); mp->clearDevice(); break; } } _device = dev; _state = _device->open(); _device->setPort(portno()); } else // dev is null, clear this device clearDevice(); }
int getFreeMidiPort()/*{{{*/ { int rv = -1; for (int i = 0; i < MIDI_PORTS; ++i) { MidiPort* mp = &midiPorts[i]; //Use the first unconfigured port if (!mp->device()) { rv = i; break; } } return rv; }/*}}}*/
void MidiPort::setMidiDevice(MidiDevice* dev) { // close old device if (_device) { if (_device->isSynthPlugin()) { _instrument = genericMidiInstrument; } _device->setPort(-1); _device->close(); } // set-up new device if (dev) { for (int i = 0; i < MIDI_PORTS; ++i) { MidiPort* mp = &midiPorts[i]; if (mp->device() == dev) { if (dev->isSynthPlugin()) mp->setInstrument(genericMidiInstrument); // move device _state = mp->state(); mp->clearDevice(); break; } } _device = dev; if (_device->isSynthPlugin()) { SynthPluginDevice* s = (SynthPluginDevice*) _device; _instrument = s; //_instrument = genericMidiInstrument; } _state = _device->open(); _device->setPort(portno()); } else // dev is null, clear this device clearDevice(); }
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"); }/*}}}*/
static void readConfigMidiPort(Xml& xml)/*{{{*/ { int idx = 0; qint64 id = -1; QString device; bool isGlobal = false; QString instrument("GM"); QList<PatchSequence*> patchSequences; QList<QPair<int, QString> > presets; int openFlags = 1; int dic = 0; int doc = 0; int type = MidiDevice::ALSA_MIDI; bool cachenrpn = false; MidiDevice* dev = 0; for (;;) { Xml::Token token = xml.parse(); if (token == Xml::Error || token == Xml::End) break; QString tag = xml.s1(); switch (token) { case Xml::TagStart: if (tag == "name") { device = xml.parse1(); if (!dev)//Look for it as an alsa or already created device dev = midiDevices.find(device); } else if (tag == "type") { type = xml.parseInt(); } else if (tag == "record") { // old bool f = xml.parseInt(); if (f) openFlags |= 2; } else if (tag == "openFlags") openFlags = xml.parseInt(); else if (tag == "defaultInChans") dic = xml.parseInt(); else if (tag == "defaultOutChans") doc = xml.parseInt(); else if (tag == "instrument") { instrument = xml.parse1(); } else if (tag == "channel") { readPortChannel(xml, idx); } else if (tag == "preset" || tag == "patchSequence") { PatchSequence* p = readMidiPortPatchSequences(xml); if (p) patchSequences.append(p); } else if(tag == "midiPreset") { presets.append(readMidiPortPreset(xml)); } else if(tag == "cacheNRPN") { cachenrpn = xml.parseInt(); } else xml.skip(tag); break; case Xml::Attribut: if (tag == "idx") {//Check to see if this port is already used, and bump if so idx = xml.s2().toInt(); int freePort = getFreeMidiPort(); if(freePort != idx) {//Set a flag here so we know when loading tracks later that we are dealing with an old file or global inputs changed idx = freePort; } } else if(tag == "portId") {//New style id = xml.s2().toLongLong(); idx = getFreeMidiPort(); } else if(tag == "isGlobalInput") {//Find the matching input if posible and set our index to it isGlobal = xml.s2().toInt(); } break; case Xml::TagEnd: if (tag == "midiport") { if(isGlobal) {//Find the global input that matches // if(gInputListPorts.size()) { int myport = -1; for(int i = 0; i < gInputListPorts.size(); ++i) { myport = gInputListPorts.at(i); MidiPort* inport = &midiPorts[i]; if(inport && inport->device() && inport->device()->name() == device) { idx = myport; break; } } } } if (idx < 0 || idx >= MIDI_PORTS) { fprintf(stderr, "bad midi port %d (>%d)\n", idx, MIDI_PORTS); idx = 0; } if (!dev) { if (type == MidiDevice::JACK_MIDI) { dev = MidiJackDevice::createJackMidiDevice(device); // p3.3.55 if (debugMsg) fprintf(stderr, "readConfigMidiPort: creating jack midi device %s\n", device.toLatin1().constData()); } else dev = midiDevices.find(device); } if (debugMsg && !dev) fprintf(stderr, "readConfigMidiPort: device not found %s\n", device.toLatin1().constData()); MidiPort* mp = &midiPorts[idx]; if(id) mp->setPortId(id); mp->setInstrument(registerMidiInstrument(instrument)); mp->setDefaultInChannels(dic); mp->setDefaultOutChannels(doc); //Indicate the port was found in the song file, even if no device is assigned to it. mp->setFoundInSongFile(true); if (!patchSequences.isEmpty()) { for (int i = 0; i < patchSequences.size(); ++i) { mp->appendPatchSequence(patchSequences.at(i)); } } if(!presets.isEmpty()) { for(int i = 0; i < presets.size(); ++i) { QPair<int, QString> pair = presets.at(i); mp->addPreset(pair.first, pair.second); } } if (dev) { dev->setOpenFlags(openFlags); midiSeq->msgSetMidiDevice(mp, dev); dev->setCacheNRPN(cachenrpn); } losMidiPorts.insert(mp->id(), mp); return; } default: break; } } }/*}}}*/
void MPConfig::songChanged(int flags) { // Is it simply a midi controller value adjustment? Forget it. if (flags == SC_MIDI_CONTROLLER) return; // Get currently selected index... int no = -1; QTableWidgetItem* sitem = mdevView->currentItem(); if (sitem) { QString id = sitem->tableWidget()->item(sitem->row(), DEVCOL_NO)->text(); no = atoi(id.toLatin1().constData()) - 1; if (no < 0 || no >= kMaxMidiPorts) no = -1; } sitem = 0; for (int i = kMaxMidiPorts - 1; i >= 0; --i) { mdevView->blockSignals(true); // otherwise itemChanged() is triggered and bad things happen. MidiPort* port = &midiPorts[i]; MidiDevice* dev = port->device(); QString s; s.setNum(i + 1); QTableWidgetItem* itemno = mdevView->item(i, DEVCOL_NO); QTableWidgetItem* itemstate = mdevView->item(i, DEVCOL_STATE); itemstate->setText(port->state()); QTableWidgetItem* iteminstr = mdevView->item(i, DEVCOL_INSTR); QString instrumentName = port->instrument() ? port->instrument()->iname() : tr("<unknown>"); iteminstr->setText(instrumentName); iteminstr->setToolTip(instrumentName); QTableWidgetItem* itemname = mdevView->item(i, DEVCOL_NAME); QTableWidgetItem* itemgui = mdevView->item(i, DEVCOL_GUI); QTableWidgetItem* itemfb = mdevView->item(i, DEVCOL_CACHE_NRPN); QTableWidgetItem* itemrec = mdevView->item(i, DEVCOL_REC); QTableWidgetItem* itemplay = mdevView->item(i, DEVCOL_PLAY); QTableWidgetItem* itemout = mdevView->item(i, DEVCOL_OUTROUTES); QTableWidgetItem* itemin = mdevView->item(i, DEVCOL_INROUTES); QTableWidgetItem* itemdefin = mdevView->item(i, DEVCOL_DEF_IN_CHANS); itemdefin->setText(bitmap2String(port->defaultInChannels())); QTableWidgetItem* itemdefout = mdevView->item(i, DEVCOL_DEF_OUT_CHANS); itemdefout->setText(bitmap2String(port->defaultOutChannels())); mdevView->blockSignals(false); if (dev) { itemname->setText(dev->name()); itemname->setToolTip(dev->name()); // Is it a Jack midi device? Allow renaming. //if(dynamic_cast<MidiJackDevice*>(dev)) if (dev->deviceType() == MidiDevice::JACK_MIDI) itemname->setFlags(Qt::ItemIsEditable | Qt::ItemIsEnabled); if (dev->rwFlags() & 0x2) { itemrec->setIcon(dev->openFlags() & 2 ? QIcon(*dotIcon) : QIcon(*dothIcon)); } else { itemrec->setIcon(QIcon(QPixmap())); } if (dev->rwFlags() & 0x1) { itemplay->setIcon(dev->openFlags() & 1 ? QIcon(*dotIcon) : QIcon(*dothIcon)); } else itemplay->setIcon(QIcon(QPixmap())); itemfb->setIcon(dev->cacheNRPN() ? QIcon(*dotIcon) : QIcon(*dothIcon)); } else { itemname->setText(tr("<none>")); itemname->setToolTip(""); itemgui->setIcon(QIcon(*dothIcon)); itemrec->setIcon(QIcon(QPixmap())); itemplay->setIcon(QIcon(QPixmap())); itemfb->setIcon(QIcon(QPixmap())); } // falkTX, we don't want this in the connections manager //if (port->hasGui()) //{ // itemgui->setIcon(port->guiVisible() ? QIcon(*dotIcon) : QIcon(*dothIcon)); //} //else //{ itemgui->setIcon(QIcon(QPixmap())); //} iteminstr->setIcon(QIcon(*buttondownIcon)); itemname->setIcon(QIcon(*buttondownIcon)); //if(dev && dynamic_cast<MidiJackDevice*>(dev)) if (dev && dev->deviceType() == MidiDevice::JACK_MIDI) { //item->setPixmap(DEVCOL_ROUTES, *buttondownIcon); //item->setText(DEVCOL_ROUTES, tr("routes")); // p3.3.55 if (dev->rwFlags() & 1) //if(dev->openFlags() & 1) { itemout->setIcon(QIcon(*buttondownIcon)); if (port->device() && !port->device()->outRoutes()->empty()) { RouteList* list = port->device()->outRoutes(); if (!list->empty()) { iRoute r = list->begin(); itemout->setText(r->name()); } } else { itemout->setText(tr("out")); } //if (dev->openFlags() & 1) // itemout->setText(tr("out")); } if (dev->rwFlags() & 2) //if(dev->openFlags() & 2) { itemin->setIcon(QIcon(*buttondownIcon)); if (dev->openFlags() & 2) itemin->setText(tr("in")); } } if (i == no) sitem = itemno; } if (sitem) { mdevView->setCurrentItem(sitem); } }
void MPConfig::rbClicked(QTableWidgetItem* item) { if (item == 0) return; QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text(); int no = atoi(id.toLatin1().constData()) - 1; if (no < 0 || no >= kMaxMidiPorts) return; int n; MidiPort* port = &midiPorts[no]; MidiDevice* dev = port->device(); int rwFlags = dev ? dev->rwFlags() : 0; int openFlags = dev ? dev->openFlags() : 0; QTableWidget* listView = item->tableWidget(); QPoint ppt = listView->visualItemRect(item).bottomLeft(); QPoint mousepos = QCursor::pos(); int col = item->column(); ppt += QPoint(0, listView->horizontalHeader()->height()); ppt = listView->mapToGlobal(ppt); switch (col) { case DEVCOL_GUI: if (dev == 0) //break; return; // falkTX, we don't want this in the connections manager //if (port->hasGui()) //{ // port->instrument()->showGui(!port->guiVisible()); // item->setIcon(port->guiVisible() ? QIcon(*dotIcon) : QIcon(*dothIcon)); //} //break; return; case DEVCOL_CACHE_NRPN: if (!dev) return; dev->setCacheNRPN(!dev->cacheNRPN()); item->setIcon(dev->cacheNRPN() ? QIcon(*dotIcon) : QIcon(*dothIcon)); return; case DEVCOL_REC: if (dev == 0 || !(rwFlags & 2)) return; openFlags ^= 0x2; dev->setOpenFlags(openFlags); midiSeq->msgSetMidiDevice(port, dev); // reopen device item->setIcon(openFlags & 2 ? QIcon(*dotIcon) : QIcon(*dothIcon)); if (dev->deviceType() == MidiDevice::JACK_MIDI) { if (dev->openFlags() & 2) { item->tableWidget()->item(item->row(), DEVCOL_INROUTES)->setText(tr("in")); } else { item->tableWidget()->item(item->row(), DEVCOL_INROUTES)->setText(""); } } return; case DEVCOL_PLAY: if (dev == 0 || !(rwFlags & 1)) return; openFlags ^= 0x1; dev->setOpenFlags(openFlags); midiSeq->msgSetMidiDevice(port, dev); // reopen device item->setIcon(openFlags & 1 ? QIcon(*dotIcon) : QIcon(*dothIcon)); if (dev->deviceType() == MidiDevice::JACK_MIDI) { if (dev->openFlags() & 1) { item->tableWidget()->item(item->row(), DEVCOL_OUTROUTES)->setText(tr("out")); } else { item->tableWidget()->item(item->row(), DEVCOL_OUTROUTES)->setText(""); } } return; case DEVCOL_INROUTES: case DEVCOL_OUTROUTES: { if (!checkAudioDevice()) return; if (audioDevice->deviceType() != AudioDevice::JACK_AUDIO) //Only if Jack is running. return; if (!dev) return; // Only Jack midi devices. if (dev->deviceType() != MidiDevice::JACK_MIDI) return; if (!(dev->openFlags() & ((col == DEVCOL_OUTROUTES) ? 1 : 2))) return; RouteList* rl = (col == DEVCOL_OUTROUTES) ? dev->outRoutes() : dev->inRoutes(); // p3.3.55 QMenu* pup = 0; int gid = 0; std::list<QString> sl; pup = new QMenu(this); //A temporary Route to us for matching later QString currentRoute(""); bool routeSelected = false; _redisplay: pup->clear(); gid = 0; // Jack input ports if device is writable, and jack output ports if device is readable. sl = (col == DEVCOL_OUTROUTES) ? audioDevice->inputPorts(true, _showAliases) : audioDevice->outputPorts(true, _showAliases); QAction* act; act = pup->addAction(tr("Show first aliases")); act->setData(gid); act->setCheckable(true); act->setChecked(_showAliases == 0); ++gid; act = pup->addAction(tr("Show second aliases")); act->setData(gid); act->setCheckable(true); act->setChecked(_showAliases == 1); ++gid; pup->addSeparator(); for (std::list<QString>::iterator ip = sl.begin(); ip != sl.end(); ++ip) { act = pup->addAction(*ip); act->setData(gid); act->setCheckable(true); Route rt(*ip, (col == DEVCOL_OUTROUTES), -1, Route::JACK_ROUTE); for (iRoute ir = rl->begin(); ir != rl->end(); ++ir) { if (*ir == rt) { currentRoute = (*ir).name(); act->setChecked(true); routeSelected = true; break; } } ++gid; } act = pup->exec(ppt); if (act) { n = act->data().toInt(); if (n == 0) // Show first aliases { if (_showAliases == 0) _showAliases = -1; else _showAliases = 0; goto _redisplay; // Go back } else if (n == 1) // Show second aliases { if (_showAliases == 1) _showAliases = -1; else _showAliases = 1; goto _redisplay; // Go back } QString s(act->text()); if (col == DEVCOL_OUTROUTES) // Writable { Route srcRoute(dev, -1); Route dstRoute(s, true, -1, Route::JACK_ROUTE); if(routeSelected && currentRoute == s) { //it will alread be handled by an unchecked operation routeSelected = false; } iRoute iir = rl->begin(); for (; iir != rl->end(); ++iir) { if (*iir == dstRoute) break; } if (iir != rl->end()) { // disconnect audio->msgRemoveRoute(srcRoute, dstRoute); } else { // connect audio->msgAddRoute(srcRoute, dstRoute); } if(routeSelected) { iRoute selr = rl->begin(); for (; selr != rl->end(); ++selr) { //clean up the routing list as something was selected that was not the current so delete the old route if((*selr).name() == currentRoute) { audio->msgRemoveRoute(srcRoute, (*selr)); break; } } } } else { Route srcRoute(s, false, -1, Route::JACK_ROUTE); Route dstRoute(dev, -1); iRoute iir = rl->begin(); for (; iir != rl->end(); ++iir) { if (*iir == srcRoute) break; } if (iir != rl->end()) // disconnect audio->msgRemoveRoute(srcRoute, dstRoute); else // connect audio->msgAddRoute(srcRoute, dstRoute); } audio->msgUpdateSoloStates(); song->update(SC_ROUTE); } delete pup; } return; case DEVCOL_DEF_IN_CHANS: case DEVCOL_DEF_OUT_CHANS: { } //break; return; case DEVCOL_NAME: { //printf("MPConfig::rbClicked DEVCOL_NAME\n"); // Did we click in the text area? // NOTE: this needs the +15 pixels to make up for padding in the stylesheet. if ((mousepos.x() - (ppt.x() + 15)) > buttondownIcon->width()) { // Start the renaming of the cell... QModelIndex current = item->tableWidget()->currentIndex(); if (item->flags() & Qt::ItemIsEditable) item->tableWidget()->edit(current.sibling(current.row(), DEVCOL_NAME)); return; } else {// We clicked the 'down' button. QMenu* pup = new QMenu(this); QAction* act; act = pup->addAction(tr("Create") + QT_TRANSLATE_NOOP("@default", " Jack") + tr(" device")); act->setData(0); typedef std::map<std::string, int > asmap; typedef std::map<std::string, int >::iterator imap; asmap mapALSA; asmap mapJACK; int aix = 0x10000000; int jix = 0x20000000; for (iMidiDevice i = midiDevices.begin(); i != midiDevices.end(); ++i) { if ((*i)->deviceType() == MidiDevice::ALSA_MIDI) { mapALSA.insert(std::pair<std::string, int> (std::string((*i)->name().toLatin1().constData()), aix)); ++aix; } else if ((*i)->deviceType() == MidiDevice::JACK_MIDI) { mapJACK.insert(std::pair<std::string, int> (std::string((*i)->name().toLatin1().constData()), jix)); ++jix; } else printf("MPConfig::rbClicked unknown midi device: %s\n", (*i)->name().toLatin1().constData()); } pup->addSeparator(); pup->addAction(new MenuTitleItem(QT_TRANSLATE_NOOP("@default", "ALSA:"), pup)); for (imap i = mapALSA.begin(); i != mapALSA.end(); ++i) { int idx = i->second; QString s(i->first.c_str()); MidiDevice* md = midiDevices.find(s, MidiDevice::ALSA_MIDI); if (md) { if (md->deviceType() != MidiDevice::ALSA_MIDI) continue; act = pup->addAction(QT_TRANSLATE_NOOP("@default", md->name())); act->setData(idx); act->setCheckable(true); act->setChecked(md == dev); } } pup->addSeparator(); pup->addAction(new MenuTitleItem(QT_TRANSLATE_NOOP("@default", "JACK:"), pup)); for (imap i = mapJACK.begin(); i != mapJACK.end(); ++i) { int idx = i->second; QString s(i->first.c_str()); MidiDevice* md = midiDevices.find(s, MidiDevice::JACK_MIDI); if (md) { if (md->deviceType() != MidiDevice::JACK_MIDI) continue; act = pup->addAction(QT_TRANSLATE_NOOP("@default", md->name())); act->setData(idx); act->setCheckable(true); act->setChecked(md == dev); } } act = pup->exec(ppt); if (!act) { delete pup; return; } n = act->data().toInt(); //printf("MPConfig::rbClicked n:%d\n", n); MidiDevice* sdev = 0; if (n < 0x10000000) { delete pup; if (n <= 2) { sdev = MidiJackDevice::createJackMidiDevice(); if (sdev) { int of = 3; switch (n) { case 0: of = 0; //3; Set the open flags of the midiDevice this should be off by default break; case 1: of = 2; break; case 2: of = 1; break; } sdev->setOpenFlags(of); } } } else { int typ; if (n < 0x20000000) typ = MidiDevice::ALSA_MIDI; else if (n < 0x30000000) typ = MidiDevice::JACK_MIDI; else typ = MidiDevice::UNKNOWN_MIDI; sdev = midiDevices.find(act->text(), typ); delete pup; // Is it the current device? Reset it to <none>. // falkTX, handle synths properly here if (sdev == dev) { sdev = 0; } else { } } midiSeq->msgSetMidiDevice(port, sdev); los->changeConfig(true); // save configuration file song->update(); } } //break; return; case DEVCOL_INSTR: { if (instrPopup == 0) instrPopup = new QMenu(this); instrPopup->clear(); for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) { instrPopup->addAction((*i)->iname()); } QAction* act = instrPopup->exec(ppt, 0); if (!act) return; QString s = act->text(); item->tableWidget()->item(item->row(), DEVCOL_INSTR)->setText(s); for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) { if ((*i)->iname() == s) { port->setInstrument(*i); break; } } song->update(); } return; } }
void MPConfig::mdevViewItemRenamed(QTableWidgetItem* item) { int col = item->column(); QString s = item->text(); //printf("MPConfig::mdevViewItemRenamed col:%d txt:%s\n", col, s.toLatin1().constData()); if (item == 0) 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 >= kMaxMidiPorts) return; midiPorts[no].setDefaultInChannels(((1 << kMaxMidiChannels) - 1) & 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 >= kMaxMidiPorts) return; midiPorts[no].setDefaultOutChannels(((1 << kMaxMidiChannels) - 1) & string2bitmap(s)); song->update(); } break; case DEVCOL_NAME: { QString id = item->tableWidget()->item(item->row(), DEVCOL_NO)->text(); int no = atoi(id.toLatin1().constData()) - 1; if (no < 0 || no >= kMaxMidiPorts) return; MidiPort* port = &midiPorts[no]; MidiDevice* dev = port->device(); // Only Jack midi devices. if (!dev || dev->deviceType() != MidiDevice::JACK_MIDI) return; if (dev->name() == s) return; if (midiDevices.find(s)) { QMessageBox::critical(this, tr("LOS: bad device name"), tr("please choose a unique device name"), QMessageBox::Ok, Qt::NoButton, Qt::NoButton); songChanged(-1); return; } dev->setName(s); song->update(); } break; default: //printf("MPConfig::mdevViewItemRenamed unknown column clicked col:%d txt:%s\n", col, s.toLatin1().constData()); break; } }
void Audio::initDevices() { // // mark all used ports // bool activePorts[MIDI_PORTS]; for (int i = 0; i < MIDI_PORTS; ++i) activePorts[i] = false; MidiTrackList* tracks = song->midis(); for (iMidiTrack it = tracks->begin(); it != tracks->end(); ++it) { MidiTrack* track = *it; activePorts[track->outPort()] = true; } if (song->click()) activePorts[clickPort] = true; // // test for explicit instrument initialization // for (int i = 0; i < MIDI_PORTS; ++i) { if (!activePorts[i]) continue; MidiPort* port = &midiPorts[i]; MidiInstrument* instr = port->instrument(); MidiDevice* md = port->device(); if (instr && md) { EventList* events = instr->midiInit(); if (events->empty()) continue; for (iEvent ie = events->begin(); ie != events->end(); ++ie) { MidiPlayEvent ev(0, i, 0, ie->second); md->putEvent(ev); } activePorts[i] = false; // no standard initialization } } // // damit Midi-Devices, die mehrere Ports besitzen, wie z.B. // das Korg NS5R, nicht mehrmals zwischen GM und XG/GS hin und // hergeschaltet werden, wird zunïÿýhst auf allen Ports GM // initialisiert, und dann erst XG/GS // // Standard initialization... for (int i = 0; i < MIDI_PORTS; ++i) { if (!activePorts[i]) continue; MidiPort* port = &midiPorts[i]; switch (song->mtype()) { case MT_GS: case MT_UNKNOWN: break; case MT_GM: case MT_XG: port->sendGmOn(); break; } } for (int i = 0; i < MIDI_PORTS; ++i) { if (!activePorts[i]) continue; MidiPort* port = &midiPorts[i]; switch (song->mtype()) { case MT_UNKNOWN: break; case MT_GM: port->sendGmInitValues(); break; case MT_GS: port->sendGsOn(); port->sendGsInitValues(); break; case MT_XG: port->sendXgOn(); port->sendXgInitValues(); break; } } }
void GlobalSettingsConfig::apply() { int rtcticks = rtcResolutionSelect->currentIndex(); config.guiRefresh = guiRefreshSelect->value(); config.rtcTicks = rtcResolutions[rtcticks]; config.userInstrumentsDir = userInstrumentsPath->text(); config.startSong = startSongEntry->text(); config.startMode = startSongGroup->checkedId(); int div = midiDivisionSelect->currentIndex(); if (div < 0 || div > 9) div = 3; config.division = divisions[div]; config.useOldStyleStopShortCut = oldStyleStopCheckBox->isChecked(); config.moveArmedCheckBox = moveArmedCheckBox->isChecked(); config.useProjectSaveDialog = projectSaveCheckBox->isChecked(); losUserInstruments = config.userInstrumentsDir; //QList<QPair<int, QString> > oldList(gInputList); bool hasPorts = !gInputListPorts.isEmpty(); gInputList.clear(); for(int i = 0; i < m_inputsModel->rowCount(); ++i) { QStandardItem* item = m_inputsModel->item(i); if(item) { bool checked = (item->checkState() == Qt::Checked); QPair<int, QString> pinfo = qMakePair(item->data(Qt::UserRole+2).toInt(), item->data(Qt::UserRole+1).toString()); if(hasPorts) { bool found = false; int p = 0; MidiPort* mp = 0; for(p = 0;p < gInputListPorts.size(); p++) { mp = &midiPorts[gInputListPorts.at(p)]; if(mp && mp->device()->name() == pinfo.second) { found = true; break; } } if(!checked) {//Unconfigure if(found && mp) { //TODO:Clear routing list mp->setInstrument(registerMidiInstrument("GM")); midiSeq->msgSetMidiDevice(mp, 0); gInputListPorts.takeAt(p); } } else { if(!found) los->addGlobalInput(pinfo); gInputList.append(pinfo); } } else if(checked) { los->addGlobalInput(pinfo); gInputList.append(pinfo); } } } los->setHeartBeat(); // set guiRefresh midiSeq->msgSetRtc(); // set midi tick rate los->changeConfig(true); // save settings }