Browse Source

Merge all bridge-plugin client code into a single file, cleanup

tags/1.9.4
falkTX 11 years ago
parent
commit
8811e8d9a8
7 changed files with 101 additions and 1047 deletions
  1. +0
    -35
      source/bridges-plugin/CarlaBridge.hpp
  2. +0
    -294
      source/bridges-plugin/CarlaBridgeClient.cpp
  3. +0
    -167
      source/bridges-plugin/CarlaBridgeClient.hpp
  4. +0
    -319
      source/bridges-plugin/CarlaBridgeOsc.cpp
  5. +0
    -131
      source/bridges-plugin/CarlaBridgeOsc.hpp
  6. +94
    -86
      source/bridges-plugin/CarlaBridgePlugin.cpp
  7. +7
    -15
      source/bridges-plugin/Makefile

+ 0
- 35
source/bridges-plugin/CarlaBridge.hpp View File

@@ -1,35 +0,0 @@
/*
* Carla Bridge
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.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 doc/GPL.txt file.
*/

#ifndef CARLA_BRIDGE_HPP_INCLUDED
#define CARLA_BRIDGE_HPP_INCLUDED

#include "CarlaDefines.h"

#define CARLA_BRIDGE_START_NAMESPACE namespace CarlaBridge {
#define CARLA_BRIDGE_END_NAMESPACE }
#define CARLA_BRIDGE_USE_NAMESPACE using namespace CarlaBridge;

CARLA_BRIDGE_START_NAMESPACE

// forward declarations of commonly used Carla-Bridge classes
class CarlaBridgeClient;
class CarlaBridgeToolkit;

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_HPP_INCLUDED

+ 0
- 294
source/bridges-plugin/CarlaBridgeClient.cpp View File

@@ -1,294 +0,0 @@
/*
* Carla Bridge Client
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.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 doc/GPL.txt file.
*/

#include "CarlaBridgeClient.hpp"

#ifdef BUILD_BRIDGE_UI
# include "CarlaLibUtils.hpp"
#endif

CARLA_BRIDGE_START_NAMESPACE

// ---------------------------------------------------------------------

CarlaBridgeClient::CarlaBridgeClient(const char* const uiTitle)
: fOsc(this),
fOscData(fOsc.getControlData())
#ifdef BUILD_BRIDGE_UI
, fUI(CarlaBridgeToolkit::createNew(this, uiTitle))
#endif
{
#ifdef BUILD_BRIDGE_UI
CARLA_ASSERT(uiTitle != nullptr && uiTitle[0] != '\0');
#endif
carla_debug("CarlaBridgeClient::CarlaBridgeClient(\"%s\")", uiTitle);

#ifndef BUILD_BRIDGE_UI
return; (void)uiTitle; // unused
#endif
}

CarlaBridgeClient::~CarlaBridgeClient()
{
carla_debug("CarlaBridgeClient::~CarlaBridgeClient()");
}

#ifdef BUILD_BRIDGE_UI
// ---------------------------------------------------------------------
// ui initialization

bool CarlaBridgeClient::uiInit(const char* const, const char* const)
{
carla_debug("CarlaBridgeClient::uiInit()");

fUI.init();

return true;
}

void CarlaBridgeClient::uiClose()
{
carla_debug("CarlaBridgeClient::uiClose()");

if (isOscControlRegistered() && ! fUI.quit)
sendOscExiting();

fUI.close();
}

// ---------------------------------------------------------------------
// ui toolkit

void CarlaBridgeClient::toolkitShow()
{
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,);
carla_debug("CarlaBridgeClient::toolkitShow()");

fUI.toolkit->show();
}

void CarlaBridgeClient::toolkitHide()
{
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,);
carla_debug("CarlaBridgeClient::toolkitHide()");

fUI.toolkit->hide();
}

void CarlaBridgeClient::toolkitResize(const int width, const int height)
{
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,);
carla_debug("CarlaBridgeClient::toolkitResize(%i, %i)", width, height);

fUI.toolkit->resize(width, height);
}

void CarlaBridgeClient::toolkitExec(const bool showGui)
{
CARLA_SAFE_ASSERT_RETURN(fUI.toolkit != nullptr,);
carla_debug("CarlaBridgeClient::toolkitExec(%s)", bool2str(showGui));

fUI.toolkit->exec(showGui);
}

void CarlaBridgeClient::toolkitQuit()
{
carla_debug("CarlaBridgeClient::toolkitQuit()");

fUI.close();
}
#endif

// ---------------------------------------------------------------------
// osc stuff

void CarlaBridgeClient::oscInit(const char* const url)
{
carla_debug("CarlaBridgeClient::oscInit(\"%s\")", url);

fOsc.init(url);
}

bool CarlaBridgeClient::oscIdle() const
{
fOsc.idle();

#ifdef BUILD_BRIDGE_UI
return ! fUI.quit;
#else
return true;
#endif
}

void CarlaBridgeClient::oscClose()
{
carla_debug("CarlaBridgeClient::oscClose()");

fOsc.close();
}

bool CarlaBridgeClient::isOscControlRegistered() const noexcept
{
return fOsc.isControlRegistered();
}

void CarlaBridgeClient::sendOscUpdate() const
{
carla_debug("CarlaBridgeClient::sendOscUpdate()");

if (fOscData.target != nullptr)
osc_send_update(fOscData, fOsc.getServerPath());
}

// ---------------------------------------------------------------------

#ifdef BUILD_BRIDGE_PLUGIN
void CarlaBridgeClient::sendOscBridgeUpdate() const
{
carla_debug("CarlaBridgeClient::sendOscBridgeUpdate()");

if (fOscData.target != nullptr)
osc_send_bridge_update(fOscData, fOscData.path);
}

void CarlaBridgeClient::sendOscBridgeError(const char* const error) const
{
carla_debug("CarlaBridgeClient::sendOscBridgeError(\"%s\")", error);

if (fOscData.target != nullptr)
osc_send_bridge_error(fOscData, error);
}
#endif

// ---------------------------------------------------------------------

#ifdef BUILD_BRIDGE_UI
void CarlaBridgeClient::sendOscConfigure(const char* const key, const char* const value) const
{
carla_debug("CarlaBridgeClient::sendOscConfigure(\"%s\", \"%s\")", key, value);

if (fOscData.target != nullptr)
osc_send_configure(fOscData, key, value);
}

void CarlaBridgeClient::sendOscControl(const int32_t index, const float value) const
{
carla_debug("CarlaBridgeClient::sendOscControl(%i, %f)", index, value);

if (fOscData.target != nullptr)
osc_send_control(fOscData, index, value);
}

void CarlaBridgeClient::sendOscProgram(const uint32_t index) const
{
carla_debug("CarlaBridgeClient::sendOscProgram(%i)", index);

if (fOscData.target != nullptr)
osc_send_program(fOscData, index);
}

void CarlaBridgeClient::sendOscMidiProgram(const uint32_t index) const
{
carla_debug("CarlaBridgeClient::sendOscMidiProgram(%i)", index);

if (fOscData.target != nullptr)
osc_send_midi_program(fOscData, index);
}

void CarlaBridgeClient::sendOscMidi(const uint8_t midiBuf[4]) const
{
carla_debug("CarlaBridgeClient::sendOscMidi(%p)", midiBuf);

if (fOscData.target != nullptr)
osc_send_midi(fOscData, midiBuf);
}

void CarlaBridgeClient::sendOscExiting() const
{
carla_debug("CarlaBridgeClient::sendOscExiting()");

if (fOscData.target != nullptr)
osc_send_exiting(fOscData);
}

#ifdef BRIDGE_LV2
void CarlaBridgeClient::sendOscLv2AtomTransfer(const int32_t portIndex, const char* const atomBuf) const
{
carla_debug("CarlaBridgeClient::sendOscLv2TransferAtom(%i, \"%s\")", portIndex, atomBuf);

if (fOscData.target != nullptr)
osc_send_lv2_atom_transfer(fOscData, portIndex, atomBuf);
}

void CarlaBridgeClient::sendOscLv2UridMap(const uint32_t urid, const char* const uri) const
{
carla_debug("CarlaBridgeClient::sendOscLv2UridMap(%i, \"%s\")", urid, uri);

if (fOscData.target != nullptr)
osc_send_lv2_urid_map(fOscData, urid, uri);
}
#endif

// ---------------------------------------------------------------------

void* CarlaBridgeClient::getContainerId()
{
carla_debug("CarlaBridgeClient::getContainerId()");
return fUI.toolkit->getContainerId();
}

bool CarlaBridgeClient::uiLibOpen(const char* const filename)
{
CARLA_ASSERT(fUI.lib == nullptr);
CARLA_ASSERT(filename != nullptr);
carla_debug("CarlaBridgeClient::uiLibOpen(\"%s\")", filename);

fUI.lib = lib_open(filename);
fUI.filename = filename;

return (fUI.lib != nullptr);
}

bool CarlaBridgeClient::uiLibClose()
{
CARLA_SAFE_ASSERT_RETURN(fUI.lib != nullptr, false);
carla_debug("CarlaBridgeClient::uiLibClose()");

const bool closed = lib_close(fUI.lib);
fUI.lib = nullptr;
return closed;
}

void* CarlaBridgeClient::uiLibSymbol(const char* const symbol)
{
CARLA_SAFE_ASSERT_RETURN(fUI.lib != nullptr, nullptr);
carla_debug("CarlaBridgeClient::uiLibSymbol(\"%s\")", symbol);

return lib_symbol(fUI.lib, symbol);
}

const char* CarlaBridgeClient::uiLibError()
{
carla_debug("CarlaBridgeClient::uiLibError()");

return lib_error(fUI.filename);
}
#endif // BUILD_BRIDGE_UI

// ---------------------------------------------------------------------

CARLA_BRIDGE_END_NAMESPACE

+ 0
- 167
source/bridges-plugin/CarlaBridgeClient.hpp View File

@@ -1,167 +0,0 @@
/*
* Carla Bridge Client
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.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 doc/GPL.txt file.
*/

#ifndef CARLA_BRIDGE_CLIENT_HPP_INCLUDED
#define CARLA_BRIDGE_CLIENT_HPP_INCLUDED

#include "CarlaBridgeOsc.hpp"

#ifdef BUILD_BRIDGE_UI
# include "CarlaBridgeToolkit.hpp"
#endif

CARLA_BRIDGE_START_NAMESPACE

// -----------------------------------------------------------------------

class CarlaBridgeClient
{
public:
CarlaBridgeClient(const char* const uiTitle);
virtual ~CarlaBridgeClient();

#ifdef BUILD_BRIDGE_UI
// ---------------------------------------------------------------------
// ui initialization

virtual bool uiInit(const char* const, const char* const);
virtual void uiIdle() {}
virtual void uiClose();

// ---------------------------------------------------------------------
// ui management

virtual void* getWidget() const = 0;
virtual bool isResizable() const = 0;
virtual bool needsReparent() const = 0;

// ---------------------------------------------------------------------
// ui processing

virtual void setParameter(const int32_t rindex, const float value) = 0;
virtual void setProgram(const uint32_t index) = 0;
virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0;
virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0;
virtual void noteOff(const uint8_t channel, const uint8_t note) = 0;

// ---------------------------------------------------------------------
// ui toolkit

void toolkitShow();
void toolkitHide();
void toolkitResize(const int width, const int height);
void toolkitExec(const bool showGui);
void toolkitQuit();
#endif

// ---------------------------------------------------------------------
// osc stuff

void oscInit(const char* const url);
bool oscIdle() const;
void oscClose();

bool isOscControlRegistered() const noexcept;
void sendOscUpdate() const;

#ifdef BUILD_BRIDGE_PLUGIN
void sendOscBridgeUpdate() const;
void sendOscBridgeError(const char* const error) const;
#endif

// ---------------------------------------------------------------------

protected:
#ifdef BUILD_BRIDGE_UI
void sendOscConfigure(const char* const key, const char* const value) const;
void sendOscControl(const int32_t index, const float value) const;
void sendOscProgram(const uint32_t index) const;
void sendOscMidiProgram(const uint32_t index) const;
void sendOscMidi(const uint8_t midiBuf[4]) const;
void sendOscExiting() const;

# ifdef BRIDGE_LV2
void sendOscLv2AtomTransfer(const int32_t portIndex, const char* const atomBuf) const;
void sendOscLv2UridMap(const uint32_t urid, const char* const uri) const;
# endif

// ---------------------------------------------------------------------

void* getContainerId();
bool uiLibOpen(const char* const filename);
bool uiLibClose();
void* uiLibSymbol(const char* const symbol);
const char* uiLibError();
#endif

// ---------------------------------------------------------------------

private:
CarlaBridgeOsc fOsc;
const CarlaOscData& fOscData;

#ifdef BUILD_BRIDGE_UI
struct UI {
CarlaBridgeToolkit* const toolkit;
CarlaString filename;
void* lib;
bool quit;

UI(CarlaBridgeToolkit* const toolkit_)
: toolkit(toolkit_),
lib(nullptr),
quit(false)
{
CARLA_ASSERT(toolkit != nullptr);
}

~UI()
{
delete toolkit;
}

void init()
{
toolkit->init();
quit = false;
}

void close()
{
quit = true;
toolkit->quit();
}

# ifdef CARLA_PROPER_CPP11_SUPPORT
UI() = delete;
UI(UI&) = delete;
UI(const UI&) = delete;
# endif

} fUI;
#else
friend class CarlaPluginClient;
#endif

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeClient)
};

// -----------------------------------------------------------------------

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_CLIENT_HPP_INCLUDED

+ 0
- 319
source/bridges-plugin/CarlaBridgeOsc.cpp View File

@@ -1,319 +0,0 @@
/*
* Carla Bridge OSC
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.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 doc/GPL.txt file.
*/

#include "CarlaBridgeClient.hpp"
#include "CarlaMIDI.h"

CARLA_BRIDGE_START_NAMESPACE

// -----------------------------------------------------------------------

CarlaBridgeOsc::CarlaBridgeOsc(CarlaBridgeClient* const client)
: fClient(client),
fServer(nullptr)
{
CARLA_ASSERT(client != nullptr);
carla_debug("CarlaBridgeOsc::CarlaBridgeOsc(%p)", client);
}

CarlaBridgeOsc::~CarlaBridgeOsc()
{
CARLA_ASSERT(fControlData.source == nullptr); // must never be used
CARLA_ASSERT(fName.isEmpty());
CARLA_ASSERT(fServerPath.isEmpty());
CARLA_ASSERT(fServer == nullptr);
carla_debug("CarlaBridgeOsc::~CarlaBridgeOsc()");
}

void CarlaBridgeOsc::init(const char* const url)
{
CARLA_ASSERT(fName.isEmpty());
CARLA_ASSERT(fServerPath.isEmpty());
CARLA_ASSERT(fServer == nullptr);
CARLA_ASSERT(url != nullptr);
carla_debug("CarlaBridgeOsc::init(\"%s\")", url);

std::srand((uint)(uintptr_t)this);
std::srand((uint)(uintptr_t)&url);

#ifdef BUILD_BRIDGE_PLUGIN
fName = "plug-";
fName += CarlaString(std::rand() % 99999);
#else
fName = "ui-";
fName += CarlaString(std::rand() % 99999);
#endif

fServer = lo_server_new_with_proto(nullptr, LO_UDP, osc_error_handler);

CARLA_SAFE_ASSERT_RETURN(fServer != nullptr,)

{
char* const host = lo_url_get_hostname(url);
char* const port = lo_url_get_port(url);
fControlData.path = carla_strdup_free(lo_url_get_path(url));
fControlData.target = lo_address_new_with_proto(LO_UDP, host, port);

std::free(host);
std::free(port);
}

if (char* const tmpServerPath = lo_server_get_url(fServer))
{
fServerPath = tmpServerPath;
fServerPath += fName;
std::free(tmpServerPath);
}

#ifdef BUILD_BRIDGE_UI
lo_server_add_method(fServer, nullptr, nullptr, osc_message_handler, this);
#endif

CARLA_ASSERT(fName.isNotEmpty());
CARLA_ASSERT(fServerPath.isNotEmpty());
}

void CarlaBridgeOsc::idle() const
{
if (fServer == nullptr)
return;

for (; lo_server_recv_noblock(fServer, 0) != 0;) {}
}

void CarlaBridgeOsc::close()
{
CARLA_ASSERT(fControlData.source == nullptr); // must never be used
CARLA_ASSERT(fName.isNotEmpty());
CARLA_ASSERT(fServerPath.isNotEmpty());
CARLA_ASSERT(fServer != nullptr);
carla_debug("CarlaBridgeOsc::close()");

fName.clear();

if (fServer != nullptr)
{
lo_server_del_method(fServer, nullptr, nullptr);
lo_server_free(fServer);
fServer = nullptr;
}

fServerPath.clear();
fControlData.clear();

CARLA_ASSERT(fName.isEmpty());
CARLA_ASSERT(fServerPath.isEmpty());
CARLA_ASSERT(fServer == nullptr);
}

#ifdef BUILD_BRIDGE_UI
// -----------------------------------------------------------------------

int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg)
{
CARLA_SAFE_ASSERT_RETURN(fName.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(fServerPath.isNotEmpty(), 1);
CARLA_SAFE_ASSERT_RETURN(fServer != nullptr, 1);
CARLA_SAFE_ASSERT_RETURN(path != nullptr, 1);
CARLA_SAFE_ASSERT_RETURN(msg != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMessage(\"%s\", %i, %p, \"%s\", %p)", path, argc, argv, types, msg);

const size_t nameSize(fName.length());

// Check if message is for this client
if (std::strlen(path) <= nameSize || std::strncmp(path+1, fName, nameSize) != 0)
{
carla_stderr("CarlaBridgeOsc::handleMessage() - message not for this client -> '%s' != '/%s/'", path, fName.buffer());
return 1;
}

// Get method from path
char method[32+1] = { '\0' };
std::strncpy(method, path + (nameSize + 2), 32);

if (method[0] == '\0')
{
carla_stderr("CarlaBridgeOsc::handleMessage(\"%s\", ...) - received message without method", path);
return 1;
}

// Common methods
if (std::strcmp(method, "show") == 0)
return handleMsgShow();
if (std::strcmp(method, "hide") == 0)
return handleMsgHide();
if (std::strcmp(method, "quit") == 0)
return handleMsgQuit();

// UI methods
if (std::strcmp(method, "configure") == 0)
return handleMsgUiConfigure(argc, argv, types);
if (std::strcmp(method, "control") == 0)
return handleMsgUiControl(argc, argv, types);
if (std::strcmp(method, "program") == 0)
return handleMsgUiProgram(argc, argv, types);
if (std::strcmp(method, "midi-program") == 0)
return handleMsgUiMidiProgram(argc, argv, types);
if (std::strcmp(method, "midi") == 0)
return handleMsgUiMidi(argc, argv, types);
if (std::strcmp(method, "sample-rate") == 0)
return 0; // unused

# ifdef BRIDGE_LV2
// LV2 methods
if (std::strcmp(method, "lv2_atom_transfer") == 0)
return handleMsgLv2UiAtomTransfer(argc, argv, types);
if (std::strcmp(method, "lv2_urid_map") == 0)
return handleMsgLv2UiUridMap(argc, argv, types);
# endif

carla_stderr("CarlaBridgeOsc::handleMessage(\"%s\", ...) - received unsupported OSC method '%s'", path, method);
return 1;
}

int CarlaBridgeOsc::handleMsgShow()
{
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgShow()");

fClient->toolkitShow();

return 0;
}

int CarlaBridgeOsc::handleMsgHide()
{
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgHide()");

fClient->toolkitHide();

return 0;
}

int CarlaBridgeOsc::handleMsgQuit()
{
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgQuit()");

fClient->toolkitQuit();

return 0;
}

int CarlaBridgeOsc::handleMsgUiConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ss");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgConfigure()");

// nothing here for now
return 0;

// unused
(void)argv;
}

int CarlaBridgeOsc::handleMsgUiControl(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "if");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgControl()");

const int32_t index = argv[0]->i;
const float value = argv[1]->f;

CARLA_SAFE_ASSERT_RETURN(index != -1, 1);

fClient->setParameter(index, value);

return 0;
}

int CarlaBridgeOsc::handleMsgUiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgProgram()");

const int32_t index = argv[0]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 1);

fClient->setProgram(static_cast<uint32_t>(index));

return 0;
}

int CarlaBridgeOsc::handleMsgUiMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgMidiProgram()");

const int32_t bank = argv[0]->i;
const int32_t program = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(bank >= 0, 1);
CARLA_SAFE_ASSERT_RETURN(program >= 0, 1);

fClient->setMidiProgram(static_cast<uint32_t>(bank), static_cast<uint32_t>(program));

return 0;
}

int CarlaBridgeOsc::handleMsgUiMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "m");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgMidi()");

const uint8_t* const data = argv[0]->m;
uint8_t status = data[1];
uint8_t channel = status & 0x0F;

// Fix bad note-off
if (MIDI_IS_STATUS_NOTE_ON(status) && data[3] == 0)
status -= 0x10;

if (MIDI_IS_STATUS_NOTE_OFF(status))
{
const uint8_t note = data[2];

CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, 1);

fClient->noteOff(channel, note);
}
else if (MIDI_IS_STATUS_NOTE_ON(status))
{
const uint8_t note = data[2];
const uint8_t velo = data[3];

CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE, 1);
CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE, 1);

fClient->noteOn(channel, note, velo);
}

return 0;
}

#endif // BUILD_BRIDGE_UI

// -----------------------------------------------------------------------

CARLA_BRIDGE_END_NAMESPACE

+ 0
- 131
source/bridges-plugin/CarlaBridgeOsc.hpp View File

@@ -1,131 +0,0 @@
/*
* Carla Bridge OSC
* Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.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 doc/GPL.txt file.
*/

#ifndef CARLA_BRIDGE_OSC_HPP_INCLUDED
#define CARLA_BRIDGE_OSC_HPP_INCLUDED

#include "CarlaBridge.hpp"
#include "CarlaOscUtils.hpp"
#include "CarlaString.hpp"

#define CARLA_BRIDGE_OSC_HANDLE_ARGS const int argc, const lo_arg* const* const argv, const char* const types

#define CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(/* argc, types, */ argcToCompare, typesToCompare) \
/* check argument count */ \
if (argc != argcToCompare) \
{ \
carla_stderr("CarlaBridgeOsc::%s() - argument count mismatch: %i != %i", __FUNCTION__, argc, argcToCompare); \
return 1; \
} \
if (argc > 0) \
{ \
/* check for nullness */ \
if (types == nullptr || typesToCompare == nullptr) \
{ \
carla_stderr("CarlaBridgeOsc::%s() - argument types are null", __FUNCTION__); \
return 1; \
} \
/* check argument types */ \
if (std::strcmp(types, typesToCompare) != 0) \
{ \
carla_stderr("CarlaBridgeOsc::%s() - argument types mismatch: '%s' != '%s'", __FUNCTION__, types, typesToCompare); \
return 1; \
} \
}

CARLA_BRIDGE_START_NAMESPACE

// -----------------------------------------------------------------------

class CarlaBridgeOsc
{
public:
CarlaBridgeOsc(CarlaBridgeClient* const client);
~CarlaBridgeOsc();

void init(const char* const url);
void idle() const;
void close();

// -------------------------------------------------------------------

bool isControlRegistered() const noexcept
{
return (fControlData.target != nullptr);
}

const CarlaOscData& getControlData() const noexcept
{
return fControlData;
}

const char* getServerPath() const noexcept
{
return fServerPath;
}

// -------------------------------------------------------------------

private:
CarlaBridgeClient* const fClient;

CarlaOscData fControlData;
CarlaString fName;
CarlaString fServerPath;
lo_server fServer;

#ifdef BUILD_BRIDGE_UI
// -------------------------------------------------------------------

int handleMessage(const char* const path, const int argc, const lo_arg* const* const argv, const char* const types, const lo_message msg);

int handleMsgShow();
int handleMsgHide();
int handleMsgQuit();

int handleMsgUiConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgUiControl(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgUiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgUiMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgUiMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS);

# ifdef BRIDGE_LV2
int handleMsgLv2UiAtomTransfer(CARLA_BRIDGE_OSC_HANDLE_ARGS);
int handleMsgLv2UiUridMap(CARLA_BRIDGE_OSC_HANDLE_ARGS);
# endif

// -------------------------------------------------------------------

static int osc_message_handler(const char* path, const char* types, lo_arg** argv, int argc, lo_message msg, void* userData)
{
return ((CarlaBridgeOsc*)userData)->handleMessage(path, argc, argv, types, msg);
}
#endif

static void osc_error_handler(int num, const char* msg, const char* path)
{
carla_stderr("CarlaBridgeOsc::osc_error_handler(%i, \"%s\", \"%s\")", num, msg, path);
}

CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaBridgeOsc)
};

// -----------------------------------------------------------------------

CARLA_BRIDGE_END_NAMESPACE

#endif // CARLA_BRIDGE_OSC_HPP_INCLUDED

+ 94
- 86
source/bridges-plugin/CarlaBridgePlugin.cpp View File

@@ -15,13 +15,11 @@
* For a full copy of the GNU General Public License see the doc/GPL.txt file.
*/

#include "CarlaBridgeClient.hpp"

#include "CarlaEngine.hpp"
#include "CarlaHost.h"

#include "CarlaBackendUtils.hpp"
#include "CarlaBridgeUtils.hpp"
#include "CarlaOscUtils.hpp"
#include "CarlaMIDI.h"

#ifdef CARLA_OS_UNIX
@@ -102,16 +100,12 @@ static void initSignalHandler()

// -------------------------------------------------------------------------

static CarlaBridge::CarlaBridgeClient* gBridgeClient = nullptr;
static CarlaString gProjectFilename;

static void gIdle()
{
carla_engine_idle();

if (gBridgeClient != nullptr)
gBridgeClient->oscIdle();

if (gSaveNow)
{
gSaveNow = false;
@@ -172,19 +166,15 @@ static JUCEApplicationBase* juce_CreateApplication() { return new CarlaJuceApp()

// -------------------------------------------------------------------------

CARLA_BRIDGE_START_NAMESPACE

// -------------------------------------------------------------------------

class CarlaPluginClient : public CarlaBridgeClient
class CarlaBridgePlugin
{
public:
CarlaPluginClient(const bool useBridge, const char* const clientName, const char* const audioBaseName, const char* const controlBaseName, const char* const timeBaseName)
: CarlaBridgeClient(nullptr),
fEngine(nullptr)
CarlaBridgePlugin(const bool useBridge, const char* const clientName, const char* const audioBaseName, const char* const controlBaseName, const char* const timeBaseName)
: fEngine(nullptr),
fOscServerThread(nullptr)
{
CARLA_ASSERT(clientName != nullptr && clientName[0] != '\0');
carla_debug("CarlaPluginClient::CarlaPluginClient(%s, \"%s\", %s, %s, %s)", bool2str(useBridge), clientName, audioBaseName, controlBaseName, timeBaseName);
carla_debug("CarlaBridgePlugin::CarlaBridgePlugin(%s, \"%s\", %s, %s, %s)", bool2str(useBridge), clientName, audioBaseName, controlBaseName, timeBaseName);

carla_set_engine_callback(callback, this);

@@ -196,9 +186,9 @@ public:
fEngine = carla_get_engine();
}

~CarlaPluginClient() override
~CarlaBridgePlugin()
{
carla_debug("CarlaPluginClient::~CarlaPluginClient()");
carla_debug("CarlaBridgePlugin::~CarlaBridgePlugin()");

carla_engine_close();
}
@@ -208,12 +198,75 @@ public:
return (fEngine != nullptr);
}

// ---------------------------------------------------------------------

void oscInit(const char* const url)
{
CarlaBridgeClient::oscInit(url);
fEngine->setOscBridgeData(&fOscData);
fOscServerThread = lo_server_thread_new_with_proto(nullptr, LO_UDP, osc_error_handler);

CARLA_SAFE_ASSERT_RETURN(fOscServerThread != nullptr,)

{
char* const host = lo_url_get_hostname(url);
char* const port = lo_url_get_port(url);
fOscControlData.path = carla_strdup_free(lo_url_get_path(url));
fOscControlData.target = lo_address_new_with_proto(LO_UDP, host, port);

std::free(host);
std::free(port);
}

if (char* const tmpServerPath = lo_server_thread_get_url(fOscServerThread))
{
std::srand((uint)(uintptr_t)this);
std::srand((uint)(uintptr_t)&url);

CarlaString oscName("plug-" + CarlaString(std::rand() % 99999));

fOscServerPath = tmpServerPath;
fOscServerPath += oscName;
std::free(tmpServerPath);
}

fEngine->setOscBridgeData(&fOscControlData);
}

void oscClose()
{
fEngine->setOscBridgeData(nullptr);

if (fOscServerThread != nullptr)
{
lo_server_thread_free(fOscServerThread);
fOscServerThread = nullptr;
}

fOscControlData.clear();
fOscServerPath.clear();
}

// ---------------------------------------------------------------------

void sendOscUpdate() const noexcept
{
if (fOscControlData.target != nullptr)
osc_send_update(fOscControlData, fOscServerPath);
}

void sendOscBridgeUpdate() const noexcept
{
if (fOscControlData.target != nullptr)
osc_send_bridge_update(fOscControlData, fOscControlData.path);
}

void sendOscBridgeError(const char* const error) const noexcept
{
if (fOscControlData.target != nullptr)
osc_send_bridge_error(fOscControlData, error);
}

// ---------------------------------------------------------------------

void exec(const bool useOsc, int argc, char* argv[])
{
if (! useOsc)
@@ -231,7 +284,6 @@ public:
carla_stderr("Plugin preset load failed, error was:\n%s", carla_get_last_error());
}

gBridgeClient = this;
gIsInitiated = true;

#if defined(CARLA_OS_MAC) || defined(CARLA_OS_WIN)
@@ -244,7 +296,6 @@ public:
carla_msleep(25);
}
#endif
gBridgeClient = nullptr;

carla_set_engine_about_to_close();
carla_remove_plugin(0);
@@ -270,7 +321,7 @@ protected:
break;

case ENGINE_CALLBACK_UI_STATE_CHANGED:
if (gIsInitiated && value1 != 1 && ! isOscControlRegistered())
if (gIsInitiated && value1 != 1 && fOscControlData.target == nullptr)
gCloseNow = true;
break;

@@ -288,65 +339,26 @@ private:
const CarlaEngine* fEngine;
String fProjFilename;

CarlaOscData fOscControlData;
CarlaString fOscServerPath;
lo_server_thread fOscServerThread;

static void callback(void* ptr, EngineCallbackOpcode action, unsigned int pluginId, int value1, int value2, float value3, const char* valueStr)
{
carla_debug("CarlaPluginClient::callback(%p, %i:%s, %i, %i, %i, %f, \"%s\")", ptr, action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
carla_debug("CarlaBridgePlugin::callback(%p, %i:%s, %i, %i, %i, %f, \"%s\")", ptr, action, EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
CARLA_SAFE_ASSERT_RETURN(pluginId == 0,);

return ((CarlaPluginClient*)ptr)->handleCallback(action, value1, value2, value3, valueStr);
return ((CarlaBridgePlugin*)ptr)->handleCallback(action, value1, value2, value3, valueStr);
}

static void osc_error_handler(int num, const char* msg, const char* path)
{
carla_stderr("CarlaBridgePlugin::osc_error_handler(%i, \"%s\", \"%s\")", num, msg, path);
}
};

#if 0
// -------------------------------------------------------------------------

int CarlaBridgeOsc::handleMsgPluginSetParameterMidiChannel(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgPluginSetParameterMidiChannel()");

const int32_t index = argv[0]->i;
const int32_t channel = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
CARLA_SAFE_ASSERT_RETURN(channel >= 0 && channel < MAX_MIDI_CHANNELS, 0);

carla_set_parameter_midi_channel(0, static_cast<uint32_t>(index), static_cast<uint8_t>(channel));
return 0;
}

int CarlaBridgeOsc::handleMsgPluginSetParameterMidiCC(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(2, "ii");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgPluginSetParameterMidiCC()");

const int32_t index = argv[0]->i;
const int32_t cc = argv[1]->i;

CARLA_SAFE_ASSERT_RETURN(index >= 0, 0);
CARLA_SAFE_ASSERT_RETURN(cc >= 1 && cc < 0x5F, 0);

carla_set_parameter_midi_cc(0, static_cast<uint32_t>(index), static_cast<int16_t>(cc));
return 0;
}

int CarlaBridgeOsc::handleMsgPluginSetCustomData(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(3, "sss");
CARLA_SAFE_ASSERT_RETURN(fClient != nullptr, 1);
carla_debug("CarlaBridgeOsc::handleMsgPluginSetCustomData()");

const char* const type = (const char*)&argv[0]->s;
const char* const key = (const char*)&argv[1]->s;
const char* const value = (const char*)&argv[2]->s;

carla_set_custom_data(0, type, key, value);
return 0;
}

int CarlaBridgeOsc::handleMsgPluginSetChunk(CARLA_BRIDGE_OSC_HANDLE_ARGS)
{
CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "s");
@@ -380,14 +392,10 @@ int CarlaBridgeOsc::handleMsgPluginSetChunk(CARLA_BRIDGE_OSC_HANDLE_ARGS)
}
#endif

CARLA_BRIDGE_END_NAMESPACE

// -------------------------------------------------------------------------

int main(int argc, char* argv[])
{
CARLA_BRIDGE_USE_NAMESPACE;

// ---------------------------------------------------------------------
// Check argument count

@@ -479,11 +487,11 @@ int main(int argc, char* argv[])
}

// ---------------------------------------------------------------------
// Init plugin client
// Init plugin bridge

CarlaPluginClient client(useBridge, clientName, bridgeBaseAudioName, bridgeBaseControlName, bridgeBaseTimeName);
CarlaBridgePlugin bridge(useBridge, clientName, bridgeBaseAudioName, bridgeBaseControlName, bridgeBaseTimeName);

if (! client.isOk())
if (! bridge.isOk())
{
carla_stderr("Failed to init engine, error was:\n%s", carla_get_last_error());
return 1;
@@ -493,7 +501,7 @@ int main(int argc, char* argv[])
// Init OSC

if (useOsc)
client.oscInit(oscUrl);
bridge.oscInit(oscUrl);

// ---------------------------------------------------------------------
// Listen for ctrl+c or sigint/sigterm events
@@ -511,8 +519,8 @@ int main(int argc, char* argv[])

if (useOsc)
{
client.sendOscUpdate();
client.sendOscBridgeUpdate();
bridge.sendOscUpdate();
bridge.sendOscBridgeUpdate();
}
else
{
@@ -525,7 +533,7 @@ int main(int argc, char* argv[])
}
}

client.exec(useOsc, argc, argv);
bridge.exec(useOsc, argc, argv);
}
else
{
@@ -535,14 +543,14 @@ int main(int argc, char* argv[])
carla_stderr("Plugin failed to load, error was:\n%s", lastError);

if (useOsc)
client.sendOscBridgeError(lastError);
bridge.sendOscBridgeError(lastError);
}

// ---------------------------------------------------------------------
// Close OSC

if (useOsc)
client.oscClose();
bridge.oscClose();

return ret;
}

+ 7
- 15
source/bridges-plugin/Makefile View File

@@ -7,9 +7,8 @@
include ../Makefile.mk

# --------------------------------------------------------------
# Common

BUILD_CXX_FLAGS += -DBUILD_BRIDGE
BUILD_CXX_FLAGS += -DBUILD_BRIDGE -DBUILD_BRIDGE_PLUGIN
BUILD_CXX_FLAGS += -I. -I../backend -I../includes -I../utils -isystem ../modules
BUILD_CXX_FLAGS += $(LIBLO_FLAGS)
LINK_FLAGS += $(LIBLO_LIBS)
@@ -17,7 +16,7 @@ LINK_FLAGS += $(LIBLO_LIBS)
# --------------------------------------------------------------
# Plugin bridges

BUILD_PLUGIN_FLAGS = $(BUILD_CXX_FLAGS) -DBUILD_BRIDGE_PLUGIN
BUILD_PLUGIN_FLAGS = $(BUILD_CXX_FLAGS)
BUILD_PLUGIN_FLAGS += -I../backend/engine -I../backend/plugin

LINK_PLUGIN_FLAGS = $(LINK_FLAGS)
@@ -106,10 +105,7 @@ win64: ../../bin/carla-bridge-win64.exe
# --------------------------------------------------------------
# native

OBJS_NATIVE = \
CarlaBridgePlugin__native.o \
CarlaBridgeClient__native.o \
CarlaBridgeOsc__native.o
OBJS_NATIVE = CarlaBridgePlugin__native.o

# carla-engine
OBJS_NATIVE += \
@@ -173,8 +169,7 @@ endif
# --------------------------------------------------------------
# posix32

OBJS_POSIX32 = CarlaBridgePlugin__posix32.o \
CarlaBridgeClient__posix32.o CarlaBridgeOsc__posix32.o
OBJS_POSIX32 = CarlaBridgePlugin__posix32.o

# carla-engine
OBJS_POSIX32 += \
@@ -232,8 +227,7 @@ endif
# --------------------------------------------------------------
# posix64

OBJS_POSIX64 = CarlaBridgePlugin__posix64.o \
CarlaBridgeClient__posix64.o CarlaBridgeOsc__posix64.o
OBJS_POSIX64 = CarlaBridgePlugin__posix64.o

# carla-engine
OBJS_POSIX64 += \
@@ -291,8 +285,7 @@ endif
# --------------------------------------------------------------
# win32

OBJS_WIN32 = CarlaBridgePlugin__win32.o \
CarlaBridgeClient__win32.o CarlaBridgeOsc__win32.o
OBJS_WIN32 = CarlaBridgePlugin__win32.o

# carla-engine
OBJS_WIN32 += \
@@ -347,8 +340,7 @@ LIBS_WIN32 += \
# --------------------------------------------------------------
# win64

OBJS_WIN64 = CarlaBridgePlugin__win64.o \
CarlaBridgeClient__win64.o CarlaBridgeOsc__win64.o
OBJS_WIN64 = CarlaBridgePlugin__win64.o

# carla-engine
OBJS_WIN64 += \


Loading…
Cancel
Save