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); }
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; }
bool AudioPluginOSCGUIManager::parseOSCPath(QString path, InstrumentId &instrument, int &position, QString &method) { RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath(" << path << ")"; if (!m_studio) return false; QString pluginStr("/plugin/"); if (path.startsWith("//")) { path = path.right(path.length() - 1); } if (!path.startsWith(pluginStr)) { RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: malformed path " << path << endl; return false; } path = path.right(path.length() - pluginStr.length()); QString type = path.section('/', 0, 0); QString instrumentStr = path.section('/', 1, 1); QString positionStr = path.section('/', 2, 2); QString label = path.section('/', 3, -2); method = path.section('/', -1, -1); if (instrumentStr.isEmpty() || positionStr.isEmpty() ) { RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no instrument or position in " << path; return false; } instrument = instrumentStr.toUInt(); if (positionStr == "synth") { position = Instrument::SYNTH_PLUGIN_POSITION; } else { position = positionStr.toInt(); } // check the label PluginContainer *container = m_studio->getContainerById(instrument); if (!container) { RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no such instrument or buss as " << instrument << " in path " << path << endl; return false; } AudioPluginInstance *pluginInstance = container->getPlugin(position); if (!pluginInstance) { RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no plugin at position " << position << " for instrument " << instrument << " in path " << path << endl; return false; } QString identifier = strtoqstr(pluginInstance->getIdentifier()); QString iType, iSoName, iLabel; PluginIdentifier::parseIdentifier(identifier, iType, iSoName, iLabel); if (iLabel != label) { RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: wrong label for plugin" << " at position " << position << " for instrument " << instrument << " in path " << path << " (actual label is " << iLabel << ")" << endl; return false; } RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: good path " << path << ", got mapped id " << pluginInstance->getMappedId() << endl; return true; }