| 
							- /*
 -  * Carla Plugin bridge code
 -  * Copyright (C) 2012 Filipe Coelho <falktx@gmail.com>
 -  *
 -  * 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
 -  * any later version.
 -  *
 -  * This program is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 -  * GNU General Public License for more details.
 -  *
 -  * For a full copy of the GNU General Public License see the COPYING file
 -  */
 - 
 - #include "carla_bridge_osc.h"
 - #include "carla_bridge_client.h"
 - #include "carla_midi.h"
 - 
 - #include <QtCore/QString>
 - #include <QtCore/QStringList>
 - 
 - //CARLA_BRIDGE_START_NAMESPACE
 - namespace CarlaBridge {
 - 
 - CarlaBridgeOsc::CarlaBridgeOsc(CarlaBridgeClient* const client_, const char* const name) :
 -     client(client_)
 - {
 -     qDebug("CarlaBridgeOsc::CarlaBridgeOsc(%p, %s)", client_, name);
 -     assert(client_);
 -     assert(name);
 - 
 -     m_serverPath = nullptr;
 -     m_serverThread = nullptr;
 -     m_serverData.path = nullptr;
 -     m_serverData.source = nullptr;
 -     m_serverData.target = nullptr;
 - 
 -     m_name = strdup(name);
 -     m_name_len = strlen(name);
 - }
 - 
 - CarlaBridgeOsc::~CarlaBridgeOsc()
 - {
 -     qDebug("CarlaBridgeOsc::~CarlaBridgeOsc()");
 - 
 -     free((void*)m_name);
 - }
 - 
 - void CarlaBridgeOsc::init(const char* const url)
 - {
 -     qDebug("CarlaBridgeOsc::init(%s)", url);
 -     assert(url);
 - 
 -     const char* host = lo_url_get_hostname(url);
 -     const char* port = lo_url_get_port(url);
 - 
 -     m_serverData.path   = lo_url_get_path(url);
 -     m_serverData.target = lo_address_new(host, port);
 - 
 -     free((void*)host);
 -     free((void*)port);
 - 
 -     // create new OSC thread
 -     m_serverThread = lo_server_thread_new(nullptr, osc_error_handler);
 - 
 -     // get our full OSC server path
 -     char* const threadPath = lo_server_thread_get_url(m_serverThread);
 -     m_serverPath = strdup(QString("%1%2").arg(threadPath).arg(m_name).toUtf8().constData());
 -     free(threadPath);
 - 
 -     // register message handler and start OSC thread
 -     lo_server_thread_add_method(m_serverThread, nullptr, nullptr, osc_message_handler, this);
 -     lo_server_thread_start(m_serverThread);
 - }
 - 
 - void CarlaBridgeOsc::close()
 - {
 -     qDebug("CarlaBridgeOsc::close()");
 -     assert(client);
 - 
 -     osc_clear_data(&m_serverData);
 - 
 -     lo_server_thread_stop(m_serverThread);
 -     lo_server_thread_del_method(m_serverThread, nullptr, nullptr);
 -     lo_server_thread_free(m_serverThread);
 - 
 -     free((void*)m_serverPath);
 -     m_serverPath = nullptr;
 - }
 - 
 - int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
 - {
 -     qDebug("CarlaBridgeOsc::handleMessage(%s, %i, %p, %s, %p)", path, argc, argv, types, msg);
 -     assert(m_serverThread);
 -     assert(path);
 - 
 -     // Check if message is for this client
 -     if (strlen(path) <= m_name_len || strncmp(path+1, m_name, m_name_len) != 0)
 -     {
 -         qWarning("CarlaBridgeOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, m_name);
 -         return 1;
 -     }
 - 
 -     char method[32] = { 0 };
 -     memcpy(method, path + (m_name_len + 1), 32);
 - 
 -     // Common OSC methods
 -     if (strcmp(method, "/configure") == 0)
 -         return handle_configure(argc, argv, types);
 -     if (strcmp(method, "/control") == 0)
 -         return handle_control(argc, argv, types);
 -     if (strcmp(method, "/program") == 0)
 -         return handle_program(argc, argv, types);
 -     if (strcmp(method, "/midi_program") == 0)
 -         return handle_midi_program(argc, argv, types);
 -     if (strcmp(method, "/midi") == 0)
 -         return handle_midi(argc, argv, types);
 -     if (strcmp(method, "/show") == 0)
 -         return handle_show();
 -     if (strcmp(method, "/hide") == 0)
 -         return handle_hide();
 -     if (strcmp(method, "/quit") == 0)
 -         return handle_quit();
 - 
 -     // client specific methods
 - #if LV2_UI_GTK2 || LV2_UI_QT4 || LV2_UI_X11
 -     if (strcmp(method, "/lv2_atom_transfer") == 0)
 -         return handle_lv2_atom_transfer(argc, argv, types);
 -     if (strcmp(method, "/lv2_event_transfer") == 0)
 -         return handle_lv2_event_transfer(argc, argv, types);
 - #endif
 - 
 - #if 0
 -     else if (strcmp(method, "set_parameter_midi_channel") == 0)
 -         return osc_set_parameter_midi_channel_handler(argv);
 -     else if (strcmp(method, "set_parameter_midi_cc") == 0)
 -         return osc_set_parameter_midi_channel_handler(argv);
 - #endif
 -     else
 -         qWarning("Got unsupported OSC method '%s' on '%s'", method, path);
 - 
 -     return 1;
 - }
 - 
 - int CarlaBridgeOsc::handle_configure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
 - {
 -     qDebug("CarlaOsc::handle_configure()");
 -     CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");
 - 
 -     if (! client)
 -         return 1;
 - 
 - #ifdef BUILD_BRIDGE_PLUGIN
 -     const char* const key   = (const char*)&argv[0]->s;
 -     const char* const value = (const char*)&argv[1]->s;
 - 
 -     if (strcmp(key, CARLA_BRIDGE_MSG_SAVE_NOW) == 0)
 -     {
 -         client->quequeMessage(BRIDGE_MESSAGE_SAVE_NOW, 0, 0, 0.0);
 -     }
 -     else if (strcmp(key, CARLA_BRIDGE_MSG_SET_CHUNK) == 0)
 -     {
 -         client->setChunkData(value);
 -     }
 -     else if (strcmp(key, CARLA_BRIDGE_MSG_SET_CUSTOM) == 0)
 -     {
 -         QStringList vList = QString(value).split("ยท", QString::KeepEmptyParts);
 - 
 -         if (vList.size() == 3)
 -         {
 -             const char* const cType  = vList.at(0).toUtf8().constData();
 -             const char* const cKey   = vList.at(1).toUtf8().constData();
 -             const char* const cValue = vList.at(2).toUtf8().constData();
 - 
 -             client->set_custom_data(cType, cKey, cValue);
 -         }
 -     }
 - #else
 -     Q_UNUSED(argv);
 - #endif
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_control(CARLA_BRIDGE_OSC_HANDLE_ARGS)
 - {
 -     //qDebug("CarlaOsc::handle_control()");
 -     CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "if");
 - 
 -     if (! client)
 -         return 1;
 - 
 -     const int  rindex = argv[0]->i;
 -     const float value = argv[1]->f;
 -     client->quequeMessage(MESSAGE_PARAMETER, rindex, 0, value);
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
 - {
 -     qDebug("CarlaOsc::handle_program()");
 -     CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i");
 - 
 -     if (! client)
 -         return 1;
 - 
 -     const int index = argv[0]->i;
 -     client->quequeMessage(MESSAGE_PROGRAM, index, 0, 0.0);
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_midi_program(CARLA_BRIDGE_OSC_HANDLE_ARGS)
 - {
 -     qDebug("CarlaOsc::handle_program()");
 -     CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");
 - 
 -     if (! client)
 -         return 1;
 - 
 -     const int bank    = argv[0]->i;
 -     const int program = argv[1]->i;
 -     client->quequeMessage(MESSAGE_MIDI_PROGRAM, bank, program, 0.0);
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_midi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
 - {
 -     qDebug("CarlaOsc::handle_midi()");
 -     CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "m");
 - 
 -     if (! client)
 -         return 1;
 - 
 -     const uint8_t* const data = argv[0]->m;
 -     uint8_t status = data[1];
 - 
 -     // Fix bad note-off
 -     if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0)
 -         status -= 0x10;
 - 
 -     if (MIDI_IS_STATUS_NOTE_OFF(status))
 -     {
 -         uint8_t note = data[2];
 -         client->quequeMessage(MESSAGE_NOTE_OFF, note, 0, 0.0);
 -     }
 -     else if (MIDI_IS_STATUS_NOTE_ON(status))
 -     {
 -         uint8_t note = data[2];
 -         uint8_t velo = data[3];
 -         client->quequeMessage(MESSAGE_NOTE_ON, note, velo, 0.0);
 -     }
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_show()
 - {
 -     if (! client)
 -         return 1;
 - 
 -     client->quequeMessage(MESSAGE_SHOW_GUI, 1, 0, 0.0);
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_hide()
 - {
 -     if (! client)
 -         return 1;
 - 
 -     client->quequeMessage(MESSAGE_SHOW_GUI, 0, 0, 0.0);
 - 
 -     return 0;
 - }
 - 
 - int CarlaBridgeOsc::handle_quit()
 - {
 -     if (! client)
 -         return 1;
 - 
 -     client->quequeMessage(MESSAGE_QUIT, 0, 0, 0.0);
 - 
 -     return 0;
 - }
 - 
 - #ifdef BUILD_BRIDGE_PLUGIN
 - void osc_send_bridge_ains_peak(int index, double value)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+18];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_ains_peak");
 -         lo_send(global_osc_data.target, target_path, "if", index, value);
 -     }
 - }
 - 
 - void osc_send_bridge_aouts_peak(int index, double value)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+19];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_aouts_peak");
 -         lo_send(global_osc_data.target, target_path, "if", index, value);
 -     }
 - }
 - 
 - void osc_send_bridge_audio_count(int ins, int outs, int total)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+20];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_audio_count");
 -         lo_send(global_osc_data.target, target_path, "iii", ins, outs, total);
 -     }
 - }
 - 
 - void osc_send_bridge_midi_count(int ins, int outs, int total)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+19];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_midi_count");
 -         lo_send(global_osc_data.target, target_path, "iii", ins, outs, total);
 -     }
 - }
 - 
 - void osc_send_bridge_param_count(int ins, int outs, int total)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+20];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_param_count");
 -         lo_send(global_osc_data.target, target_path, "iii", ins, outs, total);
 -     }
 - }
 - 
 - void osc_send_bridge_program_count(int count)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+22];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_program_count");
 -         lo_send(global_osc_data.target, target_path, "i", count);
 -     }
 - }
 - 
 - void osc_send_bridge_midi_program_count(int count)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+27];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_midi_program_count");
 -         lo_send(global_osc_data.target, target_path, "i", count);
 -     }
 - }
 - 
 - void osc_send_bridge_plugin_info(int category, int hints, const char* name, const char* label, const char* maker, const char* copyright, long uniqueId)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+20];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_plugin_info");
 -         lo_send(global_osc_data.target, target_path, "iissssi", category, hints, name, label, maker, copyright, uniqueId);
 -         // FIXME - should be long type
 -     }
 - }
 - 
 - void osc_send_bridge_param_info(int index, const char* name, const char* unit)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+19];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_param_info");
 -         lo_send(global_osc_data.target, target_path, "iss", index, name, unit);
 -     }
 - }
 - 
 - void osc_send_bridge_param_data(int index, int type, int rindex, int hints, int midi_channel, int midi_cc)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+19];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_param_data");
 -         lo_send(global_osc_data.target, target_path, "iiiiii", index, type, rindex, hints, midi_channel, midi_cc);
 -     }
 - }
 - 
 - void osc_send_bridge_param_ranges(int index, double def, double min, double max, double step, double step_small, double step_large)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+21];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_param_ranges");
 -         lo_send(global_osc_data.target, target_path, "iffffff", index, def, min, max, step, step_small, step_large);
 -     }
 - }
 - 
 - void osc_send_bridge_program_info(int index, const char* name)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+21];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_program_info");
 -         lo_send(global_osc_data.target, target_path, "is", index, name);
 -     }
 - }
 - 
 - void osc_send_bridge_midi_program_info(int index, int bank, int program, const char* label)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+26];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_midi_program_info");
 -         lo_send(global_osc_data.target, target_path, "iiis", index, bank, program, label);
 -     }
 - }
 - 
 - void osc_send_bridge_custom_data(const char* stype, const char* key, const char* value)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+20];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_custom_data");
 -         lo_send(global_osc_data.target, target_path, "sss", stype, key, value);
 -     }
 - }
 - 
 - void osc_send_bridge_chunk_data(const char* string_data)
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+19];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_chunk_data");
 -         lo_send(global_osc_data.target, target_path, "s", string_data);
 -     }
 - }
 - 
 - void osc_send_bridge_update()
 - {
 -     if (global_osc_data.target)
 -     {
 -         char target_path[strlen(global_osc_data.path)+15];
 -         strcpy(target_path, global_osc_data.path);
 -         strcat(target_path, "/bridge_update");
 -         lo_send(global_osc_data.target, target_path, "");
 -     }
 - }
 - #endif
 - 
 - CARLA_BRIDGE_END_NAMESPACE
 
 
  |