Пример #1
0
void
OSCQueue::postMessage(OSCMessage message)
{
    int count = 0, max = 5;
    while (m_buffer.getWriteSpace() == 0) {
        if (count == max) {
            std::cerr << "ERROR: OSCQueue::postMessage: OSC message queue is full and not clearing -- abandoning incoming message" << std::endl;
            return;
        }
        std::cerr << "WARNING: OSCQueue::postMessage: OSC message queue (capacity " << m_buffer.getSize() << " is full!" << std::endl;
        std::cerr << "Waiting for something to be processed" << std::endl;
#ifdef _WIN32
        Sleep(1);
#else
        sleep(1);
#endif
        count++;
    }

    OSCMessage *mp = new OSCMessage(message);
    m_buffer.write(&mp, 1);
    std::cerr << "OSCQueue::postMessage: Posted OSC message: target "
              << message.getTarget() << ", target data " << message.getTargetData()
              << ", method " << message.getMethod().toStdString() << std::endl;
    emit messagesAvailable();
}
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;
    }