Example #1
0
File: conf.cpp Project: Adamiko/los
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;
        }
    }
}/*}}}*/
Example #2
0
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;
    }
}