| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Backend API | |||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine API | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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); | |||
| // ------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Host API | |||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin API | |||
| * Copyright (C) 2011-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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 | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine Bridge | |||
| * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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<uint> connectedIns[2]; | |||
| LinkedList<uint> connectedOuts[2]; | |||
| CarlaMutex connectLock; | |||
| struct InternalAudio { | |||
| bool isReady; | |||
| bool usePatchbay; | |||
| int lastConnectionId; | |||
| LinkedList<ConnectionToId> 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 | |||
| }; | |||
| // ----------------------------------------------------------------------- | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla JACK Engine | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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 <cmath> | |||
| #ifdef HAVE_JUCE | |||
| # include "juce_audio_basics.h" | |||
| using juce::FloatVectorOperations; | |||
| #endif | |||
| #include <QtCore/QStringList> | |||
| #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<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount); | |||
| carla_zeroStruct<EngineEvent>(pData->bufEvents.in, EngineEvent::kMaxInternalCount); | |||
| { | |||
| uint32_t engineEventIndex = 0; | |||
| @@ -1131,7 +1141,7 @@ protected: | |||
| engineEvent.time = jackEvent.time; | |||
| engineEvent.fillFromMidiData(static_cast<uint8_t>(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]); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Juce Engine | |||
| * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount); | |||
| carla_zeroStruct<EngineEvent>(pData->bufEvents.in, EngineEvent::kMaxInternalCount); | |||
| // TODO - get events from juce | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Plugin Engine (Native) | |||
| * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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 <QtCore/QTextStream> | |||
| @@ -1053,8 +1059,8 @@ protected: | |||
| // --------------------------------------------------------------- | |||
| // initialize events | |||
| carla_zeroStruct<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount); | |||
| carla_zeroStruct<EngineEvent>(pData->bufEvents.out, kEngineMaxInternalEventCount); | |||
| carla_zeroStruct<EngineEvent>(pData->bufEvents.in, EngineEvent::kMaxInternalCount); | |||
| carla_zeroStruct<EngineEvent>(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<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount); | |||
| carla_zeroStruct<EngineEvent>(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]); | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine OSC | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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 | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine OSC | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla RtAudio Engine | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -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<EngineEvent>(pData->bufEvents.in, kEngineMaxInternalEventCount); | |||
| carla_zeroStruct<EngineEvent>(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; | |||
| } | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine Thread | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -1,6 +1,6 @@ | |||
| /* | |||
| * Carla Engine Thread | |||
| * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com> | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| @@ -0,0 +1,271 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaEngine.hpp" | |||
| #include "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<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||
| data[1] = MIDI_CONTROL_BANK_SELECT; | |||
| data[2] = static_cast<uint8_t>(value); | |||
| } | |||
| else | |||
| { | |||
| size = 3; | |||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||
| data[1] = static_cast<uint8_t>(param); | |||
| data[2] = uint8_t(value * 127.0f); | |||
| } | |||
| break; | |||
| case kEngineControlEventTypeMidiBank: | |||
| size = 3; | |||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||
| data[1] = MIDI_CONTROL_BANK_SELECT; | |||
| data[2] = static_cast<uint8_t>(param); | |||
| break; | |||
| case kEngineControlEventTypeMidiProgram: | |||
| size = 2; | |||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_PROGRAM_CHANGE + channel); | |||
| data[1] = static_cast<uint8_t>(param); | |||
| break; | |||
| case kEngineControlEventTypeAllSoundOff: | |||
| size = 2; | |||
| data[0] = static_cast<uint8_t>(MIDI_STATUS_CONTROL_CHANGE + channel); | |||
| data[1] = MIDI_CONTROL_ALL_SOUND_OFF; | |||
| break; | |||
| case kEngineControlEventTypeAllNotesOff: | |||
| size = 2; | |||
| data[0] = static_cast<uint8_t>(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 | |||
| @@ -0,0 +1,384 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaEngineInternal.hpp" | |||
| #include "CarlaPlugin.hpp" | |||
| #ifndef HAVE_JUCE | |||
| # include <cmath> | |||
| #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<EngineEvent>(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<EngineEvent>(bufEvents.in, bufEvents.out, EngineEvent::kMaxInternalCount); | |||
| // initialize event outputs (zero) | |||
| carla_zeroStruct<EngineEvent>(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<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f); | |||
| FloatVectorOperations::findMinAndMax(inBuf1, frames, tmpMin, tmpMax); | |||
| pluginData.insPeak[1] = carla_max<float>(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<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f); | |||
| FloatVectorOperations::findMinAndMax(outBuf[1], frames, tmpMin, tmpMax); | |||
| pluginData.outsPeak[1] = carla_max<float>(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<float>(peak1, std::fabs(inBuf0[k]), 1.0f); | |||
| peak2 = carla_max<float>(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<float>(peak1, std::fabs(outBuf[0][k]), 1.0f); | |||
| peak2 = carla_max<float>(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 | |||
| @@ -0,0 +1,738 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "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<int32_t>(category), static_cast<int32_t>(hints), static_cast<int64_t>(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<int32_t>(ins), static_cast<int32_t>(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<int32_t>(ins), static_cast<int32_t>(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<int32_t>(ins), static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(index), static_cast<int32_t>(rindex), static_cast<int32_t>(type), static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(index), static_cast<int32_t>(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<int32_t>(index), static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(type), static_cast<int32_t>(category), static_cast<int32_t>(hints), static_cast<int64_t>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(ins), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(type), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(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<InternalParameterIndex>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(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<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(index), static_cast<int32_t>(bank), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(note), static_cast<int32_t>(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<int32_t>(pluginId), static_cast<int32_t>(channel), static_cast<int32_t>(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<int32_t>(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 | |||
| @@ -0,0 +1,527 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #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<uint> connectedIns[2]; | |||
| LinkedList<uint> connectedOuts[2]; | |||
| CarlaMutex connectLock; | |||
| int lastConnectionId; | |||
| LinkedList<ConnectionToId> 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<uint>::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<uint>::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<uint>::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<uint>::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<ConnectionToId>::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 | |||
| @@ -0,0 +1,273 @@ | |||
| /* | |||
| * Carla Plugin Host | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaEngine.hpp" | |||
| #include "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<EngineEvent>(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<float>(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 | |||
| @@ -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 | |||
| @@ -16,11 +16,9 @@ | |||
| */ | |||
| #include "CarlaPluginInternal.hpp" | |||
| #include "CarlaLibCounter.hpp" | |||
| #include <QtCore/QFile> | |||
| #include <QtCore/QTextStream> | |||
| #include <QtCore/QSettings> | |||
| 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 | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| @@ -0,0 +1,234 @@ | |||
| /* | |||
| * Carla Plugin | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #include "CarlaPluginInternal.hpp" | |||
| #include "CarlaLibCounter.hpp" | |||
| #include <QtCore/QSettings> | |||
| 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 | |||
| @@ -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); | |||
| @@ -20,7 +20,6 @@ | |||
| #ifdef WANT_LADSPA | |||
| #include "CarlaLadspaUtils.hpp" | |||
| #include "CarlaLibUtils.hpp" | |||
| CARLA_BACKEND_START_NAMESPACE | |||
| @@ -0,0 +1,114 @@ | |||
| /* | |||
| * Carla Engine utils | |||
| * Copyright (C) 2011-2014 Filipe Coelho <falktx@falktx.com> | |||
| * | |||
| * This program is free software; you can redistribute it and/or | |||
| * modify it under the terms of the GNU General Public License as | |||
| * published by the Free Software Foundation; either version 2 of | |||
| * the License, or any later version. | |||
| * | |||
| * This program is distributed in the hope that it will be useful, | |||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
| * GNU General Public License for more details. | |||
| * | |||
| * For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
| */ | |||
| #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 | |||