| @@ -999,7 +999,7 @@ bool CarlaEngine::removePlugin(const unsigned int id) | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | ||||
| const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionRemovePlugin, id, 0, lockWait); | |||||
| #ifndef BUILD_BRIDGE | #ifndef BUILD_BRIDGE | ||||
| if (isOscControlRegistered()) | if (isOscControlRegistered()) | ||||
| @@ -1028,7 +1028,7 @@ bool CarlaEngine::removeAllPlugins() | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| const bool lockWait(isRunning()); | const bool lockWait(isRunning()); | ||||
| const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionZeroCount, 0, 0, lockWait); | |||||
| callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | callback(ENGINE_CALLBACK_IDLE, 0, 0, 0, 0.0f, nullptr); | ||||
| @@ -1157,7 +1157,7 @@ bool CarlaEngine::switchPlugins(const unsigned int idA, const unsigned int idB) | |||||
| pData->thread.stopThread(500); | pData->thread.stopThread(500); | ||||
| const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | const bool lockWait(isRunning() && pData->options.processMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS); | ||||
| const CarlaEngineProtectedData::ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait); | |||||
| const ScopedActionLock sal(pData, kEnginePostActionSwitchPlugins, idA, idB, lockWait); | |||||
| #ifndef BUILD_BRIDGE // TODO | #ifndef BUILD_BRIDGE // TODO | ||||
| //if (isOscControlRegistered()) | //if (isOscControlRegistered()) | ||||
| @@ -1702,6 +1702,7 @@ bool CarlaEngine::patchbayConnect(const int groupA, const int portA, const int g | |||||
| { | { | ||||
| 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->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); | CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.buffer != nullptr, nullptr); | |||||
| carla_debug("CarlaEngine::patchbayConnect(%i, %i)", portA, portB); | carla_debug("CarlaEngine::patchbayConnect(%i, %i)", portA, portB); | ||||
| if (portA < 0 || portB < 0) | if (portA < 0 || portB < 0) | ||||
| @@ -1710,94 +1711,17 @@ bool CarlaEngine::patchbayConnect(const int groupA, const int portA, const int g | |||||
| return false; | return false; | ||||
| } | } | ||||
| return pData->bufAudio.connect(this, groupA, portA, groupB, portB); | |||||
| return pData->bufAudio.buffer->connect(this, groupA, portA, groupB, portB); | |||||
| } | } | ||||
| bool CarlaEngine::patchbayDisconnect(const uint connectionId) | bool CarlaEngine::patchbayDisconnect(const uint 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->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); | CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.buffer != nullptr, false); | |||||
| carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); | carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); | ||||
| if (pData->bufAudio.usePatchbay) | |||||
| { | |||||
| // not implemented yet | |||||
| return false; | |||||
| } | |||||
| #if 0 | |||||
| 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 otherPort((connection.portOut >= 0) ? connection.portOut : connection.portIn); | |||||
| const int carlaPort((otherPort == connection.portOut) ? connection.portIn : connection.portOut); | |||||
| if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_MIDI_IN, false); | |||||
| const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000); | |||||
| disconnectRackMidiInPort(portId); | |||||
| } | |||||
| else if (otherPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000) | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_MIDI_OUT, false); | |||||
| const int portId(otherPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000); | |||||
| disconnectRackMidiOutPort(portId); | |||||
| } | |||||
| else if (otherPort >= 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(otherPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); | |||||
| rack->connectLock.enter(); | |||||
| if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1) | |||||
| rack->connectedOut1.removeAll(portId); | |||||
| else | |||||
| rack->connectedOut2.removeAll(portId); | |||||
| rack->connectLock.leave(); | |||||
| } | |||||
| else if (otherPort >= 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(otherPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000); | |||||
| rack->connectLock.enter(); | |||||
| if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1) | |||||
| rack->connectedIn1.removeAll(portId); | |||||
| else | |||||
| rack->connectedIn2.removeAll(portId); | |||||
| rack->connectLock.leave(); | |||||
| } | |||||
| else | |||||
| { | |||||
| CARLA_SAFE_ASSERT_RETURN(false, false); | |||||
| } | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, 0, 0, 0.0f, nullptr); | |||||
| rack->usedConnections.remove(it); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| #endif | |||||
| setLastError("Failed to find connection"); | |||||
| return false; | |||||
| return pData->bufAudio.buffer->disconnect(this, connectionId); | |||||
| } | } | ||||
| bool CarlaEngine::patchbayRefresh() | bool CarlaEngine::patchbayRefresh() | ||||
| @@ -2084,9 +2008,10 @@ void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeak | |||||
| const char* const* CarlaEngine::getPatchbayConnections() const | const char* const* CarlaEngine::getPatchbayConnections() const | ||||
| { | { | ||||
| CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.buffer != nullptr, nullptr); | |||||
| carla_debug("CarlaEngine::getPatchbayConnections()"); | carla_debug("CarlaEngine::getPatchbayConnections()"); | ||||
| return pData->bufAudio.getConnections(); | |||||
| return pData->bufAudio.buffer->getConnections(); | |||||
| } | } | ||||
| void CarlaEngine::restorePatchbayConnection(const char* const connSource, const char* const connTarget) | void CarlaEngine::restorePatchbayConnection(const char* const connSource, const char* const connTarget) | ||||
| @@ -44,18 +44,66 @@ CARLA_BACKEND_START_NAMESPACE | |||||
| const unsigned short kMaxEngineEventInternalCount = 512; | const unsigned short kMaxEngineEventInternalCount = 512; | ||||
| // ----------------------------------------------------------------------- | |||||
| // Rack Patchbay stuff | |||||
| enum RackPatchbayGroupIds { | |||||
| RACK_PATCHBAY_GROUP_CARLA = 0, | |||||
| RACK_PATCHBAY_GROUP_AUDIO = 1, | |||||
| RACK_PATCHBAY_GROUP_MIDI = 2, | |||||
| RACK_PATCHBAY_GROUP_MAX = 3 | |||||
| }; | |||||
| enum RackPatchbayCarlaPortIds { | |||||
| RACK_PATCHBAY_CARLA_PORT_NULL = 0, | |||||
| RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1 = 1, | |||||
| RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2 = 2, | |||||
| RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1 = 3, | |||||
| RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2 = 4, | |||||
| RACK_PATCHBAY_CARLA_PORT_MIDI_IN = 5, | |||||
| RACK_PATCHBAY_CARLA_PORT_MIDI_OUT = 6, | |||||
| RACK_PATCHBAY_CARLA_PORT_MAX = 7 | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | |||||
| // ... | |||||
| struct PortNameToId { | |||||
| int group, port; | |||||
| char name[STR_MAX+1]; | |||||
| }; | |||||
| struct ConnectionToId { | |||||
| uint id; | |||||
| int groupA, portA; | |||||
| int groupB, portB; | |||||
| }; | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| // AbstractEngineBuffer | // AbstractEngineBuffer | ||||
| struct AbstractEngineBuffer { | struct AbstractEngineBuffer { | ||||
| AbstractEngineBuffer(const uint32_t /*bufferSize*/) {} | |||||
| uint lastConnectionId; | |||||
| LinkedList<ConnectionToId> usedConnections; | |||||
| CarlaCriticalSection connectLock; | |||||
| AbstractEngineBuffer() | |||||
| : lastConnectionId(0) {} | |||||
| virtual ~AbstractEngineBuffer() noexcept {} | virtual ~AbstractEngineBuffer() noexcept {} | ||||
| virtual void clear() noexcept = 0; | |||||
| virtual void clear() noexcept | |||||
| { | |||||
| lastConnectionId = 0; | |||||
| usedConnections.clear(); | |||||
| } | |||||
| virtual void resize(const uint32_t bufferSize) = 0; | virtual void resize(const uint32_t bufferSize) = 0; | ||||
| virtual bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int port) noexcept = 0; | |||||
| virtual bool disconnect(const uint connectionId) noexcept = 0; | |||||
| virtual bool connect(CarlaEngine* const engine, const int groupA, const int portA, const int groupB, const int portB) noexcept = 0; | |||||
| virtual bool disconnect(CarlaEngine* const engine, const uint connectionId) noexcept = 0; | |||||
| virtual void refresh(CarlaEngine* const engine, const LinkedList<PortNameToId>& midiIns, const LinkedList<PortNameToId>& midiOuts); | |||||
| virtual const char* const* getConnections() const = 0; | virtual const char* const* getConnections() const = 0; | ||||
| }; | }; | ||||
| @@ -64,7 +112,7 @@ struct AbstractEngineBuffer { | |||||
| // InternalAudio | // InternalAudio | ||||
| struct EngineInternalAudio { | struct EngineInternalAudio { | ||||
| bool isPatchbay; // can only be patchbay or rack mode | |||||
| bool isRack; // can only be rack or patchbay mode | |||||
| bool isReady; | bool isReady; | ||||
| uint inCount; | uint inCount; | ||||
| @@ -73,7 +121,7 @@ struct EngineInternalAudio { | |||||
| AbstractEngineBuffer* buffer; | AbstractEngineBuffer* buffer; | ||||
| EngineInternalAudio() noexcept | EngineInternalAudio() noexcept | ||||
| : isPatchbay(false), | |||||
| : isRack(true), | |||||
| isReady(false), | isReady(false), | ||||
| inCount(0), | inCount(0), | ||||
| outCount(0), | outCount(0), | ||||
| @@ -227,7 +275,7 @@ struct CarlaEngineProtectedData { | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| CarlaEngineProtectedData(CarlaEngine* const engine); | |||||
| CarlaEngineProtectedData(CarlaEngine* const engine) noexcept; | |||||
| ~CarlaEngineProtectedData() noexcept; | ~CarlaEngineProtectedData() noexcept; | ||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| @@ -236,9 +284,9 @@ struct CarlaEngineProtectedData { | |||||
| void doPluginsSwitch() noexcept; | void doPluginsSwitch() noexcept; | ||||
| void doNextPluginAction(const bool unlock) noexcept; | void doNextPluginAction(const bool unlock) noexcept; | ||||
| #ifndef BUILD_BRIDGE | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| #ifndef BUILD_BRIDGE | |||||
| // the base, where plugins run | // the base, where plugins run | ||||
| void processRack(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline); | void processRack(float* inBufReal[2], float* outBuf[2], const uint32_t nframes, const bool isOffline); | ||||
| @@ -248,21 +296,6 @@ struct CarlaEngineProtectedData { | |||||
| // ------------------------------------------------------------------- | // ------------------------------------------------------------------- | ||||
| class ScopedActionLock | |||||
| { | |||||
| public: | |||||
| 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 | #ifdef CARLA_PROPER_CPP11_SUPPORT | ||||
| CarlaEngineProtectedData() = delete; | CarlaEngineProtectedData() = delete; | ||||
| CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData) | CARLA_DECLARE_NON_COPY_STRUCT(CarlaEngineProtectedData) | ||||
| @@ -271,6 +304,21 @@ struct CarlaEngineProtectedData { | |||||
| // ----------------------------------------------------------------------- | // ----------------------------------------------------------------------- | ||||
| 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 | CARLA_BACKEND_END_NAMESPACE | ||||
| #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED | #endif // CARLA_ENGINE_INTERNAL_HPP_INCLUDED | ||||
| @@ -315,7 +315,7 @@ public: | |||||
| uint8_t data[3] = { 0, 0, 0 }; | uint8_t data[3] = { 0, 0, 0 }; | ||||
| EngineControlEvent ctrlEvent = { type, param, value }; | EngineControlEvent ctrlEvent = { type, param, value }; | ||||
| ctrlEvent.dumpToMidiData(channel, size, data); | |||||
| ctrlEvent.convertToMidiData(channel, size, data); | |||||
| if (size == 0) | if (size == 0) | ||||
| return false; | return false; | ||||
| @@ -457,7 +457,7 @@ public: | |||||
| } | } | ||||
| #endif | #endif | ||||
| CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) /*noexcept*/ override | |||||
| CarlaEnginePort* addPort(const EnginePortType portType, const char* const name, const bool isInput) noexcept override | |||||
| { | { | ||||
| carla_debug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | carla_debug("CarlaEngineJackClient::addPort(%s, \"%s\", %s)", EnginePortType2Str(portType), name, bool2str(isInput)); | ||||
| @@ -481,36 +481,34 @@ public: | |||||
| port = jackbridge_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0); | port = jackbridge_port_register(fClient, name, JACK_DEFAULT_MIDI_TYPE, isInput ? JackPortIsInput : JackPortIsOutput, 0); | ||||
| break; | break; | ||||
| } | } | ||||
| } catch(...) {} | |||||
| if (port == nullptr) | |||||
| { | |||||
| carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - failed to create JACK port", EnginePortType2Str(portType), name, bool2str(isInput)); | |||||
| return nullptr; | |||||
| } | } | ||||
| CARLA_SAFE_EXCEPTION_RETURN("JackClient addPort", nullptr) | |||||
| } | } | ||||
| // Create Engine port | // Create Engine port | ||||
| switch (portType) | |||||
| { | |||||
| case kEnginePortTypeNull: | |||||
| break; | |||||
| case kEnginePortTypeAudio: { | |||||
| CarlaEngineJackAudioPort* const enginePort(new CarlaEngineJackAudioPort(fEngine, isInput, fClient, port)); | |||||
| fAudioPorts.append(enginePort); | |||||
| return enginePort; | |||||
| } | |||||
| case kEnginePortTypeCV: { | |||||
| CarlaEngineJackCVPort* const enginePort(new CarlaEngineJackCVPort(fEngine, isInput, fClient, port)); | |||||
| fCVPorts.append(enginePort); | |||||
| return enginePort; | |||||
| } | |||||
| case kEnginePortTypeEvent: { | |||||
| CarlaEngineJackEventPort* const enginePort(new CarlaEngineJackEventPort(fEngine, isInput, fClient, port)); | |||||
| fEventPorts.append(enginePort); | |||||
| return enginePort; | |||||
| } | |||||
| try { | |||||
| switch (portType) | |||||
| { | |||||
| case kEnginePortTypeNull: | |||||
| break; | |||||
| case kEnginePortTypeAudio: { | |||||
| CarlaEngineJackAudioPort* const enginePort(new CarlaEngineJackAudioPort(fEngine, isInput, fClient, port)); | |||||
| fAudioPorts.append(enginePort); | |||||
| return enginePort; | |||||
| } | |||||
| case kEnginePortTypeCV: { | |||||
| CarlaEngineJackCVPort* const enginePort(new CarlaEngineJackCVPort(fEngine, isInput, fClient, port)); | |||||
| fCVPorts.append(enginePort); | |||||
| return enginePort; | |||||
| } | |||||
| case kEnginePortTypeEvent: { | |||||
| CarlaEngineJackEventPort* const enginePort(new CarlaEngineJackEventPort(fEngine, isInput, fClient, port)); | |||||
| fEventPorts.append(enginePort); | |||||
| return enginePort; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| CARLA_SAFE_EXCEPTION_RETURN("JackClient new Port", nullptr) | |||||
| carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | carla_stderr("CarlaEngineJackClient::addPort(%s, \"%s\", %s) - invalid type", EnginePortType2Str(portType), name, bool2str(isInput)); | ||||
| return nullptr; | return nullptr; | ||||
| @@ -1343,7 +1341,7 @@ protected: | |||||
| case kEngineEventTypeControl: | case kEngineEventTypeControl: | ||||
| { | { | ||||
| const EngineControlEvent& ctrlEvent(engineEvent.ctrl); | const EngineControlEvent& ctrlEvent(engineEvent.ctrl); | ||||
| ctrlEvent.dumpToMidiData(engineEvent.channel, size, data); | |||||
| ctrlEvent.convertToMidiData(engineEvent.channel, size, data); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -116,7 +116,7 @@ void CarlaEngineOsc::idle() const noexcept | |||||
| if (lo_server_recv_noblock(fServerTCP, 0) == 0) | if (lo_server_recv_noblock(fServerTCP, 0) == 0) | ||||
| break; | break; | ||||
| } | } | ||||
| CARLA_SAFE_EXCEPTION_BREAK("OSC idle TCP") | |||||
| CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle TCP") | |||||
| } | } | ||||
| } | } | ||||
| @@ -128,7 +128,7 @@ void CarlaEngineOsc::idle() const noexcept | |||||
| if (lo_server_recv_noblock(fServerUDP, 0) == 0) | if (lo_server_recv_noblock(fServerUDP, 0) == 0) | ||||
| break; | break; | ||||
| } | } | ||||
| CARLA_SAFE_EXCEPTION_BREAK("OSC idle UDP") | |||||
| CARLA_SAFE_EXCEPTION_CONTINUE("OSC idle UDP") | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,431 +0,0 @@ | |||||
| /* | |||||
| * 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" | |||||
| #include "CarlaMIDI.h" | |||||
| #include "CarlaMathUtils.hpp" | |||||
| // ----------------------------------------------------------------------- | |||||
| CARLA_BACKEND_START_NAMESPACE | |||||
| #if 0 | |||||
| } // Fix editor indentation | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | |||||
| // CarlaEngineProtectedData | |||||
| CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) | |||||
| : osc(engine), | |||||
| thread(engine), | |||||
| oscData(nullptr), | |||||
| callback(nullptr), | |||||
| callbackPtr(nullptr), | |||||
| fileCallback(nullptr), | |||||
| fileCallbackPtr(nullptr), | |||||
| hints(0x0), | |||||
| bufferSize(0), | |||||
| sampleRate(0.0), | |||||
| aboutToClose(false), | |||||
| curPluginCount(0), | |||||
| maxPluginNumber(0), | |||||
| nextPluginId(0), | |||||
| plugins(nullptr) {} | |||||
| CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept | |||||
| { | |||||
| CARLA_SAFE_ASSERT(curPluginCount == 0); | |||||
| CARLA_SAFE_ASSERT(maxPluginNumber == 0); | |||||
| CARLA_SAFE_ASSERT(nextPluginId == 0); | |||||
| CARLA_SAFE_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, kMaxEngineEventInternalCount); | |||||
| 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, kMaxEngineEventInternalCount); | |||||
| // initialize event outputs (zero) | |||||
| carla_zeroStruct<EngineEvent>(bufEvents.out, kMaxEngineEventInternalCount); | |||||
| } | |||||
| } | |||||
| 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, static_cast<int>(frames), tmpMin, tmpMax); | |||||
| pluginData.insPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f); | |||||
| FloatVectorOperations::findMinAndMax(inBuf1, static_cast<int>(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], static_cast<int>(frames), tmpMin, tmpMax); | |||||
| pluginData.outsPeak[0] = carla_max<float>(std::abs(tmpMin), std::abs(tmpMax), 1.0f); | |||||
| FloatVectorOperations::findMinAndMax(outBuf[1], static_cast<int>(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; | |||||
| } | |||||
| } | |||||
| 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 CarlaCriticalSectionScope _cs2(rack->connectLock); | |||||
| // connect input buffers | |||||
| if (rack->connectedIn1.count() == 0) | |||||
| { | |||||
| FLOAT_CLEAR(rack->in[0], nframes); | |||||
| } | |||||
| else | |||||
| { | |||||
| bool first = true; | |||||
| for (LinkedList<int>::Itenerator it = rack->connectedIn1.begin(); it.valid(); it.next()) | |||||
| { | |||||
| const int& port(it.getValue()); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(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->connectedIn2.count() == 0) | |||||
| { | |||||
| FLOAT_CLEAR(rack->in[1], nframes); | |||||
| } | |||||
| else | |||||
| { | |||||
| bool first = true; | |||||
| for (LinkedList<int>::Itenerator it = rack->connectedIn2.begin(); it.valid(); it.next()) | |||||
| { | |||||
| const int& port(it.getValue()); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(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->connectedOut1.count() != 0) | |||||
| { | |||||
| for (LinkedList<int>::Itenerator it = rack->connectedOut1.begin(); it.valid(); it.next()) | |||||
| { | |||||
| const int& port(it.getValue()); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(outCount)); | |||||
| FLOAT_ADD(outBuf[port], rack->out[0], nframes); | |||||
| } | |||||
| } | |||||
| if (rack->connectedOut2.count() != 0) | |||||
| { | |||||
| for (LinkedList<int>::Itenerator it = rack->connectedOut2.begin(); it.valid(); it.next()) | |||||
| { | |||||
| const int& port(it.getValue()); | |||||
| CARLA_SAFE_ASSERT_CONTINUE(port >= 0 && port < static_cast<int>(outCount)); | |||||
| FLOAT_ADD(outBuf[port], rack->out[1], nframes); | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | |||||
| // ----------------------------------------------------------------------- | |||||
| // ScopedActionLock | |||||
| 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 | |||||
| @@ -199,7 +199,7 @@ public: | |||||
| return false; | return false; | ||||
| } | } | ||||
| pData->bufAudio.usePatchbay = (pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY); | |||||
| pData->bufAudio.isRack = (pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK); | |||||
| RtAudio::StreamParameters iParams, oParams; | RtAudio::StreamParameters iParams, oParams; | ||||
| bool deviceSet = false; | bool deviceSet = false; | ||||
| @@ -419,7 +419,7 @@ public: | |||||
| pData->bufAudio.initPatchbay(); | pData->bufAudio.initPatchbay(); | ||||
| if (pData->bufAudio.usePatchbay) | |||||
| if (! pData->bufAudio.isRack) | |||||
| { | { | ||||
| // not implemented yet | // not implemented yet | ||||
| return false; | return false; | ||||
| @@ -428,7 +428,7 @@ public: | |||||
| char strBuf[STR_MAX+1]; | char strBuf[STR_MAX+1]; | ||||
| strBuf[STR_MAX] = '\0'; | strBuf[STR_MAX] = '\0'; | ||||
| EngineRackBuffers* const rack(pData->bufAudio.rack); | |||||
| AbstractEngineBuffer* const rack(pData->bufAudio.buffer); | |||||
| // Main | // Main | ||||
| { | { | ||||
| @@ -449,12 +449,12 @@ public: | |||||
| else | else | ||||
| std::strncpy(strBuf, "Capture", STR_MAX); | std::strncpy(strBuf, "Capture", STR_MAX); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | |||||
| for (uint i=0; i < pData->bufAudio.inCount; ++i) | for (uint i=0; i < pData->bufAudio.inCount; ++i) | ||||
| { | { | ||||
| std::snprintf(strBuf, STR_MAX, "capture_%i", i+1); | std::snprintf(strBuf, STR_MAX, "capture_%i", i+1); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_IN, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO, 0.0f, strBuf); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO, 0.0f, strBuf); | |||||
| } | } | ||||
| } | } | ||||
| @@ -465,18 +465,18 @@ public: | |||||
| else | else | ||||
| std::strncpy(strBuf, "Playback", STR_MAX); | std::strncpy(strBuf, "Playback", STR_MAX); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, PATCHBAY_ICON_HARDWARE, -1, 0.0f, strBuf); | |||||
| for (uint i=0; i < pData->bufAudio.outCount; ++i) | for (uint i=0; i < pData->bufAudio.outCount; ++i) | ||||
| { | { | ||||
| std::snprintf(strBuf, STR_MAX, "playback_%i", i+1); | std::snprintf(strBuf, STR_MAX, "playback_%i", i+1); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO_OUT, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, strBuf); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_AUDIO, static_cast<int>(i), PATCHBAY_PORT_TYPE_AUDIO|PATCHBAY_PORT_IS_INPUT, 0.0f, strBuf); | |||||
| } | } | ||||
| } | } | ||||
| // MIDI In | // MIDI In | ||||
| { | { | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI_IN, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports"); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Readable MIDI ports"); | |||||
| for (uint i=0, count=fDummyMidiIn.getPortCount(); i < count; ++i) | for (uint i=0, count=fDummyMidiIn.getPortCount(); i < count; ++i) | ||||
| { | { | ||||
| @@ -486,13 +486,13 @@ public: | |||||
| portNameToId.name[STR_MAX] = '\0'; | portNameToId.name[STR_MAX] = '\0'; | ||||
| fUsedMidiIns.append(portNameToId); | fUsedMidiIns.append(portNameToId); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI_IN, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI, 0.0f, portNameToId.name); | |||||
| } | } | ||||
| } | } | ||||
| // MIDI Out | // MIDI Out | ||||
| { | { | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI_OUT, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports"); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_CLIENT_ADDED, RACK_PATCHBAY_GROUP_MIDI, PATCHBAY_ICON_HARDWARE, -1, 0.0f, "Writable MIDI ports"); | |||||
| for (uint i=0, count=fDummyMidiOut.getPortCount(); i < count; ++i) | for (uint i=0, count=fDummyMidiOut.getPortCount(); i < count; ++i) | ||||
| { | { | ||||
| @@ -502,7 +502,7 @@ public: | |||||
| portNameToId.name[STR_MAX] = '\0'; | portNameToId.name[STR_MAX] = '\0'; | ||||
| fUsedMidiOuts.append(portNameToId); | fUsedMidiOuts.append(portNameToId); | ||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI_OUT, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); | |||||
| callback(ENGINE_CALLBACK_PATCHBAY_PORT_ADDED, RACK_PATCHBAY_GROUP_MIDI, portNameToId.portId, PATCHBAY_PORT_TYPE_MIDI|PATCHBAY_PORT_IS_INPUT, 0.0f, portNameToId.name); | |||||
| } | } | ||||
| } | } | ||||
| @@ -516,7 +516,7 @@ public: | |||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| connectionToId.id = rack->lastConnectionId; | connectionToId.id = rack->lastConnectionId; | ||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO_IN; | |||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO; | |||||
| connectionToId.portOut = port; | connectionToId.portOut = port; | ||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; | connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; | ||||
| connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1; | connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN1; | ||||
| @@ -535,7 +535,7 @@ public: | |||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| connectionToId.id = rack->lastConnectionId; | connectionToId.id = rack->lastConnectionId; | ||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO_IN; | |||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_AUDIO; | |||||
| connectionToId.portOut = port; | connectionToId.portOut = port; | ||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; | connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; | ||||
| connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2; | connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_AUDIO_IN2; | ||||
| @@ -556,7 +556,7 @@ public: | |||||
| connectionToId.id = rack->lastConnectionId; | connectionToId.id = rack->lastConnectionId; | ||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; | connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; | ||||
| connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1; | connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT1; | ||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO_OUT; | |||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO; | |||||
| connectionToId.portIn = port; | connectionToId.portIn = port; | ||||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); | std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); | ||||
| @@ -575,7 +575,7 @@ public: | |||||
| connectionToId.id = rack->lastConnectionId; | connectionToId.id = rack->lastConnectionId; | ||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; | connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; | ||||
| connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2; | connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_AUDIO_OUT2; | ||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO_OUT; | |||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_AUDIO; | |||||
| connectionToId.portIn = port; | connectionToId.portIn = port; | ||||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); | std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); | ||||
| @@ -593,7 +593,7 @@ public: | |||||
| ConnectionToId connectionToId; | ConnectionToId connectionToId; | ||||
| connectionToId.id = rack->lastConnectionId; | connectionToId.id = rack->lastConnectionId; | ||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_MIDI_IN; | |||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_MIDI; | |||||
| connectionToId.portOut = midiPort.portId; | connectionToId.portOut = midiPort.portId; | ||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; | connectionToId.groupIn = RACK_PATCHBAY_GROUP_CARLA; | ||||
| connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_MIDI_IN; | connectionToId.portIn = RACK_PATCHBAY_CARLA_PORT_MIDI_IN; | ||||
| @@ -613,7 +613,7 @@ public: | |||||
| connectionToId.id = rack->lastConnectionId; | connectionToId.id = rack->lastConnectionId; | ||||
| connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; | connectionToId.groupOut = RACK_PATCHBAY_GROUP_CARLA; | ||||
| connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_MIDI_OUT; | connectionToId.portOut = RACK_PATCHBAY_CARLA_PORT_MIDI_OUT; | ||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_MIDI_OUT; | |||||
| connectionToId.groupIn = RACK_PATCHBAY_GROUP_MIDI; | |||||
| connectionToId.portIn = midiPort.portId; | connectionToId.portIn = midiPort.portId; | ||||
| std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); | std::snprintf(strBuf, STR_MAX, "%i:%i:%i:%i", connectionToId.groupOut, connectionToId.portOut, connectionToId.groupIn, connectionToId.portIn); | ||||
| @@ -697,12 +697,12 @@ protected: | |||||
| fMidiInEvents.mutex.unlock(); | fMidiInEvents.mutex.unlock(); | ||||
| } | } | ||||
| if (pData->bufAudio.usePatchbay) | |||||
| if (pData->bufAudio.isRack) | |||||
| { | { | ||||
| pData->processRackFull(fAudioBufIn, pData->bufAudio.inCount, fAudioBufOut, pData->bufAudio.outCount, nframes, false); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| pData->processRackFull(fAudioBufIn, pData->bufAudio.inCount, fAudioBufOut, pData->bufAudio.outCount, nframes, false); | |||||
| } | } | ||||
| // output audio | // output audio | ||||