|
- /*
- * Carla Jack Plugin
- * Copyright (C) 2014 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 "CarlaEngine.hpp"
- #include "CarlaHost.h"
-
- #include "CarlaBackendUtils.hpp"
- #include "CarlaThread.hpp"
-
- #include "../CarlaBridgeClient.hpp"
-
- #include "../backend/plugin/CarlaPluginInternal.hpp"
- #include "CarlaMathUtils.hpp"
-
- #include "jackbridge/JackBridge.hpp"
-
- // -------------------------------------------------------------------------------------------------------------------
-
- struct _jack_client {
- bool isActive;
-
- JackShutdownCallback shutdown_cb;
- void* shutdown_ptr;
-
- JackProcessCallback process_cb;
- void* process_ptr;
-
- _jack_client()
- {
- clear();
- }
-
- void clear()
- {
- isActive = false;
- shutdown_cb = nullptr;
- shutdown_ptr = nullptr;
- process_cb = nullptr;
- process_ptr = nullptr;
- }
- };
-
- static jack_client_t gJackClient;
-
- // -------------------------------------------------------------------------------------------------------------------
-
- struct _jack_port {
- bool used;
- char name[128+1];
- void* buffer;
-
- _jack_port()
- : used(false),
- buffer(nullptr) {}
- };
-
- // system ports
- static jack_port_t gPortSystemIn1; // 0
- static jack_port_t gPortSystemIn2; // 1
- static jack_port_t gPortSystemOut1; // 2
- static jack_port_t gPortSystemOut2; // 3
-
- // client ports
- static jack_port_t gPortAudioIn1; // 4
- static jack_port_t gPortAudioIn2; // 5
- static jack_port_t gPortAudioOut1; // 6
- static jack_port_t gPortAudioOut2; // 7
- static jack_port_t gPortMidiIn; // 8
- static jack_port_t gPortMidiOut; // 9
-
- // -------------------------------------------------------------------------------------------------------------------
-
- CARLA_BRIDGE_START_NAMESPACE
-
- class JackBridgeClient : public CarlaBridgeClient,
- CarlaThread
- {
- public:
- JackBridgeClient()
- : CarlaBridgeClient(nullptr),
- fEngine(nullptr)
- {
- carla_debug("JackBridgeClient::JackBridgeClient()");
-
- carla_set_engine_callback(callback, this);
-
- const char* const shmIds(std::getenv("ENGINE_BRIDGE_SHM_IDS"));
- CARLA_SAFE_ASSERT_RETURN(shmIds != nullptr,);
- CARLA_SAFE_ASSERT_RETURN(std::strlen(shmIds) == 6*2,);
-
- char bridgeBaseAudioName[6+1];
- char bridgeBaseControlName[6+1];
-
- std::strncpy(bridgeBaseAudioName, shmIds, 6);
- std::strncpy(bridgeBaseControlName, shmIds+6, 6);
- bridgeBaseAudioName[6] = '\0';
- bridgeBaseControlName[6] = '\0';
-
- const char* const clientName(std::getenv("ENGINE_BRIDGE_CLIENT_NAME"));
- CARLA_SAFE_ASSERT_RETURN(clientName != nullptr,);
-
- const char* const oscUrl(std::getenv("ENGINE_BRIDGE_OSC_URL"));
- CARLA_SAFE_ASSERT_RETURN(oscUrl != nullptr,);
-
- if (! carla_engine_init_bridge(bridgeBaseAudioName, bridgeBaseControlName, clientName))
- return;
-
- fEngine = carla_get_engine();
- CARLA_SAFE_ASSERT_RETURN(fEngine != nullptr,);
-
- CarlaBridgeClient::oscInit(oscUrl);
- fEngine->setOscBridgeData(&fOscData);
-
- carla_add_plugin(CarlaBackend::BINARY_NATIVE, CarlaBackend::PLUGIN_JACK, "bridge", clientName, clientName, nullptr);
-
- sendOscUpdate();
- sendOscBridgeUpdate();
- }
-
- ~JackBridgeClient() override
- {
- carla_debug("JackBridgeClient::~JackBridgeClient()");
- oscClose();
- carla_engine_close();
- }
-
- bool isOk() const noexcept
- {
- return (fEngine != nullptr);
- }
-
- protected:
- void handleCallback(const CarlaBackend::EngineCallbackOpcode /*action*/, const uint /*pluginId*/, const int /*value1*/, const int /*value2*/, const float /*value3*/, const char* const /*valueStr*/)
- {
- CARLA_BACKEND_USE_NAMESPACE;
- }
-
- void run()
- {
- for (; carla_is_engine_running();)
- {
- carla_engine_idle();
- CarlaBridgeClient::oscIdle();
- carla_msleep(30);
- }
- }
-
- private:
- const CarlaBackend::CarlaEngine* fEngine;
-
- static void callback(void* ptr, CarlaBackend::EngineCallbackOpcode action, uint pluginId, int value1, int value2, float value3, const char* valueStr)
- {
- carla_debug("CarlaPluginClient::callback(%p, %i:%s, %i, %i, %i, %f, \"%s\")", ptr, action, CarlaBackend::EngineCallbackOpcode2Str(action), pluginId, value1, value2, value3, valueStr);
- CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
-
- return ((JackBridgeClient*)ptr)->handleCallback(action, pluginId, value1, value2, value3, valueStr);
- }
- };
-
- // -------------------------------------------------------------------------
-
- int CarlaBridgeOsc::handleMsgShow()
- {
- carla_debug("CarlaBridgeOsc::handleMsgShow()");
-
- return 0;
- }
-
- int CarlaBridgeOsc::handleMsgHide()
- {
- carla_debug("CarlaBridgeOsc::handleMsgHide()");
-
- return 0;
- }
-
- int CarlaBridgeOsc::handleMsgQuit()
- {
- carla_debug("CarlaBridgeOsc::handleMsgQuit()");
-
- if (gJackClient.shutdown_cb != nullptr)
- gJackClient.shutdown_cb(gJackClient.shutdown_ptr);
-
- carla_engine_close();
-
- std::exit(0);
-
- return 0;
- }
-
- CARLA_BRIDGE_END_NAMESPACE
-
- // -------------------------------------------------------------------------------------------------------------------
-
- CARLA_EXPORT jack_client_t* jack_client_open(const char* client_name, jack_options_t options, jack_status_t* status, ...);
- CARLA_EXPORT int jack_client_close(jack_client_t* client);
-
- CARLA_EXPORT int jack_client_name_size();
- CARLA_EXPORT char* jack_get_client_name(jack_client_t* client);
-
- CARLA_EXPORT int jack_activate(jack_client_t* client);
- CARLA_EXPORT int jack_deactivate(jack_client_t* client);
- CARLA_EXPORT int jack_is_realtime(jack_client_t* client);
-
- CARLA_EXPORT jack_nframes_t jack_get_sample_rate(jack_client_t* client);
- CARLA_EXPORT jack_nframes_t jack_get_buffer_size(jack_client_t* client);
-
- CARLA_EXPORT jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long buffer_size);
- CARLA_EXPORT void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames);
-
- CARLA_EXPORT const char* jack_port_name(const jack_port_t* port);
-
- CARLA_EXPORT const char** jack_get_ports(jack_client_t*, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags);
- CARLA_EXPORT jack_port_t* jack_port_by_name(jack_client_t* client, const char* port_name);
- CARLA_EXPORT jack_port_t* jack_port_by_id(jack_client_t* client, jack_port_id_t port_id);
-
- CARLA_EXPORT int jack_connect(jack_client_t* client, const char* source_port, const char* destination_port);
- CARLA_EXPORT int jack_disconnect(jack_client_t* client, const char* source_port, const char* destination_port);
-
- CARLA_EXPORT void jack_on_shutdown(jack_client_t* client, JackShutdownCallback function, void* arg);
- CARLA_EXPORT int jack_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg);
-
- CARLA_EXPORT void jack_set_info_function(void (*func)(const char*));
- CARLA_EXPORT void jack_set_error_function(void (*func)(const char*));
- CARLA_EXPORT void jack_free(void* ptr);
-
- // -------------------------------------------------------------------------------------------------------------------
-
- typedef void (*jack_error_callback)(const char* msg);
- typedef void (*jack_info_callback)(const char* msg);
-
- jack_error_callback sErrorCallback = nullptr;
- jack_info_callback sInfoCallback = nullptr;
-
- // -------------------------------------------------------------------------------------------------------------------
-
- jack_client_t* jack_client_open(const char* client_name, jack_options_t /*options*/, jack_status_t* status, ...)
- {
- carla_stderr2("JACKBRIDGE CLIENT OPEN HERE");
-
- if (carla_is_engine_running())
- {
- if (status != nullptr)
- *status = JackServerStarted;
- return nullptr;
- }
-
- static CarlaBridge::JackBridgeClient bridge;
-
- if (! bridge.isOk())
- {
- if (status != nullptr)
- *status = JackServerFailed;
- return nullptr;
- }
-
- if (! gPortSystemIn1.used)
- {
- gPortSystemIn1.used = true;
- gPortSystemIn2.used = true;
- gPortSystemOut1.used = true;
- gPortSystemOut2.used = true;
- std::strcpy(gPortSystemIn1.name, "system:capture_1");
- std::strcpy(gPortSystemIn2.name, "system:capture_2");
- std::strcpy(gPortSystemOut1.name, "system:playback_1");
- std::strcpy(gPortSystemOut2.name, "system:playback_2");
- }
-
- return &gJackClient;
- }
-
- int jack_client_close(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
-
- carla_stderr2("JACKBRIDGE CLIENT CLOSE HERE");
-
- if (! carla_is_engine_running())
- return -1;
-
- carla_engine_close();
- gJackClient.clear();
- gPortAudioIn1.used = 0;
- gPortAudioIn2.used = 0;
- gPortAudioOut1.used = 0;
- gPortAudioOut2.used = 0;
- gPortMidiIn.used = 0;
- gPortMidiOut.used = 0;
- return 0;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- int jack_client_name_size()
- {
- return 32+1; // same as JACK1
- }
-
- char* jack_get_client_name(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
-
- if (const CarlaEngine* const engine = carla_get_engine())
- return const_cast<char*>(engine->getName());
-
- return nullptr;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- int jack_activate(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
-
- gJackClient.isActive = true;
- return 0;
- }
-
- int jack_deactivate(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
-
- gJackClient.isActive = false;
- return 0;
- }
-
- int jack_is_realtime(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
- return 1;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- jack_nframes_t jack_get_sample_rate(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
- return static_cast<uint32_t>(carla_get_sample_rate());
- }
-
- jack_nframes_t jack_get_buffer_size(jack_client_t* client)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, 0);
- return carla_get_buffer_size();
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- jack_port_t* jack_port_register(jack_client_t* client, const char* port_name, const char* port_type, unsigned long flags, unsigned long)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
-
- if (std::strcmp(port_type, JACK_DEFAULT_AUDIO_TYPE) == 0)
- {
- if (flags & JackPortIsInput)
- {
- if (gPortAudioIn1.used && gPortAudioIn2.used)
- return nullptr;
-
- if (! gPortAudioIn1.used)
- {
- std::strncpy(gPortAudioIn1.name, port_name, 128);
- return &gPortAudioIn1;
- }
- else
- {
- std::strncpy(gPortAudioIn2.name, port_name, 128);
- return &gPortAudioIn2;
- }
- }
- else
- {
- if (gPortAudioOut1.used && gPortAudioOut2.used)
- return nullptr;
-
- if (! gPortAudioOut1.used)
- {
- std::strncpy(gPortAudioOut1.name, port_name, 128);
- return &gPortAudioOut1;
- }
- else
- {
- std::strncpy(gPortAudioOut2.name, port_name, 128);
- return &gPortAudioOut2;
- }
- }
- }
-
- if (std::strcmp(port_type, JACK_DEFAULT_MIDI_TYPE) == 0)
- {
- if (flags & JackPortIsInput)
- {
- if (gPortMidiIn.used)
- return nullptr;
- std::strncpy(gPortMidiIn.name, port_name, 128);
- return &gPortMidiIn;
- }
- else
- {
- if (gPortMidiOut.used)
- return nullptr;
- std::strncpy(gPortMidiOut.name, port_name, 128);
- return &gPortMidiOut;
- }
- }
-
- return nullptr;
- }
-
- void* jack_port_get_buffer(jack_port_t* port, jack_nframes_t frames)
- {
- return port->buffer;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- const char* jack_port_name(const jack_port_t* port)
- {
- return port->name;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- const char** jack_get_ports(jack_client_t* client, const char* port_name_pattern, const char* type_name_pattern, unsigned long flags)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
-
- if (port_name_pattern != nullptr)
- {
- if (std::strstr("system:playback_", port_name_pattern) == nullptr)
- return nullptr;
- if (std::strstr("system:capture_", port_name_pattern) == nullptr)
- return nullptr;
- }
- if (type_name_pattern != nullptr)
- {
- if (std::strstr(JACK_DEFAULT_AUDIO_TYPE, type_name_pattern) == nullptr)
- return nullptr;
- }
-
- uint numPorts = 0;
-
- if (flags == 0)
- {
- numPorts = 4;
- }
- else
- {
- if (flags & JackPortIsInput)
- numPorts += 2;
- if (flags & JackPortIsOutput)
- numPorts += 2;
- }
-
- if (numPorts == 0)
- return nullptr;
-
- const char** const ports = new const char*[numPorts+1];
- uint i = 0;
-
- if (flags == 0 || (flags & JackPortIsInput) != 0)
- {
- ports[i++] = gPortSystemIn1.name;
- ports[i++] = gPortSystemIn1.name;
- }
- if (flags == 0 || (flags & JackPortIsOutput) != 0)
- {
- ports[i++] = gPortSystemOut1.name;
- ports[i++] = gPortSystemOut1.name;
- }
- ports[i++] = nullptr;
-
- return ports;
- }
-
- jack_port_t* jack_port_by_name(jack_client_t* client, const char* port_name)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
- CARLA_SAFE_ASSERT_RETURN(gPortSystemIn1.used, nullptr);
-
- if (std::strcmp(port_name, gPortSystemIn1.name) == 0)
- return &gPortSystemIn1;
- if (std::strcmp(port_name, gPortSystemIn2.name) == 0)
- return &gPortSystemIn2;
- if (std::strcmp(port_name, gPortSystemOut1.name) == 0)
- return &gPortSystemOut1;
- if (std::strcmp(port_name, gPortSystemOut2.name) == 0)
- return &gPortSystemOut2;
-
- if (gPortAudioIn1.used && std::strcmp(port_name, gPortAudioIn1.name) == 0)
- return &gPortAudioIn1;
- if (gPortAudioIn2.used && std::strcmp(port_name, gPortAudioIn2.name) == 0)
- return &gPortAudioIn2;
- if (gPortAudioOut1.used && std::strcmp(port_name, gPortAudioOut1.name) == 0)
- return &gPortAudioOut1;
- if (gPortAudioOut2.used && std::strcmp(port_name, gPortAudioOut2.name) == 0)
- return &gPortAudioOut2;
- if (gPortMidiIn.used && std::strcmp(port_name, gPortMidiIn.name) == 0)
- return &gPortMidiIn;
- if (gPortMidiOut.used && std::strcmp(port_name, gPortMidiOut.name) == 0)
- return &gPortMidiOut;
-
- return nullptr;
- }
-
- jack_port_t* jack_port_by_id(jack_client_t* client, jack_port_id_t port_id)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, nullptr);
- CARLA_SAFE_ASSERT_RETURN(gPortSystemIn1.used, nullptr);
-
- switch (port_id)
- {
- case 0:
- return &gPortSystemIn1;
- case 1:
- return &gPortSystemIn2;
- case 2:
- return &gPortSystemOut1;
- case 3:
- return &gPortSystemOut2;
- case 4:
- if (gPortAudioIn1.used)
- return &gPortAudioIn1;
- break;
- case 5:
- if (gPortAudioIn2.used)
- return &gPortAudioIn2;
- break;
- case 6:
- if (gPortAudioOut1.used)
- return &gPortAudioOut1;
- break;
- case 7:
- if (gPortAudioOut2.used)
- return &gPortAudioOut2;
- break;
- case 8:
- if (gPortMidiIn.used)
- return &gPortMidiIn;
- break;
- case 9:
- if (gPortMidiOut.used)
- return &gPortMidiOut;
- break;
- }
-
- return nullptr;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- int jack_connect(jack_client_t* client, const char*, const char*)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
-
- return 0;
- }
-
- int jack_disconnect(jack_client_t* client, const char*, const char*)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
-
- return 0;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- void jack_on_shutdown(jack_client_t* client, JackShutdownCallback function, void* arg)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient,);
-
- gJackClient.shutdown_cb = function;
- gJackClient.shutdown_ptr = arg;
- }
-
- int jack_set_process_callback(jack_client_t* client, JackProcessCallback process_callback, void* arg)
- {
- CARLA_SAFE_ASSERT_RETURN(client == &gJackClient, -1);
-
- gJackClient.process_cb = process_callback;
- gJackClient.process_ptr = arg;
- return 0;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- void jack_set_error_function(void (*func)(const char*))
- {
- sErrorCallback = func;
- }
-
- void jack_set_info_function(void (*func)(const char*))
- {
- sInfoCallback = func;
- }
-
- void jack_free(void* ptr)
- {
- delete[] (char**)ptr;
- }
-
- // -------------------------------------------------------------------------------------------------------------------
-
- CARLA_EXPORT void carla_register_all_plugins();
- void carla_register_all_plugins() {}
-
- // -------------------------------------------------------------------------------------------------------------------
-
- CARLA_BACKEND_START_NAMESPACE
-
- class JackPlugin : public CarlaPlugin
- {
- public:
- JackPlugin(CarlaEngine* const engine, const uint id)
- : CarlaPlugin(engine, id)
- {
- carla_debug("JackPlugin::JackPlugin(%p, %i)", engine, id);
- }
-
- ~JackPlugin() override
- {
- carla_debug("JackPlugin::~JackPlugin()");
-
- pData->singleMutex.lock();
- pData->masterMutex.lock();
-
- if (pData->client != nullptr && pData->client->isActive())
- pData->client->deactivate();
-
- if (pData->active)
- {
- deactivate();
- pData->active = false;
- }
-
- clearBuffers();
- }
-
- void clearBuffers() override
- {
- pData->audioIn.count = 0;
- pData->audioOut.count = 0;
- }
-
- // -------------------------------------------------------------------
- // Information (base)
-
- PluginType getType() const noexcept override
- {
- return PLUGIN_JACK;
- }
-
- PluginCategory getCategory() const noexcept override
- {
- return PLUGIN_CATEGORY_NONE;
- }
-
- void getLabel(char* const strBuf) const noexcept override
- {
- std::strncpy(strBuf, "zita-rev1", STR_MAX);
- }
-
- void getRealName(char* const strBuf) const noexcept override
- {
- std::strncpy(strBuf, "zita-rev1", STR_MAX);
- }
-
- // -------------------------------------------------------------------
- // Information (count)
-
- // nothing
-
- // -------------------------------------------------------------------
- // Information (current data)
-
- // nothing
-
- // -------------------------------------------------------------------
- // Information (per-plugin data)
-
- unsigned int getOptionsAvailable() const noexcept override
- {
- unsigned int options = 0x0;
-
- //options |= PLUGIN_OPTION_FIXED_BUFFERS;
- options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
- //options |= PLUGIN_OPTION_USE_CHUNKS;
-
- {
- options |= PLUGIN_OPTION_SEND_CONTROL_CHANGES;
- options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
- options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
- options |= PLUGIN_OPTION_SEND_PITCHBEND;
- options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
- }
-
- return options;
- }
-
- // -------------------------------------------------------------------
- // Set data (state)
-
- // nothing
-
- // -------------------------------------------------------------------
- // Set data (internal stuff)
-
- // -------------------------------------------------------------------
- // Set data (plugin-specific stuff)
-
- // -------------------------------------------------------------------
- // Set ui stuff
-
- // -------------------------------------------------------------------
- // Plugin state
-
- void reload() override
- {
- CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr,);
- carla_stderr2("JackPlugin::reload() - start");
-
- //const EngineProcessMode processMode(pData->engine->getProccessMode());
-
- // Safely disable plugin for reload
- const ScopedDisabler sd(this);
-
- if (pData->active)
- deactivate();
-
- clearBuffers();
-
- pData->audioIn.count = 2;
- pData->audioOut.count = 2;
-
- bufferSizeChanged(pData->engine->getBufferSize());
- //reloadPrograms(true);
-
- if (pData->active)
- activate();
-
- carla_stderr2("JackPlugin::reload() - end");
- }
-
- // -------------------------------------------------------------------
- // Plugin processing
-
- void activate() noexcept override
- {
- }
-
- void deactivate() noexcept override
- {
- }
-
- void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override
- {
- carla_stderr2("JackPlugin::process");
- // --------------------------------------------------------------------------------------------------------
- // Check if active
-
- if (! (gJackClient.isActive && pData->active))
- {
- // disable any output sound
- for (uint32_t i=0; i < pData->audioOut.count; ++i)
- FLOAT_CLEAR(outBuffer[i], static_cast<int>(frames));
- carla_stderr2("JackPlugin::process disabled");
- return;
- }
- carla_stderr2("JackPlugin::working");
-
- // --------------------------------------------------------------------------------------------------------
- // Check if needs reset
-
- if (pData->needsReset)
- {
- pData->needsReset = false;
- }
-
- processSingle(inBuffer, outBuffer, frames);
- }
-
- bool processSingle(float** const inBuffer, float** const outBuffer, const uint32_t frames)
- {
- CARLA_SAFE_ASSERT_RETURN(frames > 0, false);
-
- if (pData->audioIn.count > 0)
- {
- CARLA_SAFE_ASSERT_RETURN(inBuffer != nullptr, false);
- }
- if (pData->audioOut.count > 0)
- {
- CARLA_SAFE_ASSERT_RETURN(outBuffer != nullptr, false);
- }
-
- // --------------------------------------------------------------------------------------------------------
- // Try lock, silence otherwise
-
- if (pData->engine->isOffline())
- {
- pData->singleMutex.lock();
- }
- else if (! pData->singleMutex.tryLock())
- {
- for (uint32_t i=0; i < pData->audioOut.count; ++i)
- FLOAT_CLEAR(outBuffer[i], frames);
- return false;
- }
-
- // --------------------------------------------------------------------------------------------------------
- // Set audio in buffers
-
- if (pData->audioIn.count == 2)
- {
- gPortAudioIn1.buffer = inBuffer[0];
- gPortAudioIn2.buffer = inBuffer[1];
- }
- else if (pData->audioIn.count == 1)
- {
- gPortAudioIn1.buffer = inBuffer[0];
- }
-
- if (pData->audioOut.count == 2)
- {
- gPortAudioOut1.buffer = outBuffer[0];
- gPortAudioOut2.buffer = outBuffer[1];
- }
- else if (pData->audioOut.count == 1)
- {
- gPortAudioOut1.buffer = outBuffer[0];
- }
-
- // --------------------------------------------------------------------------------------------------------
- // Run plugin
-
- //if (gJackClient.process_cb != nullptr)
- // gJackClient.process_cb(frames, gJackClient.process_ptr);
-
- // --------------------------------------------------------------------------------------------------------
- // Set audio out buffers
-
- //for (uint32_t i=0; i < pData->audioOut.count; ++i)
- // FloatVectorOperations::copy(outBuffer[i], fAudioBuffer.getSampleData(static_cast<int>(i)), static_cast<int>(frames));
-
- // --------------------------------------------------------------------------------------------------------
-
- pData->singleMutex.unlock();
- return true;
- }
-
- void bufferSizeChanged(const uint32_t newBufferSize) override
- {
- CARLA_ASSERT_INT(newBufferSize > 0, newBufferSize);
- carla_debug("VstPlugin::bufferSizeChanged(%i)", newBufferSize);
- }
-
- void sampleRateChanged(const double newSampleRate) override
- {
- CARLA_ASSERT_INT(newSampleRate > 0.0, newSampleRate);
- carla_debug("VstPlugin::sampleRateChanged(%g)", newSampleRate);
- }
-
- // -------------------------------------------------------------------
- // Plugin buffers
-
- // nothing
-
- // -------------------------------------------------------------------
- // Post-poned UI Stuff
-
- // nothing
-
- // -------------------------------------------------------------------
-
- protected:
- // TODO
-
- // -------------------------------------------------------------------
-
- public:
- bool init(const char* const filename, const char* const name, const char* const label)
- {
- CARLA_SAFE_ASSERT_RETURN(pData->engine != nullptr, false);
-
- // ---------------------------------------------------------------
- // first checks
-
- if (pData->client != nullptr)
- {
- pData->engine->setLastError("Plugin client is already registered");
- return false;
- }
-
- if (filename == nullptr || filename[0] == '\0')
- {
- pData->engine->setLastError("null filename");
- return false;
- }
-
- if (label == nullptr || label[0] == '\0')
- {
- pData->engine->setLastError("null label");
- return false;
- }
-
- // ---------------------------------------------------------------
- // get info
-
- if (name != nullptr && name[0] != '\0')
- pData->name = pData->engine->getUniquePluginName(name);
- else
- pData->name = pData->engine->getUniquePluginName("test");
-
- pData->filename = carla_strdup(filename);
-
- // ---------------------------------------------------------------
- // register client
-
- pData->client = pData->engine->addClient(this);
-
- if (pData->client == nullptr || ! pData->client->isOk())
- {
- pData->engine->setLastError("Failed to register plugin client");
- return false;
- }
-
- // ---------------------------------------------------------------
- // load plugin settings
-
- {
- // set default options
- pData->options = 0x0;
-
- //pData->options |= PLUGIN_OPTION_FIXED_BUFFERS;
- pData->options |= PLUGIN_OPTION_MAP_PROGRAM_CHANGES;
- //pData->options |= PLUGIN_OPTION_USE_CHUNKS;
-
- //if (fInstance->acceptsMidi())
- {
- pData->options |= PLUGIN_OPTION_SEND_CHANNEL_PRESSURE;
- pData->options |= PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH;
- pData->options |= PLUGIN_OPTION_SEND_PITCHBEND;
- pData->options |= PLUGIN_OPTION_SEND_ALL_SOUND_OFF;
- }
-
- // set identifier string
- CarlaString identifier("JACK/");
- //identifier += juceId.toRawUTF8();
- pData->identifier = identifier.dup();
-
- // load settings
- pData->options = pData->loadSettings(pData->options, getOptionsAvailable());
- }
-
- return true;
- }
-
- private:
- CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(JackPlugin)
- };
-
- CarlaPlugin* CarlaPlugin::newJACK(const Initializer& init)
- {
- carla_debug("CarlaPlugin::newJACK({%p, \"%s\", \"%s\", \"%s\"})", init.engine, init.filename, init.name, init.label);
-
- JackPlugin* const plugin(new JackPlugin(init.engine, init.id));
-
- if (! plugin->init(init.filename, init.name, init.label))
- {
- delete plugin;
- return nullptr;
- }
-
- plugin->reload();
-
- // if (init.engine->getProccessMode() == ENGINE_PROCESS_MODE_CONTINUOUS_RACK && ! plugin->canRunInRack())
- // {
- // init.engine->setLastError("Carla's rack mode can only work with Stereo bridged apps, sorry!");
- // delete plugin;
- // return nullptr;
- // }
-
- return plugin;
- }
-
- CARLA_BACKEND_END_NAMESPACE
-
- // -------------------------------------------------------------------------------------------------------------------
|