Beispiel #1
0
void initMidiPorts()
{
    //TODO: Remove the need for this code
    //We should populate the losMidiPort hash with ports as we create them
    for (int i = 0; i < kMaxMidiPorts; ++i)
    {
        MidiPort* port = &midiPorts[i];
        ///port->setInstrument(genericMidiInstrument);
        port->setInstrument(registerMidiInstrument("GM")); // Changed by Tim.
    }
}
Beispiel #2
0
void initMidiPorts()
{
	//TODO: Remove the need for this code
	//We should populate the oomMidiPort hash with ports as we create them
	for (int i = 0; i < MIDI_PORTS; ++i)
	{
		MidiPort* port = &midiPorts[i];
		///port->setInstrument(genericMidiInstrument);
		port->setInstrument(registerMidiInstrument("GM")); // Changed by Tim.
		port->syncInfo().setPort(i);
	}
}
Beispiel #3
0
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();
}
Beispiel #4
0
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;
        }
    }
}/*}}}*/
Beispiel #5
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;
    }
}
Beispiel #6
0
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MType t = song->midiType();
    if (!merge)
    {
        t = mf.mtype();
        song->setMType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MT_UNKNOWN) || (t == MIDI_TYPE_GM)))
                || ((mi->iname() == "GS") && (t == MT_GS))
                || ((mi->iname() == "XG") && (t == MT_XG)))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        // somewhat silly and slooow:
        for (int port = 0; port < kMaxMidiPorts; ++port)
        {
            for (int channel = 0; channel < kMaxMidiChannels; ++channel)
            {
                //
                // check if there are any events for port/channel in track:
                //
                iMPEvent i;
                for (i = el->begin(); i != el->end(); ++i)
                {
                    MidiPlayEvent ev = *i;
                    if (ev.type() != ME_SYSEX && ev.type() != ME_META
                            && ev.channel() == channel && ev.port() == port)
                        break;
                }
                if (i == el->end())
                    continue;
                MidiTrack* track = new MidiTrack();
                if ((*t)->isDrumTrack)
                {
                    track->setType(Track::DRUM);
                }

                track->setOutChannel(channel);
                track->setOutPort(port);

                MidiPort* mport = &midiPorts[track->outPort()];
                // this overwrites any instrument set for this port:
                mport->setInstrument(instr);

                EventList* mel = track->events();
                //buildMidiEventList(mel, el, track, division, first);
                // Don't do loops.
                buildMidiEventList(mel, el, track, division, first, false);
                first = false;

                // Hmm. buildMidiEventList already takes care of this.
                // But it seems to work. How? Must test.
                if (channel == 9 && song->midiType() != MT_UNKNOWN)
                {
                    track->setType(Track::DRUM);
                    //
                    // remap drum pitch with drumInmap
                    //
                    EventList* tevents = track->events();
                    for (iEvent i = tevents->begin(); i != tevents->end(); ++i)
                    {
                        Event ev = i->second;
                        if (ev.isNote())
                        {
                            int pitch = drumInmap[ev.pitch()];
                            ev.setPitch(pitch);
                        }
                        else
                            if (ev.type() == Controller)
                        {
                            int ctl = ev.dataA();
                            MidiController *mc = mport->drumController(ctl);
                            if (mc)
                                ev.setA((ctl & ~0xff) | drumInmap[ctl & 0x7f]);
                        }
                    }
                }

                processTrack(track);

                song->insertTrack(track, -1);
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setOutChannel(0);
            track->setOutPort(0);
            EventList* mel = track->events();
            //buildMidiEventList(mel, el, track, division, true);
            // Do SysexMeta. Don't do loops.
            buildMidiEventList(mel, el, track, division, true, false);
            processTrack(track);
            song->insertTrack(track, -1);
        }
    }

    if (!merge)
    {
        TrackList* tl = song->tracks();
        if (!tl->empty())
        {
            Track* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        ///sigmap.timesig(0, z, n);
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
        ///composer->setMode(int(song->midiType())); // p4.0.7 Tim
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
Beispiel #7
0
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MidiType t = song->midiType();
    if (!merge)
    {
        t = mf.midiType();
        song->setMidiType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MIDI_TYPE_NULL) || (t == MIDI_TYPE_GM))) ||
            (mi->iname() == "GS" &&   t == MIDI_TYPE_GS) ||
            (mi->iname() == "XG" &&   t == MIDI_TYPE_XG))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    int mPort = getFreeMidiPort();
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        QList<QPair<int, int> > portChannelList;
        iMPEvent i;
        for(i = el->begin(); i != el->end(); i++)
        {
            if (i->type() != ME_SYSEX && i->type() != ME_META)
            {
                int chan = i->channel();
                int port = i->port();
                if(portChannelList.isEmpty() || !portChannelList.contains(qMakePair(chan, port)))
                {
                    portChannelList.append(qMakePair(chan, port));

                    MidiTrack* track = new MidiTrack();
                    track->setDefaultName();
                    track->setMasterFlag(true);

                    if(config.partColorNames[lastTrackPartColorIndex].contains("menu:", Qt::CaseSensitive))
                        lastTrackPartColorIndex ++;

                    track->setDefaultPartColor(lastTrackPartColorIndex);
                    lastTrackPartColorIndex ++;

                    if(lastTrackPartColorIndex == NUM_PARTCOLORS)
                        lastTrackPartColorIndex = 1;

                    //Set track channel so buildMidiEventList can match the event to a channel
                    track->setOutChannel(chan);
                    track->setOutPort(mPort);

                    MidiPort* mport = &midiPorts[track->outPort()];
                    // this overwrites any instrument set for this port:
                    mport->setInstrument(instr);

                    EventList* mel = track->events();
                    buildMidiEventList(mel, el, track, division, first, false, false);

                    first = false;

                    processTrack(track);

                    //Update track to channel 1
                    //99% of all midi we import will be alien to our setup anyway,
                    //so I'm making it easy for the user to just set the Instrument and go
                    track->setOutChannel(0);

                    song->insertTrack(track, -1);
                    mPort++;
                    //FIXME: Provice a non-iterative way to do this using the new losMidiPorts hash
                    //Or maintain a list of configured or inuse ports
                    while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
                        mPort++;//Just incase we have a configured port after an empty one
                }
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setDefaultName();
            track->setMasterFlag(true);
            track->setOutChannel(0);
            track->setOutPort(mPort);

            if(config.partColorNames[lastTrackPartColorIndex].contains("menu:", Qt::CaseSensitive))
                lastTrackPartColorIndex ++;

            track->setDefaultPartColor(lastTrackPartColorIndex);
            lastTrackPartColorIndex ++;

            if(lastTrackPartColorIndex == NUM_PARTCOLORS)
                lastTrackPartColorIndex = 1;

            EventList* mel = track->events();
            // Do SysexMeta. Don't do loops.
            // TODO: Properly support sysex dumps
            buildMidiEventList(mel, el, track, division, true, false, false);
            processTrack(track);
            song->insertTrack(track, -1);
            mPort++;
            while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
                mPort++;
        }
    }

    if (!merge)
    {
        MidiTrackList* tl = song->tracks();
        if (!tl->empty())
        {
            MidiTrack* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
Beispiel #8
0
bool LOS::importMidi(const QString name, bool merge)/*{{{*/
{
    bool popenFlag;
    FILE* fp = fileOpen(this, name, QString(".mid"), "r", popenFlag);
    if (fp == 0)
        return true;
    MidiFile mf(fp);
    bool rv = mf.read();
    popenFlag ? pclose(fp) : fclose(fp);
    if (rv)
    {
        QString s(tr("reading midifile\n  "));
        s += name;
        s += tr("\nfailed: ");
        s += mf.error();
        QMessageBox::critical(this, QString("LOS"), s);
        return rv;
    }
    //
    //  evaluate song Type (GM, XG, GS, unknown)
    //
    MType t = song->midiType();
    if (!merge)
    {
        t = mf.mtype();
        song->setMType(t);
    }
    MidiInstrument* instr = 0;
    for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
    {
        MidiInstrument* mi = *i;
        if ((mi->iname() == "GM" && ((t == MT_UNKNOWN) || (t == MIDI_TYPE_GM)))
                || ((mi->iname() == "GS") && (t == MT_GS))
                || ((mi->iname() == "XG") && (t == MT_XG)))
        {
            instr = mi;
            break;
        }
    }
    if (instr == 0)
    {
        // the standard instrument files (GM, GS, XG) must be present
        printf("no instrument, type %d\n", t);
        return true;
        //abort();
    }

    MidiFileTrackList* etl = mf.trackList();
    int division = mf.division();

    //
    // create MidiTrack and copy events to ->events()
    //    - combine note on/off events
    //    - calculate tick value for internal resolution
    //
    int mPort = getFreeMidiPort();
    for (iMidiFileTrack t = etl->begin(); t != etl->end(); ++t)
    {
        MPEventList* el = &((*t)->events);
        if (el->empty())
            continue;
        //
        // if we split the track, SYSEX and META events go into
        // the first target track

        bool first = true;
        // somewhat silly and slooow:
        QList<QPair<int, int> > eventChannelList;
        if(mPort >= 0 && mPort < kMaxMidiPorts)
        {
            for (int channel = 0; channel < kMaxMidiChannels; ++channel)
            {
                //
                // check if there are any events for port/channel in track:
                //
                iMPEvent i;
                for (i = el->begin(); i != el->end(); ++i)
                {
                    MidiPlayEvent ev = *i;
                    if (ev.type() != ME_SYSEX && ev.type() != ME_META && ev.channel() == channel)
                        break;
                }
                if (i == el->end())
                    continue;
                MidiTrack* track = new MidiTrack();
                track->setDefaultName();
                track->setMasterFlag(true);

                track->setOutChannel(channel);
                track->setOutPort(mPort);

                MidiPort* mport = &midiPorts[track->outPort()];
                // this overwrites any instrument set for this port:
                mport->setInstrument(instr);

                EventList* mel = track->events();
                buildMidiEventList(mel, el, track, division, first, false, false);

                first = false;

                processTrack(track);

                song->insertTrack(track, -1);
                //Create the Audio input side of the track
                Track* input = song->addTrackByName(QString("i").append(track->name()), Track::AUDIO_INPUT, -1, false, false);
                if(input)
                {
                    input->setMasterFlag(false);
                    input->setChainMaster(track->id());
                    track->addManagedTrack(input->id());
                }
            }
        }
        if (first)
        {
            //
            // track does only contain non-channel messages
            // (SYSEX or META)
            //
            MidiTrack* track = new MidiTrack();
            track->setDefaultName();
            track->setMasterFlag(true);
            track->setOutChannel(0);
            track->setOutPort(mPort);
            EventList* mel = track->events();
            //buildMidiEventList(mel, el, track, division, true);
            // Do SysexMeta. Don't do loops.
            buildMidiEventList(mel, el, track, division, true, false, false);
            processTrack(track);
            song->insertTrack(track, -1);
            //Create the Audio input side of the track
            Track* input = song->addTrackByName(QString("i").append(track->name()), Track::AUDIO_INPUT, -1, false, false);
            if(input)
            {
                input->setMasterFlag(false);
                input->setChainMaster(track->id());
                track->addManagedTrack(input->id());
            }
        }
        mPort++;
        //FIXME: Provice a non-iterative way to do this using the new losMidiPorts hash
        //Or maintain a list of configured or inuse ports
        while((&midiPorts[mPort])->device() && mPort < kMaxMidiPorts)
            mPort++;//Just incase we have a configured port after an empty one
    }

    if (!merge)
    {
        TrackList* tl = song->tracks();
        if (!tl->empty())
        {
            Track* track = tl->front();
            track->setSelected(true);
        }
        song->initLen();

        int z, n;
        sigmap.timesig(0, z, n);

        int tempo = tempomap.tempo(0);
        transport->setTimesig(z, n);
        transport->setTempo(tempo);

        bool masterF = !tempomap.empty();
        song->setMasterFlag(masterF);
        transport->setMasterFlag(masterF);

        song->updatePos();

        composer->reset();
    }
    else
    {
        song->initLen();
    }

    return false;
}/*}}}*/
Beispiel #9
0
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
}