You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
713 lines
23 KiB
713 lines
23 KiB
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
|
|
|
/*
|
|
Rosegarden
|
|
A MIDI and audio sequencer and musical notation editor.
|
|
|
|
This program is Copyright 2000-2008
|
|
Guillaume Laurent <glaurent@telegraph-road.org>,
|
|
Chris Cannam <cannam@all-day-breakfast.com>,
|
|
Richard Bown <richard.bown@ferventsoftware.com>
|
|
|
|
The moral rights of Guillaume Laurent, Chris Cannam, and Richard
|
|
Bown to claim authorship of this work have been asserted.
|
|
|
|
Other copyrights also apply to some parts of this work. Please
|
|
see the AUTHORS file and individual file headers for details.
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of the
|
|
License, or (at your option) any later version. See the file
|
|
COPYING included with this distribution for more information.
|
|
*/
|
|
|
|
#ifdef HAVE_LIBLO
|
|
|
|
#include <lo/lo.h>
|
|
#include <unistd.h>
|
|
|
|
#include "AudioPluginOSCGUIManager.h"
|
|
|
|
#include "sound/Midi.h"
|
|
#include <tdelocale.h>
|
|
#include "misc/Debug.h"
|
|
#include "misc/Strings.h"
|
|
#include "AudioPluginOSCGUI.h"
|
|
#include "base/AudioPluginInstance.h"
|
|
#include "base/Exception.h"
|
|
#include "base/Instrument.h"
|
|
#include "base/MidiProgram.h"
|
|
#include "base/RealTime.h"
|
|
#include "base/Studio.h"
|
|
#include "gui/application/RosegardenGUIApp.h"
|
|
#include "OSCMessage.h"
|
|
#include "sound/MappedEvent.h"
|
|
#include "sound/PluginIdentifier.h"
|
|
#include "StudioControl.h"
|
|
#include "TimerCallbackAssistant.h"
|
|
#include <tqstring.h>
|
|
|
|
|
|
namespace Rosegarden
|
|
{
|
|
|
|
static void osc_error(int num, const char *msg, const char *path)
|
|
{
|
|
std::cerr << "Rosegarden: ERROR: liblo server error " << num
|
|
<< " in path " << path << ": " << msg << std::endl;
|
|
}
|
|
|
|
static int osc_message_handler(const char *path, const char *types, lo_arg **argv,
|
|
int argc, lo_message, void *user_data)
|
|
{
|
|
AudioPluginOSCGUIManager *manager = (AudioPluginOSCGUIManager *)user_data;
|
|
|
|
InstrumentId instrument;
|
|
int position;
|
|
TQString method;
|
|
|
|
if (!manager->parseOSCPath(path, instrument, position, method)) {
|
|
return 1;
|
|
}
|
|
|
|
OSCMessage *message = new OSCMessage();
|
|
message->setTarget(instrument);
|
|
message->setTargetData(position);
|
|
message->setMethod(qstrtostr(method));
|
|
|
|
int arg = 0;
|
|
while (types && arg < argc && types[arg]) {
|
|
message->addArg(types[arg], argv[arg]);
|
|
++arg;
|
|
}
|
|
|
|
manager->postMessage(message);
|
|
return 0;
|
|
}
|
|
|
|
AudioPluginOSCGUIManager::AudioPluginOSCGUIManager(RosegardenGUIApp *app) :
|
|
m_app(app),
|
|
m_studio(0),
|
|
m_haveOSCThread(false),
|
|
m_oscBuffer(1023),
|
|
m_dispatchTimer(0)
|
|
{}
|
|
|
|
AudioPluginOSCGUIManager::~AudioPluginOSCGUIManager()
|
|
{
|
|
delete m_dispatchTimer;
|
|
|
|
for (TargetGUIMap::iterator i = m_guis.begin(); i != m_guis.end(); ++i) {
|
|
for (IntGUIMap::iterator j = i->second.begin(); j != i->second.end();
|
|
++j) {
|
|
delete j->second;
|
|
}
|
|
}
|
|
m_guis.clear();
|
|
|
|
#ifdef HAVE_LIBLO_THREADSTOP
|
|
|
|
if (m_haveOSCThread)
|
|
lo_server_thread_stop(m_serverThread);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::checkOSCThread()
|
|
{
|
|
if (m_haveOSCThread)
|
|
return ;
|
|
|
|
m_serverThread = lo_server_thread_new(NULL, osc_error);
|
|
|
|
lo_server_thread_add_method(m_serverThread, NULL, NULL,
|
|
osc_message_handler, this);
|
|
|
|
lo_server_thread_start(m_serverThread);
|
|
|
|
RG_DEBUG << "AudioPluginOSCGUIManager: Base OSC URL is "
|
|
<< lo_server_thread_get_url(m_serverThread) << endl;
|
|
|
|
m_dispatchTimer = new TimerCallbackAssistant(20, timerCallback, this);
|
|
|
|
m_haveOSCThread = true;
|
|
}
|
|
|
|
bool
|
|
AudioPluginOSCGUIManager::hasGUI(InstrumentId instrument, int position)
|
|
{
|
|
PluginContainer *container = 0;
|
|
container = m_studio->getContainerById(instrument);
|
|
if (!container) return false;
|
|
|
|
AudioPluginInstance *pluginInstance = container->getPlugin(position);
|
|
if (!pluginInstance) return false;
|
|
|
|
try {
|
|
TQString filePath = AudioPluginOSCGUI::getGUIFilePath
|
|
(strtoqstr(pluginInstance->getIdentifier()));
|
|
return (!filePath.isNull() && filePath != "");
|
|
} catch (Exception e) { // that's OK
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::startGUI(InstrumentId instrument, int position)
|
|
{
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: " << instrument << "," << position
|
|
<< endl;
|
|
|
|
checkOSCThread();
|
|
|
|
if (m_guis.find(instrument) != m_guis.end() &&
|
|
m_guis[instrument].find(position) != m_guis[instrument].end()) {
|
|
RG_DEBUG << "stopping GUI first" << endl;
|
|
stopGUI(instrument, position);
|
|
}
|
|
|
|
// check the label
|
|
PluginContainer *container = 0;
|
|
container = m_studio->getContainerById(instrument);
|
|
if (!container) {
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: no such instrument or buss as "
|
|
<< instrument << endl;
|
|
return;
|
|
}
|
|
|
|
AudioPluginInstance *pluginInstance = container->getPlugin(position);
|
|
if (!pluginInstance) {
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: no plugin at position "
|
|
<< position << " for instrument " << instrument << endl;
|
|
return ;
|
|
}
|
|
|
|
try {
|
|
AudioPluginOSCGUI *gui =
|
|
new AudioPluginOSCGUI(pluginInstance,
|
|
getOSCUrl(instrument,
|
|
position,
|
|
strtoqstr(pluginInstance->getIdentifier())),
|
|
getFriendlyName(instrument,
|
|
position,
|
|
strtoqstr(pluginInstance->getIdentifier())));
|
|
m_guis[instrument][position] = gui;
|
|
|
|
} catch (Exception e) {
|
|
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::startGUI: failed to start GUI: "
|
|
<< e.getMessage() << endl;
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::showGUI(InstrumentId instrument, int position)
|
|
{
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::showGUI: " << instrument << "," << position
|
|
<< endl;
|
|
|
|
if (m_guis.find(instrument) != m_guis.end() &&
|
|
m_guis[instrument].find(position) != m_guis[instrument].end()) {
|
|
m_guis[instrument][position]->show();
|
|
} else {
|
|
startGUI(instrument, position);
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::stopGUI(InstrumentId instrument, int position)
|
|
{
|
|
if (m_guis.find(instrument) != m_guis.end() &&
|
|
m_guis[instrument].find(position) != m_guis[instrument].end()) {
|
|
delete m_guis[instrument][position];
|
|
m_guis[instrument].erase(position);
|
|
if (m_guis[instrument].empty())
|
|
m_guis.erase(instrument);
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::stopAllGUIs()
|
|
{
|
|
while (!m_guis.empty()) {
|
|
while (!m_guis.begin()->second.empty()) {
|
|
delete (m_guis.begin()->second.begin()->second);
|
|
m_guis.begin()->second.erase(m_guis.begin()->second.begin());
|
|
}
|
|
m_guis.erase(m_guis.begin());
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::postMessage(OSCMessage *message)
|
|
{
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::postMessage" << endl;
|
|
m_oscBuffer.write(&message, 1);
|
|
}
|
|
|
|
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::updatePort(InstrumentId instrument, int position,
|
|
int port)
|
|
{
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::updatePort(" << instrument << ","
|
|
<< position << "," << port << ")" << 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 ;
|
|
|
|
PluginPortInstance *porti = pluginInstance->getPort(port);
|
|
if (!porti)
|
|
return ;
|
|
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::updatePort(" << instrument << ","
|
|
<< position << "," << port << "): value " << porti->value << endl;
|
|
|
|
m_guis[instrument][position]->sendPortValue(port, porti->value);
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::updateConfiguration(InstrumentId instrument, int position,
|
|
TQString key)
|
|
{
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::updateConfiguration(" << instrument << ","
|
|
<< position << "," << key << ")" << endl;
|
|
|
|
if (m_guis.find(instrument) == m_guis.end() ||
|
|
m_guis[instrument].find(position) == m_guis[instrument].end())
|
|
return ;
|
|
|
|
PluginContainer *container = m_studio->getContainerById(instrument);
|
|
if (!container) return;
|
|
|
|
AudioPluginInstance *pluginInstance = container->getPlugin(position);
|
|
if (!pluginInstance) return;
|
|
|
|
TQString value = strtoqstr(pluginInstance->getConfigurationValue(qstrtostr(key)));
|
|
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::updatePort(" << instrument << ","
|
|
<< position << "," << key << "): value " << value << endl;
|
|
|
|
m_guis[instrument][position]->sendConfiguration(key, value);
|
|
}
|
|
|
|
TQString
|
|
AudioPluginOSCGUIManager::getOSCUrl(InstrumentId instrument, int position,
|
|
TQString identifier)
|
|
{
|
|
// OSC URL will be of the form
|
|
// osc.udp://localhost:54343/plugin/dssi/<instrument>/<position>/<label>
|
|
// where <position> will be "synth" for synth plugins
|
|
|
|
TQString type, soName, label;
|
|
PluginIdentifier::parseIdentifier(identifier, type, soName, label);
|
|
|
|
TQString baseUrl = lo_server_thread_get_url(m_serverThread);
|
|
if (!baseUrl.endsWith("/"))
|
|
baseUrl += '/';
|
|
|
|
TQString url = TQString("%1%2/%3/%4/%5/%6")
|
|
.arg(baseUrl)
|
|
.arg("plugin")
|
|
.arg(type)
|
|
.arg(instrument);
|
|
|
|
if (position == int(Instrument::SYNTH_PLUGIN_POSITION)) {
|
|
url = url.arg("synth");
|
|
} else {
|
|
url = url.arg(position);
|
|
}
|
|
|
|
url = url.arg(label);
|
|
|
|
return url;
|
|
}
|
|
|
|
bool
|
|
AudioPluginOSCGUIManager::parseOSCPath(TQString path, InstrumentId &instrument,
|
|
int &position, TQString &method)
|
|
{
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath(" << path << ")" << endl;
|
|
if (!m_studio)
|
|
return false;
|
|
|
|
TQString 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());
|
|
|
|
TQString type = path.section('/', 0, 0);
|
|
TQString instrumentStr = path.section('/', 1, 1);
|
|
TQString positionStr = path.section('/', 2, 2);
|
|
TQString label = path.section('/', 3, -2);
|
|
method = path.section('/', -1, -1);
|
|
|
|
if (!instrumentStr || !positionStr) {
|
|
RG_DEBUG << "AudioPluginOSCGUIManager::parseOSCPath: no instrument or position in " << path << endl;
|
|
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;
|
|
}
|
|
|
|
TQString identifier = strtoqstr(pluginInstance->getIdentifier());
|
|
TQString 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;
|
|
}
|
|
|
|
TQString
|
|
AudioPluginOSCGUIManager::getFriendlyName(InstrumentId instrument, int position,
|
|
TQString)
|
|
{
|
|
PluginContainer *container = m_studio->getContainerById(instrument);
|
|
if (!container)
|
|
return i18n("Rosegarden Plugin");
|
|
else {
|
|
if (position == int(Instrument::SYNTH_PLUGIN_POSITION)) {
|
|
return i18n("Rosegarden: %1").arg(strtoqstr(container->getPresentationName()));
|
|
} else {
|
|
return i18n("Rosegarden: %1: %2").arg(strtoqstr(container->getPresentationName()))
|
|
.arg(i18n("Plugin slot %1").arg(position));
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
AudioPluginOSCGUIManager::timerCallback(void *data)
|
|
{
|
|
AudioPluginOSCGUIManager *manager = (AudioPluginOSCGUIManager *)data;
|
|
manager->dispatch();
|
|
}
|
|
|
|
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 RosegardenGUIApp. We'd
|
|
// like to emit signals, but making AudioPluginOSCGUIManager a
|
|
// TQObject 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_app->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;
|
|
|
|
TQString programName = StudioControl::getPluginProgram
|
|
(pluginInstance->getMappedId(), bank, program);
|
|
|
|
m_app->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;
|
|
}
|
|
TQString 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) {
|
|
|
|
TQString key = strtoqstr(i->first);
|
|
TQString 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;
|
|
}
|
|
TQString key = &arg->s;
|
|
|
|
if (!(arg = message->getArg(1, type)) || type != 's') {
|
|
RG_DEBUG << "AudioPluginOSCGUIManager: failed to get configure value"
|
|
<< endl;
|
|
goto done;
|
|
}
|
|
TQString 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 << endl;
|
|
goto done;
|
|
}
|
|
#endif
|
|
|
|
RG_DEBUG << "AudioPluginOSCGUIManager: configure(" << key << "," << value
|
|
<< ")" << endl;
|
|
|
|
m_app->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" << endl;
|
|
|
|
// 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" << endl;
|
|
stopGUI(instrument, position);
|
|
m_app->slotPluginGUIExited(instrument, position);
|
|
|
|
} else {
|
|
|
|
RG_DEBUG << "AudioPluginOSCGUIManager: unknown method " << method << endl;
|
|
}
|
|
|
|
done:
|
|
delete message;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|