From 78be58ae7f9c3865e8d8caf6c2a060857ce09343 Mon Sep 17 00:00:00 2001 From: falkTX Date: Wed, 15 Jan 2014 03:28:18 +0000 Subject: [PATCH] Move some file and functions around --- source/backend/CarlaBackend.h | 4 +- source/backend/CarlaEngine.hpp | 145 +- source/backend/CarlaHost.h | 4 +- source/backend/CarlaPlugin.hpp | 6 +- source/backend/engine/CarlaEngine.cpp | 1595 +---------------- source/backend/engine/CarlaEngineBridge.cpp | 4 +- source/backend/engine/CarlaEngineInternal.hpp | 556 +----- source/backend/engine/CarlaEngineJack.cpp | 26 +- source/backend/engine/CarlaEngineJuce.cpp | 10 +- source/backend/engine/CarlaEngineNative.cpp | 24 +- source/backend/engine/CarlaEngineOsc.cpp | 9 +- source/backend/engine/CarlaEngineOsc.hpp | 4 +- source/backend/engine/CarlaEngineRtAudio.cpp | 17 +- source/backend/engine/CarlaEngineThread.cpp | 4 +- source/backend/engine/CarlaEngineThread.hpp | 4 +- source/backend/engine/CarlaEngine_data.cpp | 271 +++ .../backend/engine/CarlaEngine_internal.cpp | 384 ++++ source/backend/engine/CarlaEngine_osc.cpp | 738 ++++++++ .../backend/engine/CarlaEngine_patchbay.cpp | 527 ++++++ source/backend/engine/CarlaEngine_ports.cpp | 273 +++ source/backend/engine/Makefile | 5 + source/backend/plugin/CarlaPlugin.cpp | 147 +- source/backend/plugin/CarlaPluginInternal.cpp | 234 +++ source/backend/plugin/CarlaPluginInternal.hpp | 2 + source/backend/plugin/LadspaPlugin.cpp | 1 - source/utils/CarlaEngineUtils.hpp | 114 ++ 26 files changed, 2796 insertions(+), 2312 deletions(-) create mode 100644 source/backend/engine/CarlaEngine_data.cpp create mode 100644 source/backend/engine/CarlaEngine_internal.cpp create mode 100644 source/backend/engine/CarlaEngine_osc.cpp create mode 100644 source/backend/engine/CarlaEngine_patchbay.cpp create mode 100644 source/backend/engine/CarlaEngine_ports.cpp create mode 100644 source/backend/plugin/CarlaPluginInternal.cpp create mode 100644 source/utils/CarlaEngineUtils.hpp diff --git a/source/backend/CarlaBackend.h b/source/backend/CarlaBackend.h index 8cfa7c9b4..4a559125f 100644 --- a/source/backend/CarlaBackend.h +++ b/source/backend/CarlaBackend.h @@ -1,6 +1,6 @@ /* - * Carla Backend API - * Copyright (C) 2011-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/source/backend/CarlaEngine.hpp b/source/backend/CarlaEngine.hpp index 99951d33e..a2254e877 100644 --- a/source/backend/CarlaEngine.hpp +++ b/source/backend/CarlaEngine.hpp @@ -1,6 +1,6 @@ /* - * Carla Engine API - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -19,7 +19,6 @@ #define CARLA_ENGINE_HPP_INCLUDED #include "CarlaBackend.h" -#include "CarlaMIDI.h" #ifdef BUILD_BRIDGE struct CarlaOscData; @@ -168,6 +167,9 @@ struct EngineControlEvent { uint16_t param; //!< Parameter Id, midi bank or midi program. float value; //!< Parameter value, normalized to 0.0f<->1.0f. + /*! + * Dump control event as MIDI data. + */ void dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept; }; @@ -192,6 +194,8 @@ struct EngineMidiEvent { * Engine event. */ struct EngineEvent { + static const ushort kMaxInternalCount = 512; //!< Maximum pre-allocated events for rack and bridge modes + EngineEventType type; //!< Event Type; either Control or MIDI uint32_t time; //!< Time offset in frames uint8_t channel; //!< Channel, used for MIDI-related events @@ -204,7 +208,10 @@ struct EngineEvent { EngineMidiEvent midi; }; - void fillFromMidiData(const uint8_t size, const uint8_t* const data); + /*! + * Fill event from MIDI data. + */ + void fillFromMidiData(const uint8_t size, const uint8_t* const data) noexcept; }; /*! @@ -229,47 +236,10 @@ struct EngineOptions { const char* binaryDir; const char* resourceDir; - EngineOptions() -#ifdef CARLA_OS_LINUX - : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS), - transportMode(ENGINE_TRANSPORT_MODE_JACK), -#else - : processMode(ENGINE_PROCESS_MODE_CONTINUOUS_RACK), - transportMode(ENGINE_TRANSPORT_MODE_INTERNAL), +#ifndef DOXYGEN + EngineOptions() noexcept; + ~EngineOptions(); #endif - forceStereo(false), - preferPluginBridges(false), - preferUiBridges(true), - uisAlwaysOnTop(true), - maxParameters(MAX_DEFAULT_PARAMETERS), - uiBridgesTimeout(4000), - audioNumPeriods(2), - audioBufferSize(512), - audioSampleRate(44100), - audioDevice(nullptr), - binaryDir(nullptr), - resourceDir(nullptr) {} - - ~EngineOptions() - { - if (audioDevice != nullptr) - { - delete[] audioDevice; - audioDevice = nullptr; - } - - if (binaryDir != nullptr) - { - delete[] binaryDir; - binaryDir = nullptr; - } - - if (resourceDir != nullptr) - { - delete[] resourceDir; - resourceDir = nullptr; - } - } }; /*! @@ -287,15 +257,9 @@ struct EngineTimeInfoBBT { double ticksPerBeat; double beatsPerMinute; - EngineTimeInfoBBT() noexcept - : bar(0), - beat(0), - tick(0), - barStartTick(0.0), - beatsPerBar(0.0f), - beatType(0.0f), - ticksPerBeat(0.0), - beatsPerMinute(0.0) {} +#ifndef DOXYGEN + EngineTimeInfoBBT() noexcept; +#endif }; /*! @@ -310,36 +274,18 @@ struct EngineTimeInfo { uint valid; EngineTimeInfoBBT bbt; - EngineTimeInfo() noexcept - : playing(false), - frame(0), - usecs(0), - valid(0x0) {} + /*! + * Clear. + */ + void clear() noexcept; - void clear() noexcept - { - playing = false; - frame = 0; - usecs = 0; - valid = 0x0; - } +#ifndef DOXYGEN + EngineTimeInfo() noexcept; // quick operator, doesn't check all values - bool operator==(const EngineTimeInfo& timeInfo) const noexcept - { - if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.valid != valid) - return false; - if ((valid & kValidBBT) == 0) - return true; - if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute) - return false; - return true; - } - - bool operator!=(const EngineTimeInfo& timeInfo) const noexcept - { - return !operator==(timeInfo); - } + bool operator==(const EngineTimeInfo& timeInfo) const noexcept; + bool operator!=(const EngineTimeInfo& timeInfo) const noexcept; +#endif }; // ----------------------------------------------------------------------- @@ -532,18 +478,18 @@ public: * Get the number of events present in the buffer. * \note You must only call this for input ports. */ - virtual uint32_t getEventCount() const; + virtual uint32_t getEventCount() const noexcept; /*! * Get the event at \a index. * \note You must only call this for input ports. */ - virtual const EngineEvent& getEvent(const uint32_t index); + virtual const EngineEvent& getEvent(const uint32_t index) noexcept; /*! * Get the event at \a index, faster unchecked version. */ - virtual const EngineEvent& getEventUnchecked(const uint32_t index); + virtual const EngineEvent& getEventUnchecked(const uint32_t index) noexcept; /*! * Write a control event into the buffer.\n @@ -555,10 +501,7 @@ public: /*! * Write a control event into the buffer, overloaded call. */ - bool writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) - { - return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value); - } + bool writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl); /*! * Write a MIDI event into the buffer.\n @@ -570,18 +513,12 @@ public: /*! * Write a MIDI event into the buffer, overloaded call. */ - bool writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) - { - return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data); - } + bool writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data); /*! * Write a MIDI event into the buffer, overloaded call. */ - bool writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) - { - return writeMidiEvent(time, channel, midi.port, midi.size, midi.data); - } + bool writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi); #ifndef DOXYGEN protected: @@ -1103,11 +1040,22 @@ protected: void setPluginPeaks(const unsigned int pluginId, float const inPeaks[2], float const outPeaks[2]) noexcept; // ------------------------------------------------------------------- + // Patchbay stuff + + /*! + * Called from patchbayRefresh() after all rack ports are in place. + */ + void handleRackConnectionsRefresh(); + /*! + * Virtual functions for handling MIDI ports in the rack patchbay. + */ virtual bool connectRackMidiInPort(const int) { return false; } virtual bool connectRackMidiOutPort(const int) { return false; } virtual bool disconnectRackMidiInPort(const int) { return false; } virtual bool disconnectRackMidiOutPort(const int) { return false; } + virtual uint getMidiConnectionsCount(const bool) { return 0; } + virtual uint getMidiConnectionPortId(const uint) { return 0; } // ------------------------------------------------------------------- @@ -1133,17 +1081,17 @@ private: // ------------------------------------------------------------------- // Engine initializers - // jack + // JACK static CarlaEngine* newJack(); - // rtaudio + // RtAudio static CarlaEngine* newRtAudio(const AudioApi api); static unsigned int getRtAudioApiCount(); static const char* getRtAudioApiName(const unsigned int index); static const char* const* getRtAudioApiDeviceNames(const unsigned int index); static const EngineDriverDeviceInfo* getRtAudioDeviceInfo(const unsigned int index, const char* const deviceName); - // juce + // Juce static CarlaEngine* newJuce(const AudioApi api); static unsigned int getJuceApiCount(); static const char* getJuceApiName(const unsigned int index); @@ -1152,6 +1100,7 @@ private: #ifdef BUILD_BRIDGE public: + // Bridge static CarlaEngine* newBridge(const char* const audioBaseName, const char* const controlBaseName); // ------------------------------------------------------------------- diff --git a/source/backend/CarlaHost.h b/source/backend/CarlaHost.h index 470359c5f..cac60717b 100644 --- a/source/backend/CarlaHost.h +++ b/source/backend/CarlaHost.h @@ -1,6 +1,6 @@ /* - * Carla Host API - * Copyright (C) 2011-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index 558dd68de..a2e77cc9c 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -1,6 +1,6 @@ /* - * Carla Plugin API - * Copyright (C) 2011-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -23,9 +23,7 @@ // Avoid including extra libs here typedef void* lo_address; typedef struct _NativePluginDescriptor NativePluginDescriptor; -//#ifndef LADSPA_RDF_HPP_INCLUDED struct LADSPA_RDF_Descriptor; -//#endif CARLA_BACKEND_START_NAMESPACE diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index e7b20589c..4c61c74c6 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -1,6 +1,6 @@ /* - * Carla Engine - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -27,691 +27,29 @@ */ #include "CarlaEngineInternal.hpp" +#include "CarlaPlugin.hpp" + #include "CarlaBackendUtils.hpp" #include "CarlaStateUtils.hpp" -#include "CarlaMIDI.h" #include +#ifdef HAVE_JUCE +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif + #include #include #include +// ----------------------------------------------------------------------- + CARLA_BACKEND_START_NAMESPACE #if 0 } // Fix editor indentation -#endif - -// ----------------------------------------------------------------------- -// Fallback data - -static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} }; - -// ----------------------------------------------------------------------- - -void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept -{ - switch (type) - { - case kEngineControlEventTypeNull: - break; - - case kEngineControlEventTypeParameter: - if (MIDI_IS_CONTROL_BANK_SELECT(param)) - { - size = 3; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_BANK_SELECT; - data[2] = static_cast(value); - } - else - { - size = 3; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = static_cast(param); - data[2] = uint8_t(value * 127.0f); - } - break; - - case kEngineControlEventTypeMidiBank: - size = 3; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_BANK_SELECT; - data[2] = static_cast(param); - break; - - case kEngineControlEventTypeMidiProgram: - size = 2; - data[0] = static_cast(MIDI_STATUS_PROGRAM_CHANGE + channel); - data[1] = static_cast(param); - break; - - case kEngineControlEventTypeAllSoundOff: - size = 2; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_ALL_SOUND_OFF; - break; - - case kEngineControlEventTypeAllNotesOff: - size = 2; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_ALL_NOTES_OFF; - break; - } -} - -void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data) -{ - // get channel - channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)); - - // get status - const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data))); - - if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) - { - type = kEngineEventTypeControl; - - const uint8_t midiControl(data[1]); - - if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) - { - CARLA_SAFE_ASSERT_INT(size == 3, size); - - const uint8_t midiBank(data[2]); - - ctrl.type = kEngineControlEventTypeMidiBank; - ctrl.param = midiBank; - ctrl.value = 0.0f; - } - else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) - { - CARLA_SAFE_ASSERT_INT(size == 2, size); - - ctrl.type = kEngineControlEventTypeAllSoundOff; - ctrl.param = 0; - ctrl.value = 0.0f; - } - else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) - { - CARLA_SAFE_ASSERT_INT(size == 2, size); - - ctrl.type = kEngineControlEventTypeAllNotesOff; - ctrl.param = 0; - ctrl.value = 0.0f; - } - else - { - CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl); - - const uint8_t midiValue(data[2]); - - ctrl.type = kEngineControlEventTypeParameter; - ctrl.param = midiControl; - ctrl.value = float(midiValue)/127.0f; - } - } - else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) - { - CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]); - - type = kEngineEventTypeControl; - - const uint8_t midiProgram(data[1]); - - ctrl.type = kEngineControlEventTypeMidiProgram; - ctrl.param = midiProgram; - ctrl.value = 0.0f; - } - else - { - type = kEngineEventTypeMidi; - - midi.port = 0; - midi.size = size; - - if (size > EngineMidiEvent::kDataSize) - { - midi.dataExt = data; - std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize); - } - else - { - midi.data[0] = midiStatus; - - uint8_t i=1; - for (; i < midi.size; ++i) - midi.data[i] = data[i]; - for (; i < EngineMidiEvent::kDataSize; ++i) - midi.data[i] = 0; - - midi.dataExt = nullptr; - } - } -} - -// ----------------------------------------------------------------------- - -#ifndef BUILD_BRIDGE -void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline) -{ - CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,); - CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,); - - // safe copy - float inBuf0[frames]; - float inBuf1[frames]; - float* inBuf[2] = { inBuf0, inBuf1 }; - - // initialize audio inputs - FLOAT_COPY(inBuf0, inBufReal[0], frames); - FLOAT_COPY(inBuf1, inBufReal[1], frames); - - // initialize audio outputs (zero) - FLOAT_CLEAR(outBuf[0], frames); - FLOAT_CLEAR(outBuf[1], frames); - - // initialize event outputs (zero) - carla_zeroStruct(bufEvents.out, kEngineMaxInternalEventCount); - - bool processed = false; - - uint32_t oldAudioInCount = 0; - uint32_t oldMidiOutCount = 0; - - // process plugins - for (unsigned int i=0; i < curPluginCount; ++i) - { - CarlaPlugin* const plugin = plugins[i].plugin; - - if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline)) - continue; - - if (processed) - { - // initialize audio inputs (from previous outputs) - FLOAT_COPY(inBuf0, outBuf[0], frames); - FLOAT_COPY(inBuf1, outBuf[1], frames); - - // initialize audio outputs (zero) - FLOAT_CLEAR(outBuf[0], frames); - FLOAT_CLEAR(outBuf[1], frames); - - // if plugin has no midi out, add previous events - if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull) - { - if (bufEvents.out[0].type != kEngineEventTypeNull) - { - // TODO: carefully add to input, sorted events - } - // else nothing needed - } - else - { - // initialize event inputs from previous outputs - carla_copyStruct(bufEvents.in, bufEvents.out, kEngineMaxInternalEventCount); - - // initialize event outputs (zero) - carla_zeroStruct(bufEvents.out, kEngineMaxInternalEventCount); - } - } - - oldAudioInCount = plugin->getAudioInCount(); - oldMidiOutCount = plugin->getMidiOutCount(); - - // process - plugin->initBuffers(); - plugin->process(inBuf, outBuf, frames); - plugin->unlock(); - - // if plugin has no audio inputs, add input buffer - if (oldAudioInCount == 0) - { - FLOAT_ADD(outBuf[0], inBuf0, frames); - FLOAT_ADD(outBuf[1], inBuf1, frames); - } - - // set peaks - { - EnginePluginData& pluginData(plugins[i]); - -#ifdef HAVE_JUCE - float tmpMin, tmpMax; - - if (oldAudioInCount > 0) - { - FloatVectorOperations::findMinAndMax(inBuf0, frames, tmpMin, tmpMax); - pluginData.insPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - - FloatVectorOperations::findMinAndMax(inBuf1, frames, tmpMin, tmpMax); - pluginData.insPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - } - else - { - pluginData.insPeak[0] = 0.0f; - pluginData.insPeak[1] = 0.0f; - } - - if (plugin->getAudioOutCount() > 0) - { - FloatVectorOperations::findMinAndMax(outBuf[0], frames, tmpMin, tmpMax); - pluginData.outsPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - - FloatVectorOperations::findMinAndMax(outBuf[1], frames, tmpMin, tmpMax); - pluginData.outsPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - } - else - { - pluginData.outsPeak[0] = 0.0f; - pluginData.outsPeak[1] = 0.0f; - } -#else - float peak1, peak2; - - if (oldAudioInCount > 0) - { - peak1 = peak2 = 0.0f; - - for (uint32_t k=0; k < frames; ++k) - { - peak1 = carla_max(peak1, std::fabs(inBuf0[k]), 1.0f); - peak2 = carla_max(peak2, std::fabs(inBuf1[k]), 1.0f); - } - - pluginData.insPeak[0] = peak1; - pluginData.insPeak[1] = peak2; - } - else - { - pluginData.insPeak[0] = 0.0f; - pluginData.insPeak[1] = 0.0f; - } - - if (plugin->getAudioOutCount() > 0) - { - peak1 = peak2 = 0.0f; - - for (uint32_t k=0; k < frames; ++k) - { - peak1 = carla_max(peak1, std::fabs(outBuf[0][k]), 1.0f); - peak2 = carla_max(peak2, std::fabs(outBuf[1][k]), 1.0f); - } - - pluginData.outsPeak[0] = peak1; - pluginData.outsPeak[1] = peak2; - } - else - { - pluginData.outsPeak[0] = 0.0f; - pluginData.outsPeak[1] = 0.0f; - } -#endif - } - - processed = true; - } -} - -void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) -{ - EngineRackBuffers* const rack(bufAudio.rack); - - const CarlaMutex::ScopedLocker sl(rack->connectLock); - - // connect input buffers - if (rack->connectedIns[0].count() == 0) - { - FLOAT_CLEAR(rack->in[0], nframes); - } - else - { - bool first = true; - - for (LinkedList::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < inCount); - - if (first) - { - FLOAT_COPY(rack->in[0], inBuf[port], nframes); - first = false; - } - else - { - FLOAT_ADD(rack->in[0], inBuf[port], nframes); - } - } - - if (first) - FLOAT_CLEAR(rack->in[0], nframes); - } - - if (rack->connectedIns[1].count() == 0) - { - FLOAT_CLEAR(rack->in[1], nframes); - } - else - { - bool first = true; - - for (LinkedList::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < inCount); - - if (first) - { - FLOAT_COPY(rack->in[1], inBuf[port], nframes); - first = false; - } - else - { - FLOAT_ADD(rack->in[1], inBuf[port], nframes); - } - } - - if (first) - FLOAT_CLEAR(rack->in[1], nframes); - } - - FLOAT_CLEAR(rack->out[0], nframes); - FLOAT_CLEAR(rack->out[1], nframes); - - // process - processRack(rack->in, rack->out, nframes, isOffline); - - // connect output buffers - if (rack->connectedOuts[0].count() != 0) - { - for (LinkedList::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < outCount); - - FLOAT_ADD(outBuf[port], rack->out[0], nframes); - } - } - - if (rack->connectedOuts[1].count() != 0) - { - for (LinkedList::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < outCount); - - FLOAT_ADD(outBuf[port], rack->out[1], nframes); - } - } -} -#endif - -// ----------------------------------------------------------------------- - -CarlaPlugin* CarlaPlugin::newGIG(const Initializer& init, const bool use16Outs) -{ - carla_debug("CarlaPlugin::newGIG({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs)); -#ifdef WANT_LINUXSAMPLER - return newLinuxSampler(init, "GIG", use16Outs); -#else - init.engine->setLastError("GIG support not available"); - return nullptr; - - // unused - (void)use16Outs; -#endif -} - -CarlaPlugin* CarlaPlugin::newSF2(const Initializer& init, const bool use16Outs) -{ - carla_debug("CarlaPlugin::newSF2({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs)); -#if defined(WANT_FLUIDSYNTH) - return newFluidSynth(init, use16Outs); -#elif defined(WANT_LINUXSAMPLER) - return newLinuxSampler(init, "SF2", use16Outs); -#else - init.engine->setLastError("SF2 support not available"); - return nullptr; - - // unused - (void)use16Outs; -#endif -} - -CarlaPlugin* CarlaPlugin::newSFZ(const Initializer& init, const bool use16Outs) -{ - carla_debug("CarlaPlugin::newSFZ({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs)); -#ifdef WANT_LINUXSAMPLER - return newLinuxSampler(init, "SFZ", use16Outs); -#else - init.engine->setLastError("SFZ support not available"); - return nullptr; - - // unused - (void)use16Outs; -#endif -} - -// ----------------------------------------------------------------------- -// Carla Engine port (Abstract) - -CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInput) - : fEngine(engine), - fIsInput(isInput) -{ - carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInput)); -} - -CarlaEnginePort::~CarlaEnginePort() -{ - carla_debug("CarlaEnginePort::~CarlaEnginePort()"); -} - -// ----------------------------------------------------------------------- -// Carla Engine Audio port - -CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInput) - : CarlaEnginePort(engine, isInput), - fBuffer(nullptr) -{ - carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); -} - -CarlaEngineAudioPort::~CarlaEngineAudioPort() -{ - carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()"); -} - -void CarlaEngineAudioPort::initBuffer() -{ -} - -// ----------------------------------------------------------------------- -// Carla Engine CV port - -CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput) - : CarlaEnginePort(engine, isInput), - fBuffer(nullptr), - fProcessMode(engine.getProccessMode()) -{ - carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput)); - - if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) - fBuffer = new float[engine.getBufferSize()]; -} - -CarlaEngineCVPort::~CarlaEngineCVPort() -{ - carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()"); - - if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) - { - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - - delete[] fBuffer; - fBuffer = nullptr; - } -} - -void CarlaEngineCVPort::initBuffer() -{ - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); - - FLOAT_CLEAR(fBuffer, fEngine.getBufferSize()); -} - -void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) -{ - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); - - delete[] fBuffer; - fBuffer = new float[bufferSize]; -} - -// ----------------------------------------------------------------------- -// Carla Engine Event port - -CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput) - : CarlaEnginePort(engine, isInput), - fBuffer(nullptr), - fProcessMode(engine.getProccessMode()) -{ - carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); - - if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) - fBuffer = new EngineEvent[kEngineMaxInternalEventCount]; -} - -CarlaEngineEventPort::~CarlaEngineEventPort() -{ - carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); - - if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) - { - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - - delete[] fBuffer; - fBuffer = nullptr; - } -} - -void CarlaEngineEventPort::initBuffer() -{ - if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE) - fBuffer = fEngine.getInternalEventBuffer(fIsInput); - else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput) - carla_zeroStruct(fBuffer, kEngineMaxInternalEventCount); -} - -uint32_t CarlaEngineEventPort::getEventCount() const -{ - CARLA_SAFE_ASSERT_RETURN(fIsInput, 0); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); - - uint32_t i=0; - - for (; i < kEngineMaxInternalEventCount; ++i) - { - if (fBuffer[i].type == kEngineEventTypeNull) - break; - } - - return i; -} - -const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) -{ - CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(index < kEngineMaxInternalEventCount, kFallbackEngineEvent); - - return fBuffer[index]; -} - -const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) -{ - return fBuffer[index]; -} - -bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) -{ - CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); - CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); - CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); - - if (type == kEngineControlEventTypeParameter) { - CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); - } - - const float fixedValue(carla_fixValue(0.0f, 1.0f, value)); - - for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i) - { - if (fBuffer[i].type != kEngineEventTypeNull) - continue; - - EngineEvent& event(fBuffer[i]); - - event.type = kEngineEventTypeControl; - event.time = time; - event.channel = channel; - - event.ctrl.type = type; - event.ctrl.param = param; - event.ctrl.value = fixedValue; - - return true; - } - - carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full"); - return false; -} - -bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) -{ - CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); - CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); - CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); - - for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i) - { - if (fBuffer[i].type != kEngineEventTypeNull) - continue; - - EngineEvent& event(fBuffer[i]); - - event.type = kEngineEventTypeMidi; - event.time = time; - event.channel = channel; - - event.midi.port = port; - event.midi.size = size; - - event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data)); - - uint8_t j=1; - for (; j < size; ++j) - event.midi.data[j] = data[j]; - for (; j < EngineMidiEvent::kDataSize; ++j) - event.midi.data[j] = 0; - - return true; - } - - carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full"); - return false; -} +#endif // ----------------------------------------------------------------------- // Carla Engine client (Abstract) @@ -1008,8 +346,8 @@ bool CarlaEngine::init(const char* const clientName) case ENGINE_PROCESS_MODE_CONTINUOUS_RACK: pData->maxPluginNumber = MAX_RACK_PLUGINS; - pData->bufEvents.in = new EngineEvent[kEngineMaxInternalEventCount]; - pData->bufEvents.out = new EngineEvent[kEngineMaxInternalEventCount]; + pData->bufEvents.in = new EngineEvent[EngineEvent::kMaxInternalCount]; + pData->bufEvents.out = new EngineEvent[EngineEvent::kMaxInternalCount]; break; case ENGINE_PROCESS_MODE_PATCHBAY: @@ -1018,8 +356,8 @@ bool CarlaEngine::init(const char* const clientName) case ENGINE_PROCESS_MODE_BRIDGE: pData->maxPluginNumber = 1; - pData->bufEvents.in = new EngineEvent[kEngineMaxInternalEventCount]; - pData->bufEvents.out = new EngineEvent[kEngineMaxInternalEventCount]; + pData->bufEvents.in = new EngineEvent[EngineEvent::kMaxInternalCount]; + pData->bufEvents.out = new EngineEvent[EngineEvent::kMaxInternalCount]; break; } @@ -1925,200 +1263,6 @@ void CarlaEngine::setCallback(const EngineCallbackFunc func, void* const ptr) no pData->callbackPtr = ptr; } -#ifndef BUILD_BRIDGE -// ----------------------------------------------------------------------- -// Patchbay - -bool CarlaEngine::patchbayConnect(const int portA, const int portB) -{ - CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); - CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); - carla_debug("CarlaEngineRtAudio::patchbayConnect(%i, %i)", portA, portB); - - if (pData->bufAudio.usePatchbay) - { - // not implemented yet - return false; - } - - EngineRackBuffers* const rack(pData->bufAudio.rack); - - CARLA_SAFE_ASSERT_RETURN_ERR(portA > RACK_PATCHBAY_PORT_MAX, "Invalid output port"); - CARLA_SAFE_ASSERT_RETURN_ERR(portB > RACK_PATCHBAY_PORT_MAX, "Invalid input port"); - - // only allow connections between Carla and other ports - if (portA < 0 && portB < 0) - { - setLastError("Invalid connection (1)"); - return false; - } - if (portA >= 0 && portB >= 0) - { - setLastError("Invalid connection (2)"); - return false; - } - - const int carlaPort = (portA < 0) ? portA : portB; - const int targetPort = (carlaPort == portA) ? portB : portA; - bool makeConnection = false; - - switch (carlaPort) - { - case RACK_PATCHBAY_PORT_AUDIO_IN1: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); - rack->connectLock.lock(); - rack->connectedIns[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_AUDIO_IN2: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); - rack->connectLock.lock(); - rack->connectedIns[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_AUDIO_OUT1: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); - rack->connectLock.lock(); - rack->connectedOuts[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_AUDIO_OUT2: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); - rack->connectLock.lock(); - rack->connectedOuts[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_MIDI_IN: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_IN*1000+999); - makeConnection = connectRackMidiInPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_IN*1000); - break; - - case RACK_PATCHBAY_PORT_MIDI_OUT: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_OUT*1000+999); - makeConnection = connectRackMidiOutPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_OUT*1000); - break; - } - - if (! makeConnection) - { - setLastError("Invalid connection (3)"); - return false; - } - - ConnectionToId connectionToId; - connectionToId.id = rack->lastConnectionId; - connectionToId.portOut = portA; - connectionToId.portIn = portB; - - callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, portA, portB, 0.0f, nullptr); - - rack->usedConnections.append(connectionToId); - rack->lastConnectionId++; - - return true; -} - -bool CarlaEngine::patchbayDisconnect(const int connectionId) -{ - CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); - CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); - carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); - - if (pData->bufAudio.usePatchbay) - { - // not implemented yet - return false; - } - - EngineRackBuffers* const rack(pData->bufAudio.rack); - - CARLA_SAFE_ASSERT_RETURN_ERR(rack->usedConnections.count() > 0, "No connections available"); - - for (LinkedList::Itenerator it=rack->usedConnections.begin(); it.valid(); it.next()) - { - const ConnectionToId& connection(it.getValue()); - - if (connection.id == connectionId) - { - const int targetPort((connection.portOut >= 0) ? connection.portOut : connection.portIn); - const int carlaPort((targetPort == connection.portOut) ? connection.portIn : connection.portOut); - - if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000) - { - const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000); - disconnectRackMidiInPort(portId); - } - else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000) - { - const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000); - disconnectRackMidiOutPort(portId); - } - else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000) - { - CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2, false); - - const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - - rack->connectLock.lock(); - - if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1) - rack->connectedOuts[0].removeAll(portId); - else - rack->connectedOuts[1].removeAll(portId); - - rack->connectLock.unlock(); - } - else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000) - { - CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2, false); - - const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - - rack->connectLock.lock(); - - if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1) - rack->connectedIns[0].removeAll(portId); - else - rack->connectedIns[1].removeAll(portId); - - rack->connectLock.unlock(); - } - else - { - CARLA_SAFE_ASSERT_RETURN(false, false); - } - - callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, connection.portOut, connection.portIn, 0.0f, nullptr); - - rack->usedConnections.remove(it); - break; - } - } - - return true; -} - -bool CarlaEngine::patchbayRefresh() -{ - setLastError("Unsupported operation"); - return false; -} -#endif - // ----------------------------------------------------------------------- // Transport @@ -2256,45 +1400,6 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch } } -// ----------------------------------------------------------------------- -// OSC Stuff - -#ifdef BUILD_BRIDGE -bool CarlaEngine::isOscBridgeRegistered() const noexcept -{ - return (pData->oscData != nullptr); -} -#else -bool CarlaEngine::isOscControlRegistered() const noexcept -{ - return pData->osc.isControlRegistered(); -} -#endif - -void CarlaEngine::idleOsc() const noexcept -{ - try { - pData->osc.idle(); - } catch(...) {} -} - -const char* CarlaEngine::getOscServerPathTCP() const noexcept -{ - return pData->osc.getServerPathTCP(); -} - -const char* CarlaEngine::getOscServerPathUDP() const noexcept -{ - return pData->osc.getServerPathUDP(); -} - -#ifdef BUILD_BRIDGE -void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) const noexcept -{ - pData->oscData = oscData; -} -#endif - // ----------------------------------------------------------------------- // Helper functions @@ -2382,673 +1487,5 @@ void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeak } // ----------------------------------------------------------------------- -// Bridge/Controller OSC stuff - -#ifdef BUILD_BRIDGE -void CarlaEngine::oscSend_bridge_plugin_info1(const PluginCategory category, const uint hints, const long uniqueId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_plugin_info1(%i:%s, %X, %l)", category, PluginCategory2Str(category), hints, uniqueId); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_plugin_info1"); - try_lo_send(pData->oscData->target, targetPath, "iih", static_cast(category), static_cast(hints), static_cast(uniqueId)); -} - -void CarlaEngine::oscSend_bridge_plugin_info2(const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); - CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_plugin_info2(\"%s\", \"%s\", \"%s\", \"%s\")", realName, label, maker, copyright); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_plugin_info2"); - try_lo_send(pData->oscData->target, targetPath, "ssss", realName, label, maker, copyright); -} - -void CarlaEngine::oscSend_bridge_audio_count(const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_audio_count(%i, %i)", ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_audio_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_bridge_midi_count(const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_midi_count(%i, %i)", ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_midi_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_bridge_parameter_count(const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_count(%i, %i)", ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_bridge_program_count(const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_program_count(%i)", count); - - char targetPath[std::strlen(pData->oscData->path)+22]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_program_count"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); -} - -void CarlaEngine::oscSend_bridge_midi_program_count(const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_midi_program_count(%i)", count); - - char targetPath[std::strlen(pData->oscData->path)+27]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_midi_program_count"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); -} - -void CarlaEngine::oscSend_bridge_parameter_data(const uint32_t index, const int32_t rindex, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", index, rindex, type, ParameterType2Str(type), hints, name, unit); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(index), static_cast(rindex), static_cast(type), static_cast(hints), name, unit); -} - -void CarlaEngine::oscSend_bridge_parameter_ranges1(const uint32_t index, const float def, const float min, const float max) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, def, min, max); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_ranges1"); - try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), def, min, max); -} - -void CarlaEngine::oscSend_bridge_parameter_ranges2(const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, step, stepSmall, stepLarge); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_ranges2"); - try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), step, stepSmall, stepLarge); -} - -void CarlaEngine::oscSend_bridge_parameter_midi_cc(const uint32_t index, const int16_t cc) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_cc(%i, %i)", index, cc); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_midi_cc"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(cc)); -} - -void CarlaEngine::oscSend_bridge_parameter_midi_channel(const uint32_t index, const uint8_t channel) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_channel(%i, %i)", index, channel); - - char targetPath[std::strlen(pData->oscData->path)+31]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_midi_channel"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(channel)); -} - -void CarlaEngine::oscSend_bridge_parameter_value(const int32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_value(%i, %f)", index, value); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_value"); - try_lo_send(pData->oscData->target, targetPath, "if", index, value); -} - -void CarlaEngine::oscSend_bridge_default_value(const uint32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_default_value(%i, %f)", index, value); - - char targetPath[std::strlen(pData->oscData->path)+22]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_default_value"); - try_lo_send(pData->oscData->target, targetPath, "if", static_cast(index), value); -} - -void CarlaEngine::oscSend_bridge_current_program(const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_current_program(%i)", index); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_current_program"); - try_lo_send(pData->oscData->target, targetPath, "i", index); -} - -void CarlaEngine::oscSend_bridge_current_midi_program(const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_current_midi_program(%i)", index); - - char targetPath[std::strlen(pData->oscData->path)+25]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_current_midi_program"); - try_lo_send(pData->oscData->target, targetPath, "i", index); -} - -void CarlaEngine::oscSend_bridge_program_name(const uint32_t index, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_program_name(%i, \"%s\")", index, name); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_program_name"); - try_lo_send(pData->oscData->target, targetPath, "is", static_cast(index), name); -} - -void CarlaEngine::oscSend_bridge_midi_program_data(const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_midi_program_data(%i, %i, %i, \"%s\")", index, bank, program, name); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_midi_program_data"); - try_lo_send(pData->oscData->target, targetPath, "iiis", static_cast(index), static_cast(bank), static_cast(program), name); -} - -void CarlaEngine::oscSend_bridge_configure(const char* const key, const char* const value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(value != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_configure(\"%s\", \"%s\")", key, value); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_configure"); - try_lo_send(pData->oscData->target, targetPath, "ss", key, value); -} - -void CarlaEngine::oscSend_bridge_set_custom_data(const char* const type, const char* const key, const char* const value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_set_custom_data(\"%s\", \"%s\", \"%s\")", type, key, value); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_set_custom_data"); - try_lo_send(pData->oscData->target, targetPath, "sss", type, key, value); -} - -void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(chunkFile != nullptr && chunkFile[0] != '\0',); - carla_debug("CarlaEngine::oscSend_bridge_set_chunk_data(\"%s\")", chunkFile); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_set_chunk_data"); - try_lo_send(pData->oscData->target, targetPath, "s", chunkFile); -} - -// TODO? -//void oscSend_bridge_set_peaks() const; - -#else -void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',); - carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/add_plugin_start"); - try_lo_send(pData->oscData->target, targetPath, "is", static_cast(pluginId), pluginName); -} - -void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId); - - char targetPath[std::strlen(pData->oscData->path)+16]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/add_plugin_end"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); -} - -void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId); - - char targetPath[std::strlen(pData->oscData->path)+15]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/remove_plugin"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); -} - -void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const long uniqueId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,); - carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, %l)", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_plugin_info1"); - try_lo_send(pData->oscData->target, targetPath, "iiiih", static_cast(pluginId), static_cast(type), static_cast(category), static_cast(hints), static_cast(uniqueId)); -} - -void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); - CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_plugin_info2"); - try_lo_send(pData->oscData->target, targetPath, "issss", static_cast(pluginId), realName, label, maker, copyright); -} - -void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_audio_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_program_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); -} - -void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_program_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); -} - -void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(pluginId), static_cast(index), static_cast(type), static_cast(hints), name, unit); -} - -void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(def <= min && def >= max,); - CARLA_SAFE_ASSERT_RETURN(min < max,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_ranges1"); - try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), def, min, max); -} - -void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(step <= stepSmall && step >= stepLarge,); - CARLA_SAFE_ASSERT_RETURN(stepSmall <= stepLarge,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_ranges"); - try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), step, stepSmall, stepLarge); -} - -void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(cc <= 0x5F,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_midi_cc"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(cc)); -} - -void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); - - char targetPath[std::strlen(pData->oscData->path)+28]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_midi_channel"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(channel)); -} - -void CarlaEngine::oscSend_control_set_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_value(%i, %i:%s, %f)", pluginId, index, (index < 0) ? InternalParameterIndex2Str(static_cast(index)) : "(none)", value); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_value"); - try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), index, value); -} - -void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_default_value"); - try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), static_cast(index), value); -} - -void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_current_program"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); -} - -void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_current_midi_program"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); -} - -void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_program_name"); - try_lo_send(pData->oscData->target, targetPath, "iis", static_cast(pluginId), static_cast(index), name); -} - -void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_program_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiis", static_cast(pluginId), static_cast(index), static_cast(bank), static_cast(program), name); -} - -void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,); - carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); - - char targetPath[std::strlen(pData->oscData->path)+9]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/note_on"); - try_lo_send(pData->oscData->target, targetPath, "iiii", static_cast(pluginId), static_cast(channel), static_cast(note), static_cast(velo)); -} - -void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note); - - char targetPath[std::strlen(pData->oscData->path)+10]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/note_off"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(channel), static_cast(note)); -} - -void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - - // TODO - try and see if we can get peaks[4] ref - const EnginePluginData& epData(pData->plugins[pluginId]); - - char targetPath[std::strlen(pData->oscData->path)+11]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_peaks"); - try_lo_send(pData->oscData->target, targetPath, "iffff", static_cast(pluginId), epData.insPeak[0], epData.insPeak[1], epData.outsPeak[0], epData.outsPeak[1]); -} - -void CarlaEngine::oscSend_control_exit() const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_control_exit()"); - - char targetPath[std::strlen(pData->oscData->path)+6]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/exit"); - try_lo_send(pData->oscData->target, targetPath, ""); -} -#endif - -// ----------------------------------------------------------------------- - -#undef CARLA_SAFE_ASSERT_RETURN_ERR CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngineBridge.cpp b/source/backend/engine/CarlaEngineBridge.cpp index 789ae9f65..e9a15fbd1 100644 --- a/source/backend/engine/CarlaEngineBridge.cpp +++ b/source/backend/engine/CarlaEngineBridge.cpp @@ -1,6 +1,6 @@ /* - * Carla Engine Bridge - * Copyright (C) 2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index 0afe09a93..c49672e95 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -1,6 +1,6 @@ /* - * Carla Engine - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -21,15 +21,8 @@ #include "CarlaEngine.hpp" #include "CarlaEngineOsc.hpp" #include "CarlaEngineThread.hpp" -#include "CarlaPlugin.hpp" #include "CarlaMutex.hpp" -#include "LinkedList.hpp" - -#ifdef HAVE_JUCE -# include "juce_audio_basics.h" -using juce::FloatVectorOperations; -#endif // ----------------------------------------------------------------------- // Engine helper macro, sets lastError and returns false/NULL @@ -60,114 +53,6 @@ CARLA_BACKEND_START_NAMESPACE // ----------------------------------------------------------------------- -static inline -const char* EngineType2Str(const EngineType type) noexcept -{ - switch (type) - { - case kEngineTypeNull: - return "kEngineTypeNull"; - case kEngineTypeJack: - return "kEngineTypeJack"; - case kEngineTypeJuce: - return "kEngineTypeJuce"; - case kEngineTypeRtAudio: - return "kEngineTypeRtAudio"; - case kEngineTypePlugin: - return "kEngineTypePlugin"; - case kEngineTypeBridge: - return "kEngineTypeBridge"; - } - - carla_stderr("CarlaBackend::EngineType2Str(%i) - invalid type", type); - return nullptr; -} - -static inline -const char* EnginePortType2Str(const EnginePortType type) noexcept -{ - switch (type) - { - case kEnginePortTypeNull: - return "kEnginePortTypeNull"; - case kEnginePortTypeAudio: - return "kEnginePortTypeAudio"; - case kEnginePortTypeCV: - return "kEnginePortTypeCV"; - case kEnginePortTypeEvent: - return "kEnginePortTypeEvent"; - } - - carla_stderr("CarlaBackend::EnginePortType2Str(%i) - invalid type", type); - return nullptr; -} - -static inline -const char* EngineEventType2Str(const EngineEventType type) noexcept -{ - switch (type) - { - case kEngineEventTypeNull: - return "kEngineEventTypeNull"; - case kEngineEventTypeControl: - return "kEngineEventTypeControl"; - case kEngineEventTypeMidi: - return "kEngineEventTypeMidi"; - } - - carla_stderr("CarlaBackend::EngineEventType2Str(%i) - invalid type", type); - return nullptr; -} - -static inline -const char* EngineControlEventType2Str(const EngineControlEventType type) noexcept -{ - switch (type) - { - case kEngineControlEventTypeNull: - return "kEngineNullEvent"; - case kEngineControlEventTypeParameter: - return "kEngineControlEventTypeParameter"; - case kEngineControlEventTypeMidiBank: - return "kEngineControlEventTypeMidiBank"; - case kEngineControlEventTypeMidiProgram: - return "kEngineControlEventTypeMidiProgram"; - case kEngineControlEventTypeAllSoundOff: - return "kEngineControlEventTypeAllSoundOff"; - case kEngineControlEventTypeAllNotesOff: - return "kEngineControlEventTypeAllNotesOff"; - } - - carla_stderr("CarlaBackend::EngineControlEventType2Str(%i) - invalid type", type); - return nullptr; -} - -// ----------------------------------------------------------------------- - -const unsigned short kEngineMaxInternalEventCount = 512; - -enum EnginePostAction { - kEnginePostActionNull, - kEnginePostActionZeroCount, - kEnginePostActionRemovePlugin, - kEnginePostActionSwitchPlugins -}; - -struct EnginePluginData { - CarlaPlugin* plugin; - float insPeak[2]; - float outsPeak[2]; - - void clear() noexcept - { - plugin = nullptr; - insPeak[0] = insPeak[1] = 0.0f; - outsPeak[0] = outsPeak[1] = 0.0f; - } -}; - -// ----------------------------------------------------------------------- - enum RackPatchbayGroupIds { RACK_PATCHBAY_GROUP_CARLA = -1, RACK_PATCHBAY_GROUP_AUDIO_IN = 0, @@ -200,101 +85,77 @@ struct ConnectionToId { // ----------------------------------------------------------------------- -struct EngineRackBuffers { - float* in[2]; - float* out[2]; +struct EngineRackBuffers; +struct EnginePatchbayBuffers; - // connections stuff - LinkedList connectedIns[2]; - LinkedList connectedOuts[2]; - CarlaMutex connectLock; +struct InternalAudio { + bool isReady; + bool usePatchbay; - int lastConnectionId; - LinkedList usedConnections; + uint inCount; + uint outCount; - EngineRackBuffers(const uint32_t bufferSize) - : lastConnectionId(0) - { - resize(bufferSize); - } + union { + EngineRackBuffers* rack; + EnginePatchbayBuffers* patchbay; + }; - ~EngineRackBuffers() - { - clear(); - } + InternalAudio() noexcept; + ~InternalAudio() noexcept; + void initPatchbay() noexcept; + void clear(); + void create(const uint32_t bufferSize); + void resize(const uint32_t bufferSize); +}; - void clear() - { - lastConnectionId = 0; - - if (in[0] != nullptr) - { - delete[] in[0]; - in[0] = nullptr; - } - - if (in[1] != nullptr) - { - delete[] in[1]; - in[1] = nullptr; - } - - if (out[0] != nullptr) - { - delete[] out[0]; - out[0] = nullptr; - } - - if (out[1] != nullptr) - { - delete[] out[1]; - out[1] = nullptr; - } - - connectedIns[0].clear(); - connectedIns[1].clear(); - connectedOuts[0].clear(); - connectedOuts[1].clear(); - usedConnections.clear(); - } - - void resize(const uint32_t bufferSize) - { - if (bufferSize > 0) - { - in[0] = new float[bufferSize]; - in[1] = new float[bufferSize]; - out[0] = new float[bufferSize]; - out[1] = new float[bufferSize]; - } - else - { - in[0] = nullptr; - in[1] = nullptr; - out[0] = nullptr; - out[1] = nullptr; - } - } +// ----------------------------------------------------------------------- + +struct InternalEvents { + EngineEvent* in; + EngineEvent* out; + + InternalEvents() noexcept; + ~InternalEvents() noexcept; + void allocateEvents(); }; -struct EnginePatchbayBuffers { - EnginePatchbayBuffers(const uint32_t bufferSize) - { - resize(bufferSize); - } +// ----------------------------------------------------------------------- - ~EnginePatchbayBuffers() - { - clear(); - } +struct InternalTime { + bool playing; + uint64_t frame; - void clear() - { - } + InternalTime() noexcept; +}; - void resize(const uint32_t /*bufferSize*/) - { - } +// ----------------------------------------------------------------------- + +enum EnginePostAction { + kEnginePostActionNull, + kEnginePostActionZeroCount, + kEnginePostActionRemovePlugin, + kEnginePostActionSwitchPlugins +}; + +struct NextAction { + EnginePostAction opcode; + unsigned int pluginId; + unsigned int value; + CarlaMutex mutex; + + NextAction() noexcept; + ~NextAction() noexcept; + void ready() noexcept; +}; + +// ----------------------------------------------------------------------- + +struct EnginePluginData { + CarlaPlugin* plugin; + float insPeak[2]; + float outsPeak[2]; + + void clear() noexcept; }; // ----------------------------------------------------------------------- @@ -325,253 +186,18 @@ struct CarlaEngineProtectedData { EnginePluginData* plugins; #ifndef BUILD_BRIDGE - struct InternalAudio { - bool isReady; - bool usePatchbay; - - uint inCount; - uint outCount; - - union { - EngineRackBuffers* rack; - EnginePatchbayBuffers* patchbay; - }; - - InternalAudio() noexcept - : isReady(false), - usePatchbay(false), - inCount(0), - outCount(0) - { - rack = nullptr; - } - - ~InternalAudio() noexcept - { - CARLA_ASSERT(! isReady); - CARLA_ASSERT(rack == nullptr); - } - - void initPatchbay() noexcept - { - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); - - rack->lastConnectionId = 0; - rack->usedConnections.clear(); - } - } - - void clear() - { - isReady = false; - inCount = 0; - outCount = 0; - - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); - delete patchbay; - patchbay = nullptr; - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); - delete rack; - rack = nullptr; - } - } - - void create(const uint32_t bufferSize) - { - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay == nullptr,); - patchbay = new EnginePatchbayBuffers(bufferSize); - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack == nullptr,); - rack = new EngineRackBuffers(bufferSize); - } - - isReady = true; - } - - void resize(const uint32_t bufferSize) - { - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); - patchbay->resize(bufferSize); - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); - rack->resize(bufferSize); - } - } - } bufAudio; + InternalAudio bufAudio; #endif + InternalEvents bufEvents; + InternalTime time; + NextAction nextAction; - struct InternalEvents { - EngineEvent* in; - EngineEvent* out; - - InternalEvents() noexcept - : in(nullptr), - out(nullptr) {} - - ~InternalEvents() noexcept - { - CARLA_ASSERT(in == nullptr); - CARLA_ASSERT(out == nullptr); - } - } bufEvents; - - struct InternalTime { - bool playing; - uint64_t frame; - - InternalTime() noexcept - : playing(false), - frame(0) {} - } time; - - struct NextAction { - EnginePostAction opcode; - unsigned int pluginId; - unsigned int value; - CarlaMutex mutex; - - NextAction() noexcept - : opcode(kEnginePostActionNull), - pluginId(0), - value(0) {} - - ~NextAction() noexcept - { - CARLA_ASSERT(opcode == kEnginePostActionNull); - } - - void ready() noexcept - { - mutex.lock(); - mutex.unlock(); - } - } nextAction; - - CarlaEngineProtectedData(CarlaEngine* const engine) - : osc(engine), - thread(engine), - oscData(nullptr), - callback(nullptr), - callbackPtr(nullptr), - hints(0x0), - bufferSize(0), - sampleRate(0.0), - aboutToClose(false), - curPluginCount(0), - maxPluginNumber(0), - nextPluginId(0), - plugins(nullptr) {} - -#ifdef CARLA_PROPER_CPP11_SUPPORT - CarlaEngineProtectedData() = delete; - CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData) -#endif - - ~CarlaEngineProtectedData() noexcept - { - CARLA_ASSERT(curPluginCount == 0); - CARLA_ASSERT(maxPluginNumber == 0); - CARLA_ASSERT(nextPluginId == 0); - CARLA_ASSERT(plugins == nullptr); - } - - void doPluginRemove() noexcept - { - CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,); - CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,); - --curPluginCount; - - // move all plugins 1 spot backwards - for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i) - { - CarlaPlugin* const plugin(plugins[i+1].plugin); - - CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); - - plugin->setId(i); - - plugins[i].plugin = plugin; - plugins[i].insPeak[0] = 0.0f; - plugins[i].insPeak[1] = 0.0f; - plugins[i].outsPeak[0] = 0.0f; - plugins[i].outsPeak[1] = 0.0f; - } - - const unsigned int id(curPluginCount); + CarlaEngineProtectedData(CarlaEngine* const engine); + ~CarlaEngineProtectedData() noexcept; - // reset last plugin (now removed) - plugins[id].plugin = nullptr; - plugins[id].insPeak[0] = 0.0f; - plugins[id].insPeak[1] = 0.0f; - plugins[id].outsPeak[0] = 0.0f; - plugins[id].outsPeak[1] = 0.0f; - } - - void doPluginsSwitch() noexcept - { - CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,); - - const unsigned int idA(nextAction.pluginId); - const unsigned int idB(nextAction.value); - - CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,); - CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,); - -#if 0 - std::swap(plugins[idA].plugin, plugins[idB].plugin); -#else - CarlaPlugin* const tmp(plugins[idA].plugin); - - plugins[idA].plugin = plugins[idB].plugin; - plugins[idB].plugin = tmp; -#endif - } - - void doNextPluginAction(const bool unlock) noexcept - { - switch (nextAction.opcode) - { - case kEnginePostActionNull: - break; - case kEnginePostActionZeroCount: - curPluginCount = 0; - break; - case kEnginePostActionRemovePlugin: - doPluginRemove(); - break; - case kEnginePostActionSwitchPlugins: - doPluginsSwitch(); - break; - } - - nextAction.opcode = kEnginePostActionNull; - nextAction.pluginId = 0; - nextAction.value = 0; - - if (unlock) - nextAction.mutex.unlock(); - } + void doPluginRemove() noexcept; + void doPluginsSwitch() noexcept; + void doNextPluginAction(const bool unlock) noexcept; #ifndef BUILD_BRIDGE // the base, where plugins run @@ -584,38 +210,20 @@ struct CarlaEngineProtectedData { class ScopedActionLock { public: - ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept - : fData(data) - { - fData->nextAction.mutex.lock(); - - CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,); - - fData->nextAction.opcode = action; - fData->nextAction.pluginId = pluginId; - fData->nextAction.value = value; - - if (lockWait) - { - // block wait for unlock on processing side - carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); - fData->nextAction.mutex.lock(); - carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); - } - else - { - fData->doNextPluginAction(false); - } - } - - ~ScopedActionLock() noexcept - { - fData->nextAction.mutex.unlock(); - } + ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept; + ~ScopedActionLock() noexcept; private: CarlaEngineProtectedData* const fData; + + CARLA_PREVENT_HEAP_ALLOCATION + CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock) }; + +#ifdef CARLA_PROPER_CPP11_SUPPORT + CarlaEngineProtectedData() = delete; + CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData) +#endif }; // ----------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngineJack.cpp b/source/backend/engine/CarlaEngineJack.cpp index 17dadc224..ae7ef13d9 100644 --- a/source/backend/engine/CarlaEngineJack.cpp +++ b/source/backend/engine/CarlaEngineJack.cpp @@ -1,6 +1,6 @@ /* - * Carla JACK Engine - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -16,12 +16,22 @@ */ #include "CarlaEngineInternal.hpp" +#include "CarlaPlugin.hpp" + #include "CarlaBackendUtils.hpp" +#include "CarlaEngineUtils.hpp" +#include "CarlaMIDI.h" +#include "LinkedList.hpp" #include "jackbridge/JackBridge.hpp" #include +#ifdef HAVE_JUCE +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif + #include #define URI_CANVAS_ICON "http://kxstudio.sf.net/ns/canvas/icon" @@ -200,7 +210,7 @@ public: jackbridge_midi_clear_buffer(fJackBuffer); } - uint32_t getEventCount() const override + uint32_t getEventCount() const noexcept override { if (fPort == nullptr) return CarlaEngineEventPort::getEventCount(); @@ -211,7 +221,7 @@ public: return jackbridge_midi_get_event_count(fJackBuffer); } - const EngineEvent& getEvent(const uint32_t index) override + const EngineEvent& getEvent(const uint32_t index) noexcept override { if (fPort == nullptr) return CarlaEngineEventPort::getEvent(index); @@ -222,7 +232,7 @@ public: return getEventUnchecked(index); } - const EngineEvent& getEventUnchecked(const uint32_t index) override + const EngineEvent& getEventUnchecked(const uint32_t index) noexcept override { jack_midi_event_t jackEvent; @@ -1112,7 +1122,7 @@ protected: float* outBuf[2] = { audioOut1, audioOut2 }; // initialize input events - carla_zeroStruct(pData->bufEvents.in, kEngineMaxInternalEventCount); + carla_zeroStruct(pData->bufEvents.in, EngineEvent::kMaxInternalCount); { uint32_t engineEventIndex = 0; @@ -1131,7 +1141,7 @@ protected: engineEvent.time = jackEvent.time; engineEvent.fillFromMidiData(static_cast(jackEvent.size), jackEvent.buffer); - if (engineEventIndex >= kEngineMaxInternalEventCount) + if (engineEventIndex >= EngineEvent::kMaxInternalCount) break; } } @@ -1143,7 +1153,7 @@ protected: { jackbridge_midi_clear_buffer(eventOut); - for (unsigned short i=0; i < kEngineMaxInternalEventCount; ++i) + for (unsigned short i=0; i < EngineEvent::kMaxInternalCount; ++i) { const EngineEvent& engineEvent(pData->bufEvents.out[i]); diff --git a/source/backend/engine/CarlaEngineJuce.cpp b/source/backend/engine/CarlaEngineJuce.cpp index 0b0cb891e..e02408d41 100644 --- a/source/backend/engine/CarlaEngineJuce.cpp +++ b/source/backend/engine/CarlaEngineJuce.cpp @@ -1,6 +1,6 @@ /* - * Carla Juce Engine - * Copyright (C) 2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -220,7 +220,7 @@ public: char strBuf[STR_MAX+1]; strBuf[STR_MAX] = '\0'; - EngineRackBuffers* const rack(pData->bufAudio.rack); + //EngineRackBuffers* const rack(pData->bufAudio.rack); // Main { @@ -318,6 +318,7 @@ public: } #endif +#if 0 // Connections rack->connectLock.lock(); @@ -417,6 +418,7 @@ public: rack->usedConnections.append(connectionToId); rack->lastConnectionId++; } +#endif #endif return true; @@ -437,7 +439,7 @@ protected: return runPendingRtEvents(); // initialize input events - carla_zeroStruct(pData->bufEvents.in, kEngineMaxInternalEventCount); + carla_zeroStruct(pData->bufEvents.in, EngineEvent::kMaxInternalCount); // TODO - get events from juce diff --git a/source/backend/engine/CarlaEngineNative.cpp b/source/backend/engine/CarlaEngineNative.cpp index 786c0518b..38a4654f6 100644 --- a/source/backend/engine/CarlaEngineNative.cpp +++ b/source/backend/engine/CarlaEngineNative.cpp @@ -1,6 +1,6 @@ /* - * Carla Plugin Engine (Native) - * Copyright (C) 2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -25,10 +25,16 @@ #endif #include "CarlaEngineInternal.hpp" +#include "CarlaPlugin.hpp" + +#include "CarlaNative.hpp" #include "CarlaPipeUtils.hpp" #include "CarlaStateUtils.hpp" -#include "CarlaNative.hpp" +#ifdef HAVE_JUCE +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif #include @@ -1053,8 +1059,8 @@ protected: // --------------------------------------------------------------- // initialize events - carla_zeroStruct(pData->bufEvents.in, kEngineMaxInternalEventCount); - carla_zeroStruct(pData->bufEvents.out, kEngineMaxInternalEventCount); + carla_zeroStruct(pData->bufEvents.in, EngineEvent::kMaxInternalCount); + carla_zeroStruct(pData->bufEvents.out, EngineEvent::kMaxInternalCount); // --------------------------------------------------------------- // events input (before processing) @@ -1062,7 +1068,7 @@ protected: { uint32_t engineEventIndex = 0; - for (uint32_t i=0; i < midiEventCount && engineEventIndex < kEngineMaxInternalEventCount; ++i) + for (uint32_t i=0; i < midiEventCount && engineEventIndex < EngineEvent::kMaxInternalCount; ++i) { const NativeMidiEvent& midiEvent(midiEvents[i]); EngineEvent& engineEvent(pData->bufEvents.in[engineEventIndex++]); @@ -1070,7 +1076,7 @@ protected: engineEvent.time = midiEvent.time; engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data); - if (engineEventIndex >= kEngineMaxInternalEventCount) + if (engineEventIndex >= EngineEvent::kMaxInternalCount) break; } } @@ -1106,12 +1112,12 @@ protected: // --------------------------------------------------------------- // events output (after processing) - carla_zeroStruct(pData->bufEvents.in, kEngineMaxInternalEventCount); + carla_zeroStruct(pData->bufEvents.in, EngineEvent::kMaxInternalCount); { NativeMidiEvent midiEvent; - for (uint32_t i=0; i < kEngineMaxInternalEventCount; ++i) + for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) { const EngineEvent& engineEvent(pData->bufEvents.out[i]); diff --git a/source/backend/engine/CarlaEngineOsc.cpp b/source/backend/engine/CarlaEngineOsc.cpp index d2fd98655..8079aa5cd 100644 --- a/source/backend/engine/CarlaEngineOsc.cpp +++ b/source/backend/engine/CarlaEngineOsc.cpp @@ -1,6 +1,6 @@ /* - * Carla Engine OSC - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,15 +15,16 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#include "CarlaEngineOsc.hpp" - #include "CarlaEngine.hpp" +#include "CarlaEngineOsc.hpp" #include "CarlaPlugin.hpp" #ifndef BUILD_BRIDGE # include "CarlaBridgeUtils.hpp" #endif +#include "CarlaMIDI.h" + CARLA_BACKEND_START_NAMESPACE #ifndef BUILD_BRIDGE diff --git a/source/backend/engine/CarlaEngineOsc.hpp b/source/backend/engine/CarlaEngineOsc.hpp index b27cc1248..8e9dad2e8 100644 --- a/source/backend/engine/CarlaEngineOsc.hpp +++ b/source/backend/engine/CarlaEngineOsc.hpp @@ -1,6 +1,6 @@ /* - * Carla Engine OSC - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/source/backend/engine/CarlaEngineRtAudio.cpp b/source/backend/engine/CarlaEngineRtAudio.cpp index c24dfbf6e..1e25526e6 100644 --- a/source/backend/engine/CarlaEngineRtAudio.cpp +++ b/source/backend/engine/CarlaEngineRtAudio.cpp @@ -1,6 +1,6 @@ /* - * Carla RtAudio Engine - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -23,6 +23,11 @@ #include "rtaudio/RtAudio.h" #include "rtmidi/RtMidi.h" +#ifdef HAVE_JUCE +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif + CARLA_BACKEND_START_NAMESPACE #if 0 @@ -418,7 +423,7 @@ public: char strBuf[STR_MAX+1]; strBuf[STR_MAX] = '\0'; - EngineRackBuffers* const rack(pData->bufAudio.rack); + //EngineRackBuffers* const rack(pData->bufAudio.rack); // Main { @@ -496,6 +501,7 @@ public: } #endif +#if 0 // Connections rack->connectLock.lock(); @@ -594,6 +600,7 @@ public: rack->usedConnections.append(connectionToId); rack->lastConnectionId++; } +#endif return true; } @@ -636,7 +643,7 @@ protected: FLOAT_CLEAR(fAudioBufOut[i], nframes); // initialize input events - carla_zeroStruct(pData->bufEvents.in, kEngineMaxInternalEventCount); + carla_zeroStruct(pData->bufEvents.in, EngineEvent::kMaxInternalCount); if (fMidiInEvents.mutex.tryLock()) { @@ -662,7 +669,7 @@ protected: engineEvent.fillFromMidiData(midiEvent.size, midiEvent.data); - if (engineEventIndex >= kEngineMaxInternalEventCount) + if (engineEventIndex >= EngineEvent::kMaxInternalCount) break; } diff --git a/source/backend/engine/CarlaEngineThread.cpp b/source/backend/engine/CarlaEngineThread.cpp index 979b5d6f8..412f23bff 100644 --- a/source/backend/engine/CarlaEngineThread.cpp +++ b/source/backend/engine/CarlaEngineThread.cpp @@ -1,6 +1,6 @@ /* - * Carla Engine Thread - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/source/backend/engine/CarlaEngineThread.hpp b/source/backend/engine/CarlaEngineThread.hpp index 63642ec5c..73e3fd3c6 100644 --- a/source/backend/engine/CarlaEngineThread.hpp +++ b/source/backend/engine/CarlaEngineThread.hpp @@ -1,6 +1,6 @@ /* - * Carla Engine Thread - * Copyright (C) 2012-2013 Filipe Coelho + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as diff --git a/source/backend/engine/CarlaEngine_data.cpp b/source/backend/engine/CarlaEngine_data.cpp new file mode 100644 index 000000000..d45485822 --- /dev/null +++ b/source/backend/engine/CarlaEngine_data.cpp @@ -0,0 +1,271 @@ +/* + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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 "CarlaMIDI.h" + +#include "CarlaUtils.hpp" + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- +// EngineControlEvent + +void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept +{ + switch (type) + { + case kEngineControlEventTypeNull: + break; + + case kEngineControlEventTypeParameter: + if (MIDI_IS_CONTROL_BANK_SELECT(param)) + { + size = 3; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_BANK_SELECT; + data[2] = static_cast(value); + } + else + { + size = 3; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = static_cast(param); + data[2] = uint8_t(value * 127.0f); + } + break; + + case kEngineControlEventTypeMidiBank: + size = 3; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_BANK_SELECT; + data[2] = static_cast(param); + break; + + case kEngineControlEventTypeMidiProgram: + size = 2; + data[0] = static_cast(MIDI_STATUS_PROGRAM_CHANGE + channel); + data[1] = static_cast(param); + break; + + case kEngineControlEventTypeAllSoundOff: + size = 2; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_ALL_SOUND_OFF; + break; + + case kEngineControlEventTypeAllNotesOff: + size = 2; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_ALL_NOTES_OFF; + break; + } +} + +// ----------------------------------------------------------------------- +// EngineEvent + +void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data) noexcept +{ + // get channel + channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)); + + // get status + const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data))); + + if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) + { + type = kEngineEventTypeControl; + + const uint8_t midiControl(data[1]); + + if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) + { + CARLA_SAFE_ASSERT_INT(size == 3, size); + + const uint8_t midiBank(data[2]); + + ctrl.type = kEngineControlEventTypeMidiBank; + ctrl.param = midiBank; + ctrl.value = 0.0f; + } + else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) + { + CARLA_SAFE_ASSERT_INT(size == 2, size); + + ctrl.type = kEngineControlEventTypeAllSoundOff; + ctrl.param = 0; + ctrl.value = 0.0f; + } + else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) + { + CARLA_SAFE_ASSERT_INT(size == 2, size); + + ctrl.type = kEngineControlEventTypeAllNotesOff; + ctrl.param = 0; + ctrl.value = 0.0f; + } + else + { + CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl); + + const uint8_t midiValue(data[2]); + + ctrl.type = kEngineControlEventTypeParameter; + ctrl.param = midiControl; + ctrl.value = float(midiValue)/127.0f; + } + } + else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) + { + CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]); + + type = kEngineEventTypeControl; + + const uint8_t midiProgram(data[1]); + + ctrl.type = kEngineControlEventTypeMidiProgram; + ctrl.param = midiProgram; + ctrl.value = 0.0f; + } + else + { + type = kEngineEventTypeMidi; + + midi.port = 0; + midi.size = size; + + if (size > EngineMidiEvent::kDataSize) + { + midi.dataExt = data; + std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize); + } + else + { + midi.data[0] = midiStatus; + + uint8_t i=1; + for (; i < midi.size; ++i) + midi.data[i] = data[i]; + for (; i < EngineMidiEvent::kDataSize; ++i) + midi.data[i] = 0; + + midi.dataExt = nullptr; + } + } +} + +// ----------------------------------------------------------------------- +// EngineOptions + +EngineOptions::EngineOptions() noexcept +#ifdef CARLA_OS_LINUX + : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS), + transportMode(ENGINE_TRANSPORT_MODE_JACK), +#else + : processMode(ENGINE_PROCESS_MODE_CONTINUOUS_RACK), + transportMode(ENGINE_TRANSPORT_MODE_INTERNAL), +#endif + forceStereo(false), + preferPluginBridges(false), + preferUiBridges(true), + uisAlwaysOnTop(true), + maxParameters(MAX_DEFAULT_PARAMETERS), + uiBridgesTimeout(4000), + audioNumPeriods(2), + audioBufferSize(512), + audioSampleRate(44100), + audioDevice(nullptr), + binaryDir(nullptr), + resourceDir(nullptr) {} + +EngineOptions::~EngineOptions() +{ + if (audioDevice != nullptr) + { + delete[] audioDevice; + audioDevice = nullptr; + } + + if (binaryDir != nullptr) + { + delete[] binaryDir; + binaryDir = nullptr; + } + + if (resourceDir != nullptr) + { + delete[] resourceDir; + resourceDir = nullptr; + } +} + +// ----------------------------------------------------------------------- +// EngineTimeInfoBBT + +EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept + : bar(0), + beat(0), + tick(0), + barStartTick(0.0), + beatsPerBar(0.0f), + beatType(0.0f), + ticksPerBeat(0.0), + beatsPerMinute(0.0) {} + +// ----------------------------------------------------------------------- +// EngineTimeInfo + +EngineTimeInfo::EngineTimeInfo() noexcept + : playing(false), + frame(0), + usecs(0), + valid(0x0) {} + +void EngineTimeInfo::clear() noexcept +{ + playing = false; + frame = 0; + usecs = 0; + valid = 0x0; +} + +bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept +{ + if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.valid != valid) + return false; + if ((valid & kValidBBT) == 0) + return true; + if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute) + return false; + return true; +} + +bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept +{ + return !operator==(timeInfo); +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_internal.cpp b/source/backend/engine/CarlaEngine_internal.cpp new file mode 100644 index 000000000..68a7619be --- /dev/null +++ b/source/backend/engine/CarlaEngine_internal.cpp @@ -0,0 +1,384 @@ +/* + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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 "CarlaEngineInternal.hpp" +#include "CarlaPlugin.hpp" + +#ifndef HAVE_JUCE +# include +#else +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- +// InternalEvents + +InternalEvents::InternalEvents() noexcept + : in(nullptr), + out(nullptr) {} + +InternalEvents::~InternalEvents() noexcept +{ + CARLA_ASSERT(in == nullptr); + CARLA_ASSERT(out == nullptr); +} + +// ----------------------------------------------------------------------- +// InternalTime + +InternalTime::InternalTime() noexcept + : playing(false), + frame(0) {} + +// ----------------------------------------------------------------------- +// NextAction + +NextAction::NextAction() noexcept + : opcode(kEnginePostActionNull), + pluginId(0), + value(0) {} + +NextAction::~NextAction() noexcept +{ + CARLA_ASSERT(opcode == kEnginePostActionNull); +} + +void NextAction::ready() noexcept +{ + mutex.lock(); + mutex.unlock(); +} + +// ----------------------------------------------------------------------- + +void EnginePluginData::clear() noexcept +{ + plugin = nullptr; + insPeak[0] = insPeak[1] = 0.0f; + outsPeak[0] = outsPeak[1] = 0.0f; +} + +// ----------------------------------------------------------------------- + +CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) + : osc(engine), + thread(engine), + oscData(nullptr), + callback(nullptr), + callbackPtr(nullptr), + hints(0x0), + bufferSize(0), + sampleRate(0.0), + aboutToClose(false), + curPluginCount(0), + maxPluginNumber(0), + nextPluginId(0), + plugins(nullptr) {} + +CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept +{ + CARLA_ASSERT(curPluginCount == 0); + CARLA_ASSERT(maxPluginNumber == 0); + CARLA_ASSERT(nextPluginId == 0); + CARLA_ASSERT(plugins == nullptr); +} + +// ----------------------------------------------------------------------- + +void CarlaEngineProtectedData::doPluginRemove() noexcept +{ + CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,); + CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,); + --curPluginCount; + + // move all plugins 1 spot backwards + for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i) + { + CarlaPlugin* const plugin(plugins[i+1].plugin); + + CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); + + plugin->setId(i); + + plugins[i].plugin = plugin; + plugins[i].insPeak[0] = 0.0f; + plugins[i].insPeak[1] = 0.0f; + plugins[i].outsPeak[0] = 0.0f; + plugins[i].outsPeak[1] = 0.0f; + } + + const unsigned int id(curPluginCount); + + // reset last plugin (now removed) + plugins[id].plugin = nullptr; + plugins[id].insPeak[0] = 0.0f; + plugins[id].insPeak[1] = 0.0f; + plugins[id].outsPeak[0] = 0.0f; + plugins[id].outsPeak[1] = 0.0f; +} + +void CarlaEngineProtectedData::doPluginsSwitch() noexcept +{ + CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,); + + const unsigned int idA(nextAction.pluginId); + const unsigned int idB(nextAction.value); + + CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,); + CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,); + +#if 0 + std::swap(plugins[idA].plugin, plugins[idB].plugin); +#else + CarlaPlugin* const tmp(plugins[idA].plugin); + + plugins[idA].plugin = plugins[idB].plugin; + plugins[idB].plugin = tmp; +#endif +} + +void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept +{ + switch (nextAction.opcode) + { + case kEnginePostActionNull: + break; + case kEnginePostActionZeroCount: + curPluginCount = 0; + break; + case kEnginePostActionRemovePlugin: + doPluginRemove(); + break; + case kEnginePostActionSwitchPlugins: + doPluginsSwitch(); + break; + } + + nextAction.opcode = kEnginePostActionNull; + nextAction.pluginId = 0; + nextAction.value = 0; + + if (unlock) + nextAction.mutex.unlock(); +} + +#ifndef BUILD_BRIDGE +void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline) +{ + CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,); + CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,); + + // safe copy + float inBuf0[frames]; + float inBuf1[frames]; + float* inBuf[2] = { inBuf0, inBuf1 }; + + // initialize audio inputs + FLOAT_COPY(inBuf0, inBufReal[0], frames); + FLOAT_COPY(inBuf1, inBufReal[1], frames); + + // initialize audio outputs (zero) + FLOAT_CLEAR(outBuf[0], frames); + FLOAT_CLEAR(outBuf[1], frames); + + // initialize event outputs (zero) + carla_zeroStruct(bufEvents.out, EngineEvent::kMaxInternalCount); + + bool processed = false; + + uint32_t oldAudioInCount = 0; + uint32_t oldMidiOutCount = 0; + + // process plugins + for (unsigned int i=0; i < curPluginCount; ++i) + { + CarlaPlugin* const plugin = plugins[i].plugin; + + if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline)) + continue; + + if (processed) + { + // initialize audio inputs (from previous outputs) + FLOAT_COPY(inBuf0, outBuf[0], frames); + FLOAT_COPY(inBuf1, outBuf[1], frames); + + // initialize audio outputs (zero) + FLOAT_CLEAR(outBuf[0], frames); + FLOAT_CLEAR(outBuf[1], frames); + + // if plugin has no midi out, add previous events + if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull) + { + if (bufEvents.out[0].type != kEngineEventTypeNull) + { + // TODO: carefully add to input, sorted events + } + // else nothing needed + } + else + { + // initialize event inputs from previous outputs + carla_copyStruct(bufEvents.in, bufEvents.out, EngineEvent::kMaxInternalCount); + + // initialize event outputs (zero) + carla_zeroStruct(bufEvents.out, EngineEvent::kMaxInternalCount); + } + } + + oldAudioInCount = plugin->getAudioInCount(); + oldMidiOutCount = plugin->getMidiOutCount(); + + // process + plugin->initBuffers(); + plugin->process(inBuf, outBuf, frames); + plugin->unlock(); + + // if plugin has no audio inputs, add input buffer + if (oldAudioInCount == 0) + { + FLOAT_ADD(outBuf[0], inBuf0, frames); + FLOAT_ADD(outBuf[1], inBuf1, frames); + } + + // set peaks + { + EnginePluginData& pluginData(plugins[i]); + +#ifdef HAVE_JUCE + float tmpMin, tmpMax; + + if (oldAudioInCount > 0) + { + FloatVectorOperations::findMinAndMax(inBuf0, frames, tmpMin, tmpMax); + pluginData.insPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + + FloatVectorOperations::findMinAndMax(inBuf1, frames, tmpMin, tmpMax); + pluginData.insPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + } + else + { + pluginData.insPeak[0] = 0.0f; + pluginData.insPeak[1] = 0.0f; + } + + if (plugin->getAudioOutCount() > 0) + { + FloatVectorOperations::findMinAndMax(outBuf[0], frames, tmpMin, tmpMax); + pluginData.outsPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + + FloatVectorOperations::findMinAndMax(outBuf[1], frames, tmpMin, tmpMax); + pluginData.outsPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + } + else + { + pluginData.outsPeak[0] = 0.0f; + pluginData.outsPeak[1] = 0.0f; + } +#else + float peak1, peak2; + + if (oldAudioInCount > 0) + { + peak1 = peak2 = 0.0f; + + for (uint32_t k=0; k < frames; ++k) + { + peak1 = carla_max(peak1, std::fabs(inBuf0[k]), 1.0f); + peak2 = carla_max(peak2, std::fabs(inBuf1[k]), 1.0f); + } + + pluginData.insPeak[0] = peak1; + pluginData.insPeak[1] = peak2; + } + else + { + pluginData.insPeak[0] = 0.0f; + pluginData.insPeak[1] = 0.0f; + } + + if (plugin->getAudioOutCount() > 0) + { + peak1 = peak2 = 0.0f; + + for (uint32_t k=0; k < frames; ++k) + { + peak1 = carla_max(peak1, std::fabs(outBuf[0][k]), 1.0f); + peak2 = carla_max(peak2, std::fabs(outBuf[1][k]), 1.0f); + } + + pluginData.outsPeak[0] = peak1; + pluginData.outsPeak[1] = peak2; + } + else + { + pluginData.outsPeak[0] = 0.0f; + pluginData.outsPeak[1] = 0.0f; + } +#endif + } + + processed = true; + } +} +#endif + +// ----------------------------------------------------------------------- + +CarlaEngineProtectedData::ScopedActionLock::ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept + : fData(data) +{ + fData->nextAction.mutex.lock(); + + CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,); + + fData->nextAction.opcode = action; + fData->nextAction.pluginId = pluginId; + fData->nextAction.value = value; + + if (lockWait) + { + // block wait for unlock on processing side + carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); + fData->nextAction.mutex.lock(); + carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); + } + else + { + fData->doNextPluginAction(false); + } +} + +CarlaEngineProtectedData::ScopedActionLock::~ScopedActionLock() noexcept +{ + fData->nextAction.mutex.unlock(); +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_osc.cpp b/source/backend/engine/CarlaEngine_osc.cpp new file mode 100644 index 000000000..0028a371e --- /dev/null +++ b/source/backend/engine/CarlaEngine_osc.cpp @@ -0,0 +1,738 @@ +/* + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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 "CarlaEngineInternal.hpp" +#include "CarlaMIDI.h" + +#include "CarlaUtils.hpp" + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- +// OSC Stuff + +#ifdef BUILD_BRIDGE +bool CarlaEngine::isOscBridgeRegistered() const noexcept +{ + return (pData->oscData != nullptr); +} +#else +bool CarlaEngine::isOscControlRegistered() const noexcept +{ + return pData->osc.isControlRegistered(); +} +#endif + +void CarlaEngine::idleOsc() const noexcept +{ + try { + pData->osc.idle(); + } catch(...) {} +} + +const char* CarlaEngine::getOscServerPathTCP() const noexcept +{ + return pData->osc.getServerPathTCP(); +} + +const char* CarlaEngine::getOscServerPathUDP() const noexcept +{ + return pData->osc.getServerPathUDP(); +} + +#ifdef BUILD_BRIDGE +void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) const noexcept +{ + pData->oscData = oscData; +} +#endif + +// ----------------------------------------------------------------------- +// Bridge/Controller OSC stuff + +#ifdef BUILD_BRIDGE +void CarlaEngine::oscSend_bridge_plugin_info1(const PluginCategory category, const uint hints, const long uniqueId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_plugin_info1(%i:%s, %X, %l)", category, PluginCategory2Str(category), hints, uniqueId); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_plugin_info1"); + try_lo_send(pData->oscData->target, targetPath, "iih", static_cast(category), static_cast(hints), static_cast(uniqueId)); +} + +void CarlaEngine::oscSend_bridge_plugin_info2(const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); + CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_plugin_info2(\"%s\", \"%s\", \"%s\", \"%s\")", realName, label, maker, copyright); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_plugin_info2"); + try_lo_send(pData->oscData->target, targetPath, "ssss", realName, label, maker, copyright); +} + +void CarlaEngine::oscSend_bridge_audio_count(const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_audio_count(%i, %i)", ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+20]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_audio_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_bridge_midi_count(const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_midi_count(%i, %i)", ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+19]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_midi_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_bridge_parameter_count(const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_count(%i, %i)", ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_bridge_program_count(const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_program_count(%i)", count); + + char targetPath[std::strlen(pData->oscData->path)+22]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_program_count"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); +} + +void CarlaEngine::oscSend_bridge_midi_program_count(const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_midi_program_count(%i)", count); + + char targetPath[std::strlen(pData->oscData->path)+27]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_midi_program_count"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); +} + +void CarlaEngine::oscSend_bridge_parameter_data(const uint32_t index, const int32_t rindex, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", index, rindex, type, ParameterType2Str(type), hints, name, unit); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_data"); + try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(index), static_cast(rindex), static_cast(type), static_cast(hints), name, unit); +} + +void CarlaEngine::oscSend_bridge_parameter_ranges1(const uint32_t index, const float def, const float min, const float max) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, def, min, max); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_ranges1"); + try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), def, min, max); +} + +void CarlaEngine::oscSend_bridge_parameter_ranges2(const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, step, stepSmall, stepLarge); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_ranges2"); + try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), step, stepSmall, stepLarge); +} + +void CarlaEngine::oscSend_bridge_parameter_midi_cc(const uint32_t index, const int16_t cc) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_cc(%i, %i)", index, cc); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_midi_cc"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(cc)); +} + +void CarlaEngine::oscSend_bridge_parameter_midi_channel(const uint32_t index, const uint8_t channel) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_channel(%i, %i)", index, channel); + + char targetPath[std::strlen(pData->oscData->path)+31]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_midi_channel"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(channel)); +} + +void CarlaEngine::oscSend_bridge_parameter_value(const int32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_value(%i, %f)", index, value); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_value"); + try_lo_send(pData->oscData->target, targetPath, "if", index, value); +} + +void CarlaEngine::oscSend_bridge_default_value(const uint32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_default_value(%i, %f)", index, value); + + char targetPath[std::strlen(pData->oscData->path)+22]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_default_value"); + try_lo_send(pData->oscData->target, targetPath, "if", static_cast(index), value); +} + +void CarlaEngine::oscSend_bridge_current_program(const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_current_program(%i)", index); + + char targetPath[std::strlen(pData->oscData->path)+20]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_current_program"); + try_lo_send(pData->oscData->target, targetPath, "i", index); +} + +void CarlaEngine::oscSend_bridge_current_midi_program(const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_current_midi_program(%i)", index); + + char targetPath[std::strlen(pData->oscData->path)+25]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_current_midi_program"); + try_lo_send(pData->oscData->target, targetPath, "i", index); +} + +void CarlaEngine::oscSend_bridge_program_name(const uint32_t index, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_program_name(%i, \"%s\")", index, name); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_program_name"); + try_lo_send(pData->oscData->target, targetPath, "is", static_cast(index), name); +} + +void CarlaEngine::oscSend_bridge_midi_program_data(const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_midi_program_data(%i, %i, %i, \"%s\")", index, bank, program, name); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_midi_program_data"); + try_lo_send(pData->oscData->target, targetPath, "iiis", static_cast(index), static_cast(bank), static_cast(program), name); +} + +void CarlaEngine::oscSend_bridge_configure(const char* const key, const char* const value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(value != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_configure(\"%s\", \"%s\")", key, value); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_configure"); + try_lo_send(pData->oscData->target, targetPath, "ss", key, value); +} + +void CarlaEngine::oscSend_bridge_set_custom_data(const char* const type, const char* const key, const char* const value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_set_custom_data(\"%s\", \"%s\", \"%s\")", type, key, value); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_set_custom_data"); + try_lo_send(pData->oscData->target, targetPath, "sss", type, key, value); +} + +void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(chunkFile != nullptr && chunkFile[0] != '\0',); + carla_debug("CarlaEngine::oscSend_bridge_set_chunk_data(\"%s\")", chunkFile); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_set_chunk_data"); + try_lo_send(pData->oscData->target, targetPath, "s", chunkFile); +} + +// TODO? +//void oscSend_bridge_set_peaks() const; + +#else +void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',); + carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/add_plugin_start"); + try_lo_send(pData->oscData->target, targetPath, "is", static_cast(pluginId), pluginName); +} + +void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId); + + char targetPath[std::strlen(pData->oscData->path)+16]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/add_plugin_end"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); +} + +void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId); + + char targetPath[std::strlen(pData->oscData->path)+15]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/remove_plugin"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); +} + +void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const long uniqueId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,); + carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, %l)", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_plugin_info1"); + try_lo_send(pData->oscData->target, targetPath, "iiiih", static_cast(pluginId), static_cast(type), static_cast(category), static_cast(hints), static_cast(uniqueId)); +} + +void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); + CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_plugin_info2"); + try_lo_send(pData->oscData->target, targetPath, "issss", static_cast(pluginId), realName, label, maker, copyright); +} + +void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_audio_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_midi_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count); + + char targetPath[std::strlen(pData->oscData->path)+19]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_program_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); +} + +void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_midi_program_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); +} + +void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit); + + char targetPath[std::strlen(pData->oscData->path)+20]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_data"); + try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(pluginId), static_cast(index), static_cast(type), static_cast(hints), name, unit); +} + +void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(def <= min && def >= max,); + CARLA_SAFE_ASSERT_RETURN(min < max,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_ranges1"); + try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), def, min, max); +} + +void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(step <= stepSmall && step >= stepLarge,); + CARLA_SAFE_ASSERT_RETURN(stepSmall <= stepLarge,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_ranges"); + try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), step, stepSmall, stepLarge); +} + +void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(cc <= 0x5F,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_midi_cc"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(cc)); +} + +void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); + + char targetPath[std::strlen(pData->oscData->path)+28]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_midi_channel"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(channel)); +} + +void CarlaEngine::oscSend_control_set_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_value(%i, %i:%s, %f)", pluginId, index, (index < 0) ? InternalParameterIndex2Str(static_cast(index)) : "(none)", value); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_value"); + try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), index, value); +} + +void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value); + + char targetPath[std::strlen(pData->oscData->path)+19]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_default_value"); + try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), static_cast(index), value); +} + +void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_current_program"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); +} + +void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_current_midi_program"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); +} + +void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_program_name"); + try_lo_send(pData->oscData->target, targetPath, "iis", static_cast(pluginId), static_cast(index), name); +} + +void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_midi_program_data"); + try_lo_send(pData->oscData->target, targetPath, "iiiis", static_cast(pluginId), static_cast(index), static_cast(bank), static_cast(program), name); +} + +void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,); + carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); + + char targetPath[std::strlen(pData->oscData->path)+9]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/note_on"); + try_lo_send(pData->oscData->target, targetPath, "iiii", static_cast(pluginId), static_cast(channel), static_cast(note), static_cast(velo)); +} + +void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note); + + char targetPath[std::strlen(pData->oscData->path)+10]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/note_off"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(channel), static_cast(note)); +} + +void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + + // TODO - try and see if we can get peaks[4] ref + const EnginePluginData& epData(pData->plugins[pluginId]); + + char targetPath[std::strlen(pData->oscData->path)+11]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_peaks"); + try_lo_send(pData->oscData->target, targetPath, "iffff", static_cast(pluginId), epData.insPeak[0], epData.insPeak[1], epData.outsPeak[0], epData.outsPeak[1]); +} + +void CarlaEngine::oscSend_control_exit() const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_control_exit()"); + + char targetPath[std::strlen(pData->oscData->path)+6]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/exit"); + try_lo_send(pData->oscData->target, targetPath, ""); +} +#endif + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_patchbay.cpp b/source/backend/engine/CarlaEngine_patchbay.cpp new file mode 100644 index 000000000..d1c4ff595 --- /dev/null +++ b/source/backend/engine/CarlaEngine_patchbay.cpp @@ -0,0 +1,527 @@ +/* + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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. + */ + +#ifdef BUILD_BRIDGE +# error This file should not be compiled if building bridge +#endif + +#include "CarlaEngineInternal.hpp" + +#include "LinkedList.hpp" + +#ifdef HAVE_JUCE +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- + +struct EngineRackBuffers { + float* in[2]; + float* out[2]; + + // connections stuff + LinkedList connectedIns[2]; + LinkedList connectedOuts[2]; + CarlaMutex connectLock; + + int lastConnectionId; + LinkedList usedConnections; + + EngineRackBuffers(const uint32_t bufferSize); + ~EngineRackBuffers(); + void clear(); + void resize(const uint32_t bufferSize); +}; + +// ----------------------------------------------------------------------- + +struct EnginePatchbayBuffers { + // TODO + EnginePatchbayBuffers(const uint32_t bufferSize); + ~EnginePatchbayBuffers(); + void clear(); + void resize(const uint32_t bufferSize); +}; + +// ----------------------------------------------------------------------- +// EngineRackBuffers + +EngineRackBuffers::EngineRackBuffers(const uint32_t bufferSize) + : lastConnectionId(0) +{ + resize(bufferSize); +} + +EngineRackBuffers::~EngineRackBuffers() +{ + clear(); +} + +void EngineRackBuffers::clear() +{ + lastConnectionId = 0; + + if (in[0] != nullptr) + { + delete[] in[0]; + in[0] = nullptr; + } + + if (in[1] != nullptr) + { + delete[] in[1]; + in[1] = nullptr; + } + + if (out[0] != nullptr) + { + delete[] out[0]; + out[0] = nullptr; + } + + if (out[1] != nullptr) + { + delete[] out[1]; + out[1] = nullptr; + } + + connectedIns[0].clear(); + connectedIns[1].clear(); + connectedOuts[0].clear(); + connectedOuts[1].clear(); + usedConnections.clear(); +} + +void EngineRackBuffers::resize(const uint32_t bufferSize) +{ + if (bufferSize > 0) + { + in[0] = new float[bufferSize]; + in[1] = new float[bufferSize]; + out[0] = new float[bufferSize]; + out[1] = new float[bufferSize]; + } + else + { + in[0] = nullptr; + in[1] = nullptr; + out[0] = nullptr; + out[1] = nullptr; + } +} + +// ----------------------------------------------------------------------- +// EnginePatchbayBuffers + +EnginePatchbayBuffers::EnginePatchbayBuffers(const uint32_t bufferSize) +{ + resize(bufferSize); +} + +EnginePatchbayBuffers::~EnginePatchbayBuffers() +{ + clear(); +} + +void clear() +{ +} + +void EnginePatchbayBuffers::resize(const uint32_t /*bufferSize*/) +{ +} + +// ----------------------------------------------------------------------- +// InternalAudio + +InternalAudio::InternalAudio() noexcept + : isReady(false), + usePatchbay(false), + inCount(0), + outCount(0) +{ + rack = nullptr; +} + +InternalAudio::~InternalAudio() noexcept +{ + CARLA_ASSERT(! isReady); + CARLA_ASSERT(rack == nullptr); +} + +void InternalAudio::initPatchbay() noexcept +{ + if (usePatchbay) + { + CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); + } + else + { + CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); + + rack->lastConnectionId = 0; + rack->usedConnections.clear(); + } +} + +void InternalAudio::clear() +{ + isReady = false; + inCount = 0; + outCount = 0; + + if (usePatchbay) + { + CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); + delete patchbay; + patchbay = nullptr; + } + else + { + CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); + delete rack; + rack = nullptr; + } +} + +void InternalAudio::create(const uint32_t bufferSize) +{ + if (usePatchbay) + { + CARLA_SAFE_ASSERT_RETURN(patchbay == nullptr,); + patchbay = new EnginePatchbayBuffers(bufferSize); + } + else + { + CARLA_SAFE_ASSERT_RETURN(rack == nullptr,); + rack = new EngineRackBuffers(bufferSize); + } + + isReady = true; +} + +void InternalAudio::resize(const uint32_t bufferSize) +{ + if (usePatchbay) + { + CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); + patchbay->resize(bufferSize); + } + else + { + CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); + rack->resize(bufferSize); + } +} + +void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) +{ + EngineRackBuffers* const rack(bufAudio.rack); + + const CarlaMutex::ScopedLocker sl(rack->connectLock); + + // connect input buffers + if (rack->connectedIns[0].count() == 0) + { + FLOAT_CLEAR(rack->in[0], nframes); + } + else + { + bool first = true; + + for (LinkedList::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < inCount); + + if (first) + { + FLOAT_COPY(rack->in[0], inBuf[port], nframes); + first = false; + } + else + { + FLOAT_ADD(rack->in[0], inBuf[port], nframes); + } + } + + if (first) + FLOAT_CLEAR(rack->in[0], nframes); + } + + if (rack->connectedIns[1].count() == 0) + { + FLOAT_CLEAR(rack->in[1], nframes); + } + else + { + bool first = true; + + for (LinkedList::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < inCount); + + if (first) + { + FLOAT_COPY(rack->in[1], inBuf[port], nframes); + first = false; + } + else + { + FLOAT_ADD(rack->in[1], inBuf[port], nframes); + } + } + + if (first) + FLOAT_CLEAR(rack->in[1], nframes); + } + + FLOAT_CLEAR(rack->out[0], nframes); + FLOAT_CLEAR(rack->out[1], nframes); + + // process + processRack(rack->in, rack->out, nframes, isOffline); + + // connect output buffers + if (rack->connectedOuts[0].count() != 0) + { + for (LinkedList::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < outCount); + + FLOAT_ADD(outBuf[port], rack->out[0], nframes); + } + } + + if (rack->connectedOuts[1].count() != 0) + { + for (LinkedList::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < outCount); + + FLOAT_ADD(outBuf[port], rack->out[1], nframes); + } + } +} + +// ----------------------------------------------------------------------- +// Patchbay + +bool CarlaEngine::patchbayConnect(const int portA, const int portB) +{ + CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); + CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); + carla_debug("CarlaEngineRtAudio::patchbayConnect(%i, %i)", portA, portB); + + if (pData->bufAudio.usePatchbay) + { + // not implemented yet + return false; + } + + EngineRackBuffers* const rack(pData->bufAudio.rack); + + CARLA_SAFE_ASSERT_RETURN_ERR(portA > RACK_PATCHBAY_PORT_MAX, "Invalid output port"); + CARLA_SAFE_ASSERT_RETURN_ERR(portB > RACK_PATCHBAY_PORT_MAX, "Invalid input port"); + + // only allow connections between Carla and other ports + if (portA < 0 && portB < 0) + { + setLastError("Invalid connection (1)"); + return false; + } + if (portA >= 0 && portB >= 0) + { + setLastError("Invalid connection (2)"); + return false; + } + + const int carlaPort = (portA < 0) ? portA : portB; + const int targetPort = (carlaPort == portA) ? portB : portA; + bool makeConnection = false; + + switch (carlaPort) + { + case RACK_PATCHBAY_PORT_AUDIO_IN1: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); + rack->connectLock.lock(); + rack->connectedIns[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_AUDIO_IN2: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); + rack->connectLock.lock(); + rack->connectedIns[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_AUDIO_OUT1: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); + rack->connectLock.lock(); + rack->connectedOuts[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_AUDIO_OUT2: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); + rack->connectLock.lock(); + rack->connectedOuts[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_MIDI_IN: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_IN*1000+999); + makeConnection = connectRackMidiInPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_IN*1000); + break; + + case RACK_PATCHBAY_PORT_MIDI_OUT: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_OUT*1000+999); + makeConnection = connectRackMidiOutPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_OUT*1000); + break; + } + + if (! makeConnection) + { + setLastError("Invalid connection (3)"); + return false; + } + + ConnectionToId connectionToId; + connectionToId.id = rack->lastConnectionId; + connectionToId.portOut = portA; + connectionToId.portIn = portB; + + callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, portA, portB, 0.0f, nullptr); + + rack->usedConnections.append(connectionToId); + rack->lastConnectionId++; + + return true; +} + +bool CarlaEngine::patchbayDisconnect(const int connectionId) +{ + CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); + CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); + carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); + + if (pData->bufAudio.usePatchbay) + { + // not implemented yet + return false; + } + + EngineRackBuffers* const rack(pData->bufAudio.rack); + + CARLA_SAFE_ASSERT_RETURN_ERR(rack->usedConnections.count() > 0, "No connections available"); + + for (LinkedList::Itenerator it=rack->usedConnections.begin(); it.valid(); it.next()) + { + const ConnectionToId& connection(it.getValue()); + + if (connection.id == connectionId) + { + const int targetPort((connection.portOut >= 0) ? connection.portOut : connection.portIn); + const int carlaPort((targetPort == connection.portOut) ? connection.portIn : connection.portOut); + + if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000) + { + const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000); + disconnectRackMidiInPort(portId); + } + else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000) + { + const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000); + disconnectRackMidiOutPort(portId); + } + else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000) + { + CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2, false); + + const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + + rack->connectLock.lock(); + + if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1) + rack->connectedOuts[0].removeAll(portId); + else + rack->connectedOuts[1].removeAll(portId); + + rack->connectLock.unlock(); + } + else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000) + { + CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2, false); + + const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + + rack->connectLock.lock(); + + if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1) + rack->connectedIns[0].removeAll(portId); + else + rack->connectedIns[1].removeAll(portId); + + rack->connectLock.unlock(); + } + else + { + CARLA_SAFE_ASSERT_RETURN(false, false); + } + + callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, connection.portOut, connection.portIn, 0.0f, nullptr); + + rack->usedConnections.remove(it); + break; + } + } + + return true; +} + +bool CarlaEngine::patchbayRefresh() +{ + setLastError("Unsupported operation"); + return false; +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_ports.cpp b/source/backend/engine/CarlaEngine_ports.cpp new file mode 100644 index 000000000..5db5f6f00 --- /dev/null +++ b/source/backend/engine/CarlaEngine_ports.cpp @@ -0,0 +1,273 @@ +/* + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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 "CarlaMIDI.h" + +#include "CarlaUtils.hpp" + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- +// Fallback data + +static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} }; + +// ----------------------------------------------------------------------- +// Carla Engine port (Abstract) + +CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInput) + : fEngine(engine), + fIsInput(isInput) +{ + carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInput)); +} + +CarlaEnginePort::~CarlaEnginePort() +{ + carla_debug("CarlaEnginePort::~CarlaEnginePort()"); +} + +// ----------------------------------------------------------------------- +// Carla Engine Audio port + +CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInput) + : CarlaEnginePort(engine, isInput), + fBuffer(nullptr) +{ + carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); +} + +CarlaEngineAudioPort::~CarlaEngineAudioPort() +{ + carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()"); +} + +void CarlaEngineAudioPort::initBuffer() +{ +} + +// ----------------------------------------------------------------------- +// Carla Engine CV port + +CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput) + : CarlaEnginePort(engine, isInput), + fBuffer(nullptr), + fProcessMode(engine.getProccessMode()) +{ + carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput)); + + if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) + fBuffer = new float[engine.getBufferSize()]; +} + +CarlaEngineCVPort::~CarlaEngineCVPort() +{ + carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()"); + + if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) + { + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + + delete[] fBuffer; + fBuffer = nullptr; + } +} + +void CarlaEngineCVPort::initBuffer() +{ + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); + + carla_zeroFloat(fBuffer, fEngine.getBufferSize()); +} + +void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) +{ + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); + + delete[] fBuffer; + fBuffer = new float[bufferSize]; +} + +// ----------------------------------------------------------------------- +// Carla Engine Event port + +CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput) + : CarlaEnginePort(engine, isInput), + fBuffer(nullptr), + fProcessMode(engine.getProccessMode()) +{ + carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); + + if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) + fBuffer = new EngineEvent[EngineEvent::kMaxInternalCount]; +} + +CarlaEngineEventPort::~CarlaEngineEventPort() +{ + carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); + + if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) + { + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + + delete[] fBuffer; + fBuffer = nullptr; + } +} + +void CarlaEngineEventPort::initBuffer() +{ + if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE) + fBuffer = fEngine.getInternalEventBuffer(fIsInput); + else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput) + carla_zeroStruct(fBuffer, EngineEvent::kMaxInternalCount); +} + +uint32_t CarlaEngineEventPort::getEventCount() const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(fIsInput, 0); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); + + uint32_t i=0; + + for (; i < EngineEvent::kMaxInternalCount; ++i) + { + if (fBuffer[i].type == kEngineEventTypeNull) + break; + } + + return i; +} + +const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) noexcept +{ + CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(index < EngineEvent::kMaxInternalCount, kFallbackEngineEvent); + + return fBuffer[index]; +} + +const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) noexcept +{ + return fBuffer[index]; +} + +bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) +{ + CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); + CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); + CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); + + if (type == kEngineControlEventTypeParameter) { + CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); + } + + const float fixedValue(carla_fixValue(0.0f, 1.0f, value)); + + for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) + { + if (fBuffer[i].type != kEngineEventTypeNull) + continue; + + EngineEvent& event(fBuffer[i]); + + event.type = kEngineEventTypeControl; + event.time = time; + event.channel = channel; + + event.ctrl.type = type; + event.ctrl.param = param; + event.ctrl.value = fixedValue; + + return true; + } + + carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full"); + return false; +} + +bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) +{ + return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value); +} + +bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) +{ + CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); + CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); + CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); + + for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) + { + if (fBuffer[i].type != kEngineEventTypeNull) + continue; + + EngineEvent& event(fBuffer[i]); + + event.type = kEngineEventTypeMidi; + event.time = time; + event.channel = channel; + + event.midi.port = port; + event.midi.size = size; + + event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data)); + + uint8_t j=1; + for (; j < size; ++j) + event.midi.data[j] = data[j]; + for (; j < EngineMidiEvent::kDataSize; ++j) + event.midi.data[j] = 0; + + return true; + } + + carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full"); + return false; +} + +bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) +{ + return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data); +} + +bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) +{ + return writeMidiEvent(time, channel, midi.port, midi.size, midi.data); +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index 20841aa67..fe5c9f6e7 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -10,6 +10,11 @@ include ../Makefile.mk OBJS = \ CarlaEngine.cpp.o \ + CarlaEngine_data.cpp.o \ + CarlaEngine_internal.cpp.o \ + CarlaEngine_osc.cpp.o \ + CarlaEngine_patchbay.cpp.o \ + CarlaEngine_ports.cpp.o \ CarlaEngineOsc.cpp.o \ CarlaEngineThread.cpp.o diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index ebf05bbca..8aea82f3b 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -16,11 +16,9 @@ */ #include "CarlaPluginInternal.hpp" -#include "CarlaLibCounter.hpp" #include #include -#include CARLA_BACKEND_START_NAMESPACE @@ -59,129 +57,50 @@ struct ParamSymbol { #endif }; -// ------------------------------------------------------------------- -// Library functions, defined in CarlaPluginInternal.hpp - -static LibCounter sLibCounter; - -bool CarlaPluginProtectedData::libOpen(const char* const filename) -{ - lib = sLibCounter.open(filename); - return (lib != nullptr); -} - -bool CarlaPluginProtectedData::libClose() -{ - const bool ret = sLibCounter.close(lib); - lib = nullptr; - return ret; -} - -void* CarlaPluginProtectedData::libSymbol(const char* const symbol) -{ - return lib_symbol(lib, symbol); -} - -bool CarlaPluginProtectedData::uiLibOpen(const char* const filename) -{ - uiLib = sLibCounter.open(filename); - return (uiLib != nullptr); -} +// ----------------------------------------------------------------------- -bool CarlaPluginProtectedData::uiLibClose() +CarlaPlugin* CarlaPlugin::newGIG(const Initializer& init, const bool use16Outs) { - const bool ret = sLibCounter.close(uiLib); - uiLib = nullptr; - return ret; -} + carla_debug("CarlaPlugin::newGIG({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs)); +#ifdef WANT_LINUXSAMPLER + return newLinuxSampler(init, "GIG", use16Outs); +#else + init.engine->setLastError("GIG support not available"); + return nullptr; -void* CarlaPluginProtectedData::uiLibSymbol(const char* const symbol) -{ - return lib_symbol(uiLib, symbol); + // unused + (void)use16Outs; +#endif } -// ------------------------------------------------------------------- -// Settings functions, defined in CarlaPluginInternal.hpp - -void CarlaPluginProtectedData::saveSetting(const unsigned int option, const bool yesNo) +CarlaPlugin* CarlaPlugin::newSF2(const Initializer& init, const bool use16Outs) { - CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0',); - - QSettings settings("falkTX", "CarlaPluginSettings"); - settings.beginGroup(identifier); - - switch (option) - { - case PLUGIN_OPTION_FIXED_BUFFERS: - settings.setValue("FixedBuffers", yesNo); - break; - case PLUGIN_OPTION_FORCE_STEREO: - settings.setValue("ForceStereo", yesNo); - break; - case PLUGIN_OPTION_MAP_PROGRAM_CHANGES: - settings.setValue("MapProgramChanges", yesNo); - break; - case PLUGIN_OPTION_USE_CHUNKS: - settings.setValue("UseChunks", yesNo); - break; - case PLUGIN_OPTION_SEND_CONTROL_CHANGES: - settings.setValue("SendControlChanges", yesNo); - break; - case PLUGIN_OPTION_SEND_CHANNEL_PRESSURE: - settings.setValue("SendChannelPressure", yesNo); - break; - case PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH: - settings.setValue("SendNoteAftertouch", yesNo); - break; - case PLUGIN_OPTION_SEND_PITCHBEND: - settings.setValue("SendPitchbend", yesNo); - break; - case PLUGIN_OPTION_SEND_ALL_SOUND_OFF: - settings.setValue("SendAllSoundOff", yesNo); - break; - default: - break; - } + carla_debug("CarlaPlugin::newSF2({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs)); +#if defined(WANT_FLUIDSYNTH) + return newFluidSynth(init, use16Outs); +#elif defined(WANT_LINUXSAMPLER) + return newLinuxSampler(init, "SF2", use16Outs); +#else + init.engine->setLastError("SF2 support not available"); + return nullptr; - settings.endGroup(); + // unused + (void)use16Outs; +#endif } -unsigned int CarlaPluginProtectedData::loadSettings(const unsigned int options, const unsigned int availOptions) +CarlaPlugin* CarlaPlugin::newSFZ(const Initializer& init, const bool use16Outs) { - CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0', 0x0); - - QSettings settings("falkTX", "CarlaPluginSettings"); - settings.beginGroup(identifier); - - unsigned int newOptions = 0x0; - - #define CHECK_AND_SET_OPTION(STR, BIT) \ - if ((availOptions & BIT) != 0 || BIT == PLUGIN_OPTION_FORCE_STEREO) \ - { \ - if (settings.contains(STR)) \ - { \ - if (settings.value(STR, (options & BIT) != 0).toBool()) \ - newOptions |= BIT; \ - } \ - else if (options & BIT) \ - newOptions |= BIT; \ - } - - CHECK_AND_SET_OPTION("FixedBuffers", PLUGIN_OPTION_FIXED_BUFFERS); - CHECK_AND_SET_OPTION("ForceStereo", PLUGIN_OPTION_FORCE_STEREO); - CHECK_AND_SET_OPTION("MapProgramChanges", PLUGIN_OPTION_MAP_PROGRAM_CHANGES); - CHECK_AND_SET_OPTION("UseChunks", PLUGIN_OPTION_USE_CHUNKS); - CHECK_AND_SET_OPTION("SendControlChanges", PLUGIN_OPTION_SEND_CONTROL_CHANGES); - CHECK_AND_SET_OPTION("SendChannelPressure", PLUGIN_OPTION_SEND_CHANNEL_PRESSURE); - CHECK_AND_SET_OPTION("SendNoteAftertouch", PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH); - CHECK_AND_SET_OPTION("SendPitchbend", PLUGIN_OPTION_SEND_PITCHBEND); - CHECK_AND_SET_OPTION("SendAllSoundOff", PLUGIN_OPTION_SEND_ALL_SOUND_OFF); - - #undef CHECK_AND_SET_OPTION - - settings.endGroup(); + carla_debug("CarlaPlugin::newSFZ({%p, \"%s\", \"%s\", \"%s\"}, %s)", init.engine, init.filename, init.name, init.label, bool2str(use16Outs)); +#ifdef WANT_LINUXSAMPLER + return newLinuxSampler(init, "SFZ", use16Outs); +#else + init.engine->setLastError("SFZ support not available"); + return nullptr; - return newOptions; + // unused + (void)use16Outs; +#endif } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/CarlaPluginInternal.cpp b/source/backend/plugin/CarlaPluginInternal.cpp new file mode 100644 index 000000000..4474a25dd --- /dev/null +++ b/source/backend/plugin/CarlaPluginInternal.cpp @@ -0,0 +1,234 @@ +/* + * Carla Plugin + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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 "CarlaPluginInternal.hpp" + +#include "CarlaLibCounter.hpp" + +#include + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- +// Buffer functions + +void CarlaPluginProtectedData::clearBuffers() +{ + if (latencyBuffers != nullptr) + { + CARLA_ASSERT(audioIn.count > 0); + + for (uint32_t i=0; i < audioIn.count; ++i) + { + CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr); + + delete[] latencyBuffers[i]; + latencyBuffers[i] = nullptr; + } + + delete[] latencyBuffers; + latencyBuffers = nullptr; + latency = 0; + } + else + { + CARLA_ASSERT(latency == 0); + } + + audioIn.clear(); + audioOut.clear(); + param.clear(); + event.clear(); +} + +void CarlaPluginProtectedData::recreateLatencyBuffers() +{ + if (latencyBuffers != nullptr) + { + CARLA_ASSERT(audioIn.count > 0); + + for (uint32_t i=0; i < audioIn.count; ++i) + { + CARLA_SAFE_ASSERT_CONTINUE(latencyBuffers[i] != nullptr); + + delete[] latencyBuffers[i]; + latencyBuffers[i] = nullptr; + } + + delete[] latencyBuffers; + latencyBuffers = nullptr; + } + + if (audioIn.count > 0 && latency > 0) + { + latencyBuffers = new float*[audioIn.count]; + + for (uint32_t i=0; i < audioIn.count; ++i) + { + latencyBuffers[i] = new float[latency]; + FLOAT_CLEAR(latencyBuffers[i], latency); + } + } +} + +// ----------------------------------------------------------------------- +// Post-poned events + +void CarlaPluginProtectedData::postponeRtEvent(const PluginPostRtEventType type, const int32_t value1, const int32_t value2, const float value3) +{ + CARLA_SAFE_ASSERT_RETURN(type != kPluginPostRtEventNull,); + + PluginPostRtEvent event = { type, value1, value2, value3 }; + + postRtEvents.appendRT(event); +} + +// ----------------------------------------------------------------------- +// Library functions + +static LibCounter sLibCounter; + +void* CarlaPluginProtectedData::libError(const char* const filename) +{ + lib_error(lib, filename); +} + +bool CarlaPluginProtectedData::libOpen(const char* const filename) +{ + lib = sLibCounter.open(filename); + return (lib != nullptr); +} + +bool CarlaPluginProtectedData::libClose() +{ + const bool ret = sLibCounter.close(lib); + lib = nullptr; + return ret; +} + +void* CarlaPluginProtectedData::libSymbol(const char* const symbol) +{ + return lib_symbol(lib, symbol); +} + +bool CarlaPluginProtectedData::uiLibOpen(const char* const filename) +{ + uiLib = sLibCounter.open(filename); + return (uiLib != nullptr); +} + +bool CarlaPluginProtectedData::uiLibClose() +{ + const bool ret = sLibCounter.close(uiLib); + uiLib = nullptr; + return ret; +} + +void* CarlaPluginProtectedData::uiLibSymbol(const char* const symbol) +{ + return lib_symbol(uiLib, symbol); +} + +// ----------------------------------------------------------------------- +// Settings functions + +void CarlaPluginProtectedData::saveSetting(const unsigned int option, const bool yesNo) +{ + CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0',); + + QSettings settings("falkTX", "CarlaPluginSettings"); + settings.beginGroup(identifier); + + switch (option) + { + case PLUGIN_OPTION_FIXED_BUFFERS: + settings.setValue("FixedBuffers", yesNo); + break; + case PLUGIN_OPTION_FORCE_STEREO: + settings.setValue("ForceStereo", yesNo); + break; + case PLUGIN_OPTION_MAP_PROGRAM_CHANGES: + settings.setValue("MapProgramChanges", yesNo); + break; + case PLUGIN_OPTION_USE_CHUNKS: + settings.setValue("UseChunks", yesNo); + break; + case PLUGIN_OPTION_SEND_CONTROL_CHANGES: + settings.setValue("SendControlChanges", yesNo); + break; + case PLUGIN_OPTION_SEND_CHANNEL_PRESSURE: + settings.setValue("SendChannelPressure", yesNo); + break; + case PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH: + settings.setValue("SendNoteAftertouch", yesNo); + break; + case PLUGIN_OPTION_SEND_PITCHBEND: + settings.setValue("SendPitchbend", yesNo); + break; + case PLUGIN_OPTION_SEND_ALL_SOUND_OFF: + settings.setValue("SendAllSoundOff", yesNo); + break; + default: + break; + } + + settings.endGroup(); +} + +unsigned int CarlaPluginProtectedData::loadSettings(const unsigned int options, const unsigned int availOptions) +{ + CARLA_SAFE_ASSERT_RETURN(identifier != nullptr && identifier[0] != '\0', 0x0); + + QSettings settings("falkTX", "CarlaPluginSettings"); + settings.beginGroup(identifier); + + unsigned int newOptions = 0x0; + + #define CHECK_AND_SET_OPTION(STR, BIT) \ + if ((availOptions & BIT) != 0 || BIT == PLUGIN_OPTION_FORCE_STEREO) \ + { \ + if (settings.contains(STR)) \ + { \ + if (settings.value(STR, (options & BIT) != 0).toBool()) \ + newOptions |= BIT; \ + } \ + else if (options & BIT) \ + newOptions |= BIT; \ + } + + CHECK_AND_SET_OPTION("FixedBuffers", PLUGIN_OPTION_FIXED_BUFFERS); + CHECK_AND_SET_OPTION("ForceStereo", PLUGIN_OPTION_FORCE_STEREO); + CHECK_AND_SET_OPTION("MapProgramChanges", PLUGIN_OPTION_MAP_PROGRAM_CHANGES); + CHECK_AND_SET_OPTION("UseChunks", PLUGIN_OPTION_USE_CHUNKS); + CHECK_AND_SET_OPTION("SendControlChanges", PLUGIN_OPTION_SEND_CONTROL_CHANGES); + CHECK_AND_SET_OPTION("SendChannelPressure", PLUGIN_OPTION_SEND_CHANNEL_PRESSURE); + CHECK_AND_SET_OPTION("SendNoteAftertouch", PLUGIN_OPTION_SEND_NOTE_AFTERTOUCH); + CHECK_AND_SET_OPTION("SendPitchbend", PLUGIN_OPTION_SEND_PITCHBEND); + CHECK_AND_SET_OPTION("SendAllSoundOff", PLUGIN_OPTION_SEND_ALL_SOUND_OFF); + + #undef CHECK_AND_SET_OPTION + + settings.endGroup(); + + return newOptions; +} + +CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index eac8bf188..3c185c5d8 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -860,6 +860,8 @@ struct CarlaPluginProtectedData { // ------------------------------------------------------------------- // Library functions, see CarlaPlugin.cpp + void libError(const char* const filename); + bool libOpen(const char* const filename); bool libClose(); void* libSymbol(const char* const symbol); diff --git a/source/backend/plugin/LadspaPlugin.cpp b/source/backend/plugin/LadspaPlugin.cpp index 4f24394d1..c5751355c 100644 --- a/source/backend/plugin/LadspaPlugin.cpp +++ b/source/backend/plugin/LadspaPlugin.cpp @@ -20,7 +20,6 @@ #ifdef WANT_LADSPA #include "CarlaLadspaUtils.hpp" -#include "CarlaLibUtils.hpp" CARLA_BACKEND_START_NAMESPACE diff --git a/source/utils/CarlaEngineUtils.hpp b/source/utils/CarlaEngineUtils.hpp new file mode 100644 index 000000000..25a96f23f --- /dev/null +++ b/source/utils/CarlaEngineUtils.hpp @@ -0,0 +1,114 @@ +/* + * Carla Engine utils + * Copyright (C) 2011-2014 Filipe Coelho + * + * 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_ENGINE_UTILS_HPP_INCLUDED +#define CARLA_ENGINE_UTILS_HPP_INCLUDED + +#include "CarlaEngine.hpp" +#include "CarlaUtils.hpp" + +CARLA_BACKEND_START_NAMESPACE + +// ----------------------------------------------------------------------- + +static inline +const char* EngineType2Str(const EngineType type) noexcept +{ + switch (type) + { + case kEngineTypeNull: + return "kEngineTypeNull"; + case kEngineTypeJack: + return "kEngineTypeJack"; + case kEngineTypeJuce: + return "kEngineTypeJuce"; + case kEngineTypeRtAudio: + return "kEngineTypeRtAudio"; + case kEngineTypePlugin: + return "kEngineTypePlugin"; + case kEngineTypeBridge: + return "kEngineTypeBridge"; + } + + carla_stderr("CarlaBackend::EngineType2Str(%i) - invalid type", type); + return nullptr; +} + +static inline +const char* EnginePortType2Str(const EnginePortType type) noexcept +{ + switch (type) + { + case kEnginePortTypeNull: + return "kEnginePortTypeNull"; + case kEnginePortTypeAudio: + return "kEnginePortTypeAudio"; + case kEnginePortTypeCV: + return "kEnginePortTypeCV"; + case kEnginePortTypeEvent: + return "kEnginePortTypeEvent"; + } + + carla_stderr("CarlaBackend::EnginePortType2Str(%i) - invalid type", type); + return nullptr; +} + +static inline +const char* EngineEventType2Str(const EngineEventType type) noexcept +{ + switch (type) + { + case kEngineEventTypeNull: + return "kEngineEventTypeNull"; + case kEngineEventTypeControl: + return "kEngineEventTypeControl"; + case kEngineEventTypeMidi: + return "kEngineEventTypeMidi"; + } + + carla_stderr("CarlaBackend::EngineEventType2Str(%i) - invalid type", type); + return nullptr; +} + +static inline +const char* EngineControlEventType2Str(const EngineControlEventType type) noexcept +{ + switch (type) + { + case kEngineControlEventTypeNull: + return "kEngineNullEvent"; + case kEngineControlEventTypeParameter: + return "kEngineControlEventTypeParameter"; + case kEngineControlEventTypeMidiBank: + return "kEngineControlEventTypeMidiBank"; + case kEngineControlEventTypeMidiProgram: + return "kEngineControlEventTypeMidiProgram"; + case kEngineControlEventTypeAllSoundOff: + return "kEngineControlEventTypeAllSoundOff"; + case kEngineControlEventTypeAllNotesOff: + return "kEngineControlEventTypeAllNotesOff"; + } + + carla_stderr("CarlaBackend::EngineControlEventType2Str(%i) - invalid type", type); + return nullptr; +} + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_END_NAMESPACE + +#endif // CARLA_ENGINE_UTILS_HPP_INCLUDED