|
- /*
- * 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.
- */
-
- #ifndef CARLA_ENGINE_INTERNAL_HPP_INCLUDED
- #define CARLA_ENGINE_INTERNAL_HPP_INCLUDED
-
- #include "CarlaEngine.hpp"
- #include "CarlaEngineOsc.hpp"
- #include "CarlaEngineThread.hpp"
-
- #include "CarlaMathUtils.hpp"
- #include "CarlaMutex.hpp"
- #include "LinkedList.hpp"
-
- // -----------------------------------------------------------------------
- // Engine helper macro, sets lastError and returns false/NULL
-
- #define CARLA_SAFE_ASSERT_RETURN_ERR(cond, err) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return false; }
- #define CARLA_SAFE_ASSERT_RETURN_ERRN(cond, err) if (cond) pass(); else { carla_safe_assert(#cond, __FILE__, __LINE__); setLastError(err); return nullptr; }
-
- // -----------------------------------------------------------------------
-
- CARLA_BACKEND_START_NAMESPACE
-
- #if 0
- } // Fix editor indentation
- #endif
-
- // -----------------------------------------------------------------------
- // Maximum pre-allocated events for rack and bridge modes
-
- const unsigned short kMaxEngineEventInternalCount = 512;
-
- #ifndef BUILD_BRIDGE
- // -----------------------------------------------------------------------
- // Rack Graph stuff
-
- enum RackGraphGroupIds {
- RACK_GRAPH_GROUP_CARLA = 0,
- RACK_GRAPH_GROUP_AUDIO_IN = 1,
- RACK_GRAPH_GROUP_AUDIO_OUT = 2,
- RACK_GRAPH_GROUP_MIDI_IN = 3,
- RACK_GRAPH_GROUP_MIDI_OUT = 4,
- RACK_GRAPH_GROUP_MAX = 5
- };
-
- enum RackGraphCarlaPortIds {
- RACK_GRAPH_CARLA_PORT_NULL = 0,
- RACK_GRAPH_CARLA_PORT_AUDIO_IN1 = 1,
- RACK_GRAPH_CARLA_PORT_AUDIO_IN2 = 2,
- RACK_GRAPH_CARLA_PORT_AUDIO_OUT1 = 3,
- RACK_GRAPH_CARLA_PORT_AUDIO_OUT2 = 4,
- RACK_GRAPH_CARLA_PORT_MIDI_IN = 5,
- RACK_GRAPH_CARLA_PORT_MIDI_OUT = 6,
- RACK_GRAPH_CARLA_PORT_MAX = 7
- };
-
- struct PortNameToId {
- int port;
- char name[STR_MAX+1];
- };
-
- struct ConnectionToId {
- uint id;
- int groupA, portA;
- int groupB, portB;
- };
-
- // -----------------------------------------------------------------------
- // RackGraph
-
- struct RackGraph {
- uint lastConnectionId;
-
- CarlaMutex connectLock; // Recursive
-
- LinkedList<int> connectedIn1;
- LinkedList<int> connectedIn2;
- LinkedList<int> connectedOut1;
- LinkedList<int> connectedOut2;
- LinkedList<ConnectionToId> usedConnections;
-
- RackGraph() noexcept
- : lastConnectionId(0) {}
-
- ~RackGraph() noexcept
- {
- clear();
- }
-
- void clear() noexcept
- {
- lastConnectionId = 0;
-
- connectedIn1.clear();
- connectedIn2.clear();
- connectedOut1.clear();
- connectedOut2.clear();
-
- usedConnections.clear();
- }
-
- bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept;
- bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept;
-
- const char* const* getConnections() const;
- bool getPortIdFromName(const char* const portName, int& groupId, int& portId);
- };
-
- // -----------------------------------------------------------------------
- // PatchbayGraph
-
- struct PatchbayGraph {
- PatchbayGraph() noexcept {}
-
- ~PatchbayGraph()
- {
- clear();
- }
-
- void clear() noexcept
- {
- }
-
- bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept;
- bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept;
-
- const char* const* getConnections() const;
- bool getPortIdFromName(const char* const portName, int& groupId, int& portId);
- };
- #endif
-
- // -----------------------------------------------------------------------
- // InternalAudio
-
- struct EngineInternalAudio {
- bool isReady;
-
- // always 2x2 in rack mode
- uint inCount;
- uint outCount;
- float** inBuf;
- float** outBuf;
-
- EngineInternalAudio() noexcept
- : isReady(false),
- inCount(0),
- outCount(0),
- inBuf(nullptr),
- outBuf(nullptr) {}
-
- ~EngineInternalAudio() noexcept
- {
- CARLA_SAFE_ASSERT(! isReady);
- CARLA_SAFE_ASSERT(inCount == 0);
- CARLA_SAFE_ASSERT(outCount == 0);
- CARLA_SAFE_ASSERT(inBuf == nullptr);
- CARLA_SAFE_ASSERT(outBuf == nullptr);
- }
-
- void clearBuffers() noexcept
- {
- for (uint32_t i=0; i < inCount; ++i)
- {
- if (inBuf[i] != nullptr)
- {
- delete[] inBuf[i];
- inBuf[i] = nullptr;
- }
- }
- for (uint32_t i=0; i < outCount; ++i)
- {
- if (outBuf[i] != nullptr)
- {
- delete[] outBuf[i];
- outBuf[i] = nullptr;
- }
- }
- }
-
- void clear() noexcept
- {
- isReady = false;
-
- clearBuffers();
-
- inCount = 0;
- outCount = 0;
-
- if (inBuf != nullptr)
- {
- delete[] inBuf;
- inBuf = nullptr;
- }
-
- if (outBuf != nullptr)
- {
- delete[] outBuf;
- outBuf = nullptr;
- }
- }
-
- void create(const uint32_t bufferSize)
- {
- CARLA_SAFE_ASSERT(! isReady);
- CARLA_SAFE_ASSERT(inBuf == nullptr);
- CARLA_SAFE_ASSERT(outBuf == nullptr);
-
- if (inCount > 0)
- {
- inBuf = new float*[inCount];
-
- for (uint32_t i=0; i < inCount; ++i)
- inBuf[i] = nullptr;
- }
-
- if (outCount > 0)
- {
- outBuf = new float*[outCount];
-
- for (uint32_t i=0; i < outCount; ++i)
- outBuf[i] = nullptr;
- }
-
- resize(bufferSize, false);
- }
-
- void resize(const uint32_t bufferSize, const bool doClear = true)
- {
- if (doClear)
- clearBuffers();
-
- CARLA_SAFE_ASSERT_RETURN(bufferSize != 0,);
-
- for (uint32_t i=0; i < inCount; ++i)
- {
- inBuf[i] = new float[bufferSize];
- FLOAT_CLEAR(inBuf[i], bufferSize);
- }
-
- for (uint32_t i=0; i < outCount; ++i)
- {
- outBuf[i] = new float[bufferSize];
- FLOAT_CLEAR(outBuf[i], bufferSize);
- }
- }
-
- CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalAudio)
- };
-
- // -----------------------------------------------------------------------
- // InternalEvents
-
- struct EngineInternalEvents {
- EngineEvent* in;
- EngineEvent* out;
-
- EngineInternalEvents() noexcept
- : in(nullptr),
- out(nullptr) {}
-
- ~EngineInternalEvents() noexcept
- {
- CARLA_SAFE_ASSERT(in == nullptr);
- CARLA_SAFE_ASSERT(out == nullptr);
- }
-
- void clear() noexcept
- {
- if (in != nullptr)
- {
- delete[] in;
- in = nullptr;
- }
-
- if (out != nullptr)
- {
- delete[] out;
- out = nullptr;
- }
- }
-
- CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalEvents)
- };
-
- #ifndef BUILD_BRIDGE
- // -----------------------------------------------------------------------
- // InternalGraph
-
- struct EngineInternalGraph {
- bool isRack;
-
- union {
- RackGraph* rack;
- PatchbayGraph* patchbay;
- };
-
- EngineInternalGraph() noexcept
- : isRack(true)
- {
- rack = nullptr;
- }
-
- ~EngineInternalGraph() noexcept
- {
- CARLA_SAFE_ASSERT(rack == nullptr);
- }
-
- void create()
- {
- CARLA_SAFE_ASSERT(rack == nullptr);
-
- if (isRack)
- rack = new RackGraph();
- else
- patchbay = new PatchbayGraph();
- }
-
- void clear()
- {
- if (isRack)
- {
- CARLA_SAFE_ASSERT_RETURN(rack != nullptr,);
- delete rack;
- rack = nullptr;
- }
- else
- {
- CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,);
- delete patchbay;
- patchbay = nullptr;
- }
- }
-
- CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalGraph)
- };
- #endif
-
- // -----------------------------------------------------------------------
- // InternalTime
-
- struct EngineInternalTime {
- bool playing;
- uint64_t frame;
-
- EngineInternalTime() noexcept
- : playing(false),
- frame(0) {}
-
- CARLA_DECLARE_NON_COPY_STRUCT(EngineInternalTime)
- };
-
- // -----------------------------------------------------------------------
- // NextAction
-
- enum EnginePostAction {
- kEnginePostActionNull,
- kEnginePostActionZeroCount,
- kEnginePostActionRemovePlugin,
- kEnginePostActionSwitchPlugins
- };
-
- struct EngineNextAction {
- EnginePostAction opcode;
- unsigned int pluginId;
- unsigned int value;
- CarlaMutex mutex;
-
- EngineNextAction() noexcept
- : opcode(kEnginePostActionNull),
- pluginId(0),
- value(0) {}
-
- ~EngineNextAction() noexcept
- {
- CARLA_SAFE_ASSERT(opcode == kEnginePostActionNull);
- }
-
- void ready() const noexcept
- {
- mutex.lock();
- mutex.unlock();
- }
-
- CARLA_DECLARE_NON_COPY_STRUCT(EngineNextAction)
- };
-
- // -----------------------------------------------------------------------
- // EnginePluginData
-
- 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;
- }
- };
-
- // -----------------------------------------------------------------------
- // CarlaEngineProtectedData
-
- struct CarlaEngineProtectedData {
- CarlaEngineOsc osc;
- CarlaEngineThread thread;
-
- const CarlaOscData* oscData;
-
- EngineCallbackFunc callback;
- void* callbackPtr;
-
- FileCallbackFunc fileCallback;
- void* fileCallbackPtr;
-
- uint hints;
- uint32_t bufferSize;
- double sampleRate;
-
- bool aboutToClose; // don't re-activate thread if true
- uint curPluginCount; // number of plugins loaded (0...max)
- uint maxPluginNumber; // number of plugins allowed (0, 16, 99 or 255)
- uint nextPluginId; // invalid if == maxPluginNumber
-
- CarlaString lastError;
- CarlaString name;
- EngineOptions options;
- EngineTimeInfo timeInfo;
-
- EnginePluginData* plugins;
-
- #ifndef BUILD_BRIDGE
- EngineInternalAudio audio;
- #endif
- EngineInternalEvents events;
- #ifndef BUILD_BRIDGE
- EngineInternalGraph graph;
- #endif
- EngineInternalTime time;
- EngineNextAction nextAction;
-
- // -------------------------------------------------------------------
-
- CarlaEngineProtectedData(CarlaEngine* const engine) noexcept;
- ~CarlaEngineProtectedData() noexcept;
-
- // -------------------------------------------------------------------
-
- void doPluginRemove() noexcept;
- void doPluginsSwitch() noexcept;
- void doNextPluginAction(const bool unlock) noexcept;
-
- #ifndef BUILD_BRIDGE
- // -------------------------------------------------------------------
-
- // the base, where plugins run
- void processRack(const float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline);
-
- // extended, will call processRack() in the middle
- void processRackFull(const float* const* const inBuf, const uint32_t inCount, float* const* const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline);
- #endif
-
- // -------------------------------------------------------------------
-
- #ifdef CARLA_PROPER_CPP11_SUPPORT
- CarlaEngineProtectedData() = delete;
- CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData)
- #endif
- };
-
- // -----------------------------------------------------------------------
-
- class ScopedActionLock
- {
- public:
- ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const uint pluginId, const uint value, const bool lockWait) noexcept;
- ~ScopedActionLock() noexcept;
-
- private:
- CarlaEngineProtectedData* const fData;
-
- CARLA_PREVENT_HEAP_ALLOCATION
- CARLA_DECLARE_NON_COPY_CLASS(ScopedActionLock)
- };
-
- // -----------------------------------------------------------------------
-
- CARLA_BACKEND_END_NAMESPACE
-
- #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED
|