void
AudioPluginOSCGUIManager::updateProgram(InstrumentId instrument, int position)
{
    RG_DEBUG << "AudioPluginOSCGUIManager::updateProgram(" << instrument << ","
             << position << ")" << endl;

    if (m_guis.find(instrument) == m_guis.end() ||
            m_guis[instrument].find(position) == m_guis[instrument].end())
        return ;

    PluginContainer *container = 0;
    container = m_studio->getContainerById(instrument);
    if (!container) return;

    AudioPluginInstance *pluginInstance = container->getPlugin(position);
    if (!pluginInstance) return;

    unsigned long rv = StudioControl::getPluginProgram
                       (pluginInstance->getMappedId(),
                        strtoqstr(pluginInstance->getProgram()));

    int bank = rv >> 16;
    int program = rv - (bank << 16);

    RG_DEBUG << "AudioPluginOSCGUIManager::updateProgram(" << instrument << ","
             << position << "): rv " << rv << ", bank " << bank << ", program " << program << endl;

    m_guis[instrument][position]->sendProgram(bank, program);
}
예제 #2
0
void
ManageMetronomeDialog::populate(int deviceIndex)
{
    m_metronomeInstrument->clear();

    DeviceList *devices = m_doc->getStudio().getDevices();
    DeviceListConstIterator it;
    int count = 0;
    Device *dev = 0;

    for (it = devices->begin(); it != devices->end(); it++) {

        dev = *it;
        if (!isSuitable(dev)) continue;

        if (count == deviceIndex) break;
        count++;
    }

    // sanity
    if (count < 0 || dev == 0 || !isSuitable(dev)) {
        return ;
    }

    // populate instrument list
    InstrumentList list = dev->getPresentationInstruments();
    InstrumentList::iterator iit;

    const MidiMetronome *metronome = getMetronome(dev);

    // if we've got no metronome against this device then create one
    if (metronome == 0) {
        InstrumentId id = SystemInstrumentBase;

        for (iit = list.begin(); iit != list.end(); ++iit) {
            if ((*iit)->isPercussion()) {
                id = (*iit)->getId();
                break;
            }
        }

        setMetronome(dev, MidiMetronome(id));

        metronome = getMetronome(dev);
    }

    // metronome should now be set but we still check it
    if (metronome) {
        int position = 0;
        int count = 0;

        for (iit = list.begin(); iit != list.end(); ++iit) {

            QString iname(QObject::tr((*iit)->getName().c_str()));
            QString ipname((*iit)->getLocalizedPresentationName());
            QString pname(QObject::tr((*iit)->getProgramName().c_str()));

            QString text;

            if ((*iit)->getType() == Instrument::SoftSynth) {

                iname.replace(QObject::tr("Synth plugin "), "");
                pname = "";

                AudioPluginInstance *plugin = (*iit)->getPlugin
                    (Instrument::SYNTH_PLUGIN_POSITION);
                if (plugin) {
                    pname = strtoqstr(plugin->getProgram());
                    QString identifier = strtoqstr(plugin->getIdentifier());
                    if (identifier != "") {
                        QString type, soName, label;
                        PluginIdentifier::parseIdentifier
                            (identifier, type, soName, label);
                        if (pname == "") {
                            pname = strtoqstr(plugin->getDistinctiveConfigurationText());
                        }
                        if (pname != "") {
                            pname = QString("%1: %2").arg(label).arg(pname);
                        } else {
                            pname = label;
                        }
                    }
                }

            } else {

                iname = ipname;
            }

            if (pname != "") {
                text = tr("%1 (%2)").arg(iname).arg(pname);
            } else {
                text = iname;
            }

            m_metronomeInstrument->addItem(text);

            if ((*iit)->getId() == metronome->getInstrument()) {
                position = count;
            }
            count++;
        }
        m_metronomeInstrument->setCurrentIndex(position);

        m_barPitch = metronome->getBarPitch();
        m_beatPitch = metronome->getBeatPitch();
        m_subBeatPitch = metronome->getSubBeatPitch();
        slotPitchSelectorChanged(0);
        m_metronomeResolution->setCurrentIndex(metronome->getDepth());
        m_metronomeBarVely->setValue(metronome->getBarVelocity());
        m_metronomeBeatVely->setValue(metronome->getBeatVelocity());
        m_metronomeSubBeatVely->setValue(metronome->getSubBeatVelocity());
        m_playEnabled->setChecked(m_doc->getComposition().usePlayMetronome());
        m_recordEnabled->setChecked(m_doc->getComposition().useRecordMetronome());
        slotResolutionChanged(metronome->getDepth());
    }
}
void
AudioPluginOSCGUIManager::dispatch()
{
    if (!m_studio)
        return ;

    while (m_oscBuffer.getReadSpace() > 0) {

        OSCMessage *message = 0;
        m_oscBuffer.read(&message, 1);

        int instrument = message->getTarget();
        int position = message->getTargetData();

        PluginContainer *container = m_studio->getContainerById(instrument);
        if (!container) continue;

        AudioPluginInstance *pluginInstance = container->getPlugin(position);
        if (!pluginInstance) continue;

        AudioPluginOSCGUI *gui = 0;

        if (m_guis.find(instrument) == m_guis.end()) {
            RG_DEBUG << "AudioPluginOSCGUIManager: no GUI for instrument "
                     << instrument << endl;
        } else if (m_guis[instrument].find(position) == m_guis[instrument].end()) {
            RG_DEBUG << "AudioPluginOSCGUIManager: no GUI for instrument "
                     << instrument << ", position " << position << endl;
        } else {
            gui = m_guis[instrument][position];
        }

        std::string method = message->getMethod();

        char type;
        const lo_arg *arg;

        // These generally call back on the RosegardenMainWindow.  We'd
        // like to emit signals, but making AudioPluginOSCGUIManager a
        // QObject is problematic if it's only conditionally compiled.

        if (method == "control") {

            if (message->getArgCount() != 2) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for control method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 'i') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get port number"
                         << endl;
                goto done;
            }
            int port = arg->i;
            if (!(arg = message->getArg(1, type)) || type != 'f') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get port value"
                         << endl;
                goto done;
            }
            float value = arg->f;

            RG_DEBUG << "AudioPluginOSCGUIManager: setting port " << port
                     << " to value " << value << endl;

            m_mainWindow->slotChangePluginPort(instrument, position, port, value);

        } else if (method == "program") {

            if (message->getArgCount() != 2) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for program method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 'i') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get bank number"
                         << endl;
                goto done;
            }
            int bank = arg->i;
            if (!(arg = message->getArg(1, type)) || type != 'i') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get program number"
                         << endl;
                goto done;
            }
            int program = arg->i;

            QString programName = StudioControl::getPluginProgram
                                  (pluginInstance->getMappedId(), bank, program);

            m_mainWindow->slotChangePluginProgram(instrument, position, programName);

        } else if (method == "update") {

            if (message->getArgCount() != 1) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for update method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 's') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get GUI URL"
                         << endl;
                goto done;
            }
            QString url = &arg->s;

            if (!gui) {
                RG_DEBUG << "AudioPluginOSCGUIManager: no GUI for update method"
                         << endl;
                goto done;
            }

            gui->setGUIUrl(url);

            for (AudioPluginInstance::ConfigMap::const_iterator i =
                        pluginInstance->getConfiguration().begin();
                    i != pluginInstance->getConfiguration().end(); ++i) {

                QString key = strtoqstr(i->first);
                QString value = strtoqstr(i->second);

#ifdef DSSI_PROJECT_DIRECTORY_KEY

                if (key == PluginIdentifier::RESERVED_PROJECT_DIRECTORY_KEY) {
                    key = DSSI_PROJECT_DIRECTORY_KEY;
                }
#endif

                RG_DEBUG << "update: configuration: " << key << " -> "
                         << value << endl;

                gui->sendConfiguration(key, value);
            }

            unsigned long rv = StudioControl::getPluginProgram
                               (pluginInstance->getMappedId(), strtoqstr(pluginInstance->getProgram()));

            int bank = rv >> 16;
            int program = rv - (bank << 16);
            gui->sendProgram(bank, program);

            int controlCount = 0;
            for (PortInstanceIterator i = pluginInstance->begin();
                    i != pluginInstance->end(); ++i) {
                gui->sendPortValue((*i)->number, (*i)->value);
                /* Avoid overloading the GUI if there are lots and lots of ports */
                if (++controlCount % 50 == 0)
                    usleep(300000);
            }

            gui->show();

        } else if (method == "configure") {

            if (message->getArgCount() != 2) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for configure method"
                         << endl;
                goto done;
            }

            if (!(arg = message->getArg(0, type)) || type != 's') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get configure key"
                         << endl;
                goto done;
            }
            QString key = &arg->s;

            if (!(arg = message->getArg(1, type)) || type != 's') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get configure value"
                         << endl;
                goto done;
            }
            QString value = &arg->s;

#ifdef DSSI_RESERVED_CONFIGURE_PREFIX

            if (key.startsWith(DSSI_RESERVED_CONFIGURE_PREFIX) ||
                    key == PluginIdentifier::RESERVED_PROJECT_DIRECTORY_KEY) {
                RG_DEBUG << "AudioPluginOSCGUIManager: illegal reserved configure call from gui: " << key << " -> " << value;
                goto done;
            }
#endif

            RG_DEBUG << "AudioPluginOSCGUIManager: configure(" << key << "," << value
                     << ")" << endl;

            m_mainWindow->slotChangePluginConfiguration(instrument, position,
#ifdef DSSI_GLOBAL_CONFIGURE_PREFIX
                    key.startsWith(DSSI_GLOBAL_CONFIGURE_PREFIX),
#else
                    false,
#endif
                    key, value);

        } else if (method == "midi") {

            if (message->getArgCount() != 1) {
                RG_DEBUG << "AudioPluginOSCGUIManager: wrong number of args ("
                         << message->getArgCount() << ") for midi method"
                         << endl;
                goto done;
            }
            if (!(arg = message->getArg(0, type)) || type != 'm') {
                RG_DEBUG << "AudioPluginOSCGUIManager: failed to get MIDI event"
                         << endl;
                goto done;
            }

            RG_DEBUG << "AudioPluginOSCGUIManager: handling MIDI message";

            // let's only handle note on and note off

            int eventCode = arg->m[1];
            int eventType = eventCode & MIDI_MESSAGE_TYPE_MASK;
            if (eventType == MIDI_NOTE_ON ||
                    eventType == MIDI_NOTE_OFF) {
                MappedEvent ev(instrument,
                               MappedEvent::MidiNote,
                               MidiByte(arg->m[2]),
                               MidiByte(arg->m[3]),
                               RealTime::zeroTime,
                               RealTime::zeroTime,
                               RealTime::zeroTime);
                if (eventType == MIDI_NOTE_OFF)
                    ev.setVelocity(0);
                StudioControl::sendMappedEvent(ev);
            }

        } else if (method == "exiting") {

            RG_DEBUG << "AudioPluginOSCGUIManager: GUI exiting";
            stopGUI(instrument, position);
            m_mainWindow->slotPluginGUIExited(instrument, position);

        } else {

            RG_DEBUG << "AudioPluginOSCGUIManager: unknown method " << method;
        }

done:
        delete message;
    }