diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index a2e77cc9c..1ce205fe0 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -834,14 +834,16 @@ public: static CarlaPlugin* newLV2(const Initializer& init); static CarlaPlugin* newVST(const Initializer& init); static CarlaPlugin* newAU(const Initializer& init); - static CarlaPlugin* newCsound(const Initializer& init); - static CarlaPlugin* newGIG(const Initializer& init, const bool use16Outs); - static CarlaPlugin* newSF2(const Initializer& init, const bool use16Outs); - static CarlaPlugin* newSFZ(const Initializer& init, const bool use16Outs); + static CarlaPlugin* newCsound(const Initializer& init); static CarlaPlugin* newJuce(const Initializer& init, const char* const format); static CarlaPlugin* newFluidSynth(const Initializer& init, const bool use16Outs); static CarlaPlugin* newLinuxSampler(const Initializer& init, const char* const format, const bool use16Outs); + + static CarlaPlugin* newFileCSD(const Initializer& init); + static CarlaPlugin* newFileGIG(const Initializer& init, const bool use16Outs); + static CarlaPlugin* newFileSF2(const Initializer& init, const bool use16Outs); + static CarlaPlugin* newFileSFZ(const Initializer& init); #endif // ------------------------------------------------------------------- diff --git a/source/backend/engine/CarlaEngine.cpp b/source/backend/engine/CarlaEngine.cpp index 4c61c74c6..5c09917d1 100644 --- a/source/backend/engine/CarlaEngine.cpp +++ b/source/backend/engine/CarlaEngine.cpp @@ -21,7 +21,6 @@ * - implement processPatchbay() * - implement oscSend_control_switch_plugins() * - proper find&load plugins - * - uncomment CarlaPlugin::newAU and newCSOUND * - something about the peaks? * - patchbayDisconnect should return false sometimes */ @@ -51,6 +50,246 @@ CARLA_BACKEND_START_NAMESPACE } // Fix editor indentation #endif +// ----------------------------------------------------------------------- +// Fallback data + +static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} }; + +// ----------------------------------------------------------------------- +// Carla Engine port (Abstract) + +CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInput) + : fEngine(engine), + fIsInput(isInput) +{ + carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInput)); +} + +CarlaEnginePort::~CarlaEnginePort() +{ + carla_debug("CarlaEnginePort::~CarlaEnginePort()"); +} + +// ----------------------------------------------------------------------- +// Carla Engine Audio port + +CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInput) + : CarlaEnginePort(engine, isInput), + fBuffer(nullptr) +{ + carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); +} + +CarlaEngineAudioPort::~CarlaEngineAudioPort() +{ + carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()"); +} + +void CarlaEngineAudioPort::initBuffer() +{ +} + +// ----------------------------------------------------------------------- +// Carla Engine CV port + +CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput) + : CarlaEnginePort(engine, isInput), + fBuffer(nullptr), + fProcessMode(engine.getProccessMode()) +{ + carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput)); + + if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) + fBuffer = new float[engine.getBufferSize()]; +} + +CarlaEngineCVPort::~CarlaEngineCVPort() +{ + carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()"); + + if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) + { + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + + delete[] fBuffer; + fBuffer = nullptr; + } +} + +void CarlaEngineCVPort::initBuffer() +{ + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); + + carla_zeroFloat(fBuffer, fEngine.getBufferSize()); +} + +void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) +{ + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); + + delete[] fBuffer; + fBuffer = new float[bufferSize]; +} + +// ----------------------------------------------------------------------- +// Carla Engine Event port + +CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput) + : CarlaEnginePort(engine, isInput), + fBuffer(nullptr), + fProcessMode(engine.getProccessMode()) +{ + carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); + + if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) + fBuffer = new EngineEvent[EngineEvent::kMaxInternalCount]; +} + +CarlaEngineEventPort::~CarlaEngineEventPort() +{ + carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); + + if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) + { + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); + + delete[] fBuffer; + fBuffer = nullptr; + } +} + +void CarlaEngineEventPort::initBuffer() +{ + if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE) + fBuffer = fEngine.getInternalEventBuffer(fIsInput); + else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput) + carla_zeroStruct(fBuffer, EngineEvent::kMaxInternalCount); +} + +uint32_t CarlaEngineEventPort::getEventCount() const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(fIsInput, 0); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); + + uint32_t i=0; + + for (; i < EngineEvent::kMaxInternalCount; ++i) + { + if (fBuffer[i].type == kEngineEventTypeNull) + break; + } + + return i; +} + +const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) noexcept +{ + CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); + CARLA_SAFE_ASSERT_RETURN(index < EngineEvent::kMaxInternalCount, kFallbackEngineEvent); + + return fBuffer[index]; +} + +const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) noexcept +{ + return fBuffer[index]; +} + +bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) +{ + CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); + CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); + CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); + + if (type == kEngineControlEventTypeParameter) { + CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); + } + + const float fixedValue(carla_fixValue(0.0f, 1.0f, value)); + + for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) + { + if (fBuffer[i].type != kEngineEventTypeNull) + continue; + + EngineEvent& event(fBuffer[i]); + + event.type = kEngineEventTypeControl; + event.time = time; + event.channel = channel; + + event.ctrl.type = type; + event.ctrl.param = param; + event.ctrl.value = fixedValue; + + return true; + } + + carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full"); + return false; +} + +bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) +{ + return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value); +} + +bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) +{ + CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); + CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); + CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); + CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); + CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); + + for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) + { + if (fBuffer[i].type != kEngineEventTypeNull) + continue; + + EngineEvent& event(fBuffer[i]); + + event.type = kEngineEventTypeMidi; + event.time = time; + event.channel = channel; + + event.midi.port = port; + event.midi.size = size; + + event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data)); + + uint8_t j=1; + for (; j < size; ++j) + event.midi.data[j] = data[j]; + for (; j < EngineMidiEvent::kDataSize; ++j) + event.midi.data[j] = 0; + + return true; + } + + carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full"); + return false; +} + +bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) +{ + return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data); +} + +bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) +{ + return writeMidiEvent(time, channel, midi.port, midi.size, midi.data); +} + // ----------------------------------------------------------------------- // Carla Engine client (Abstract) @@ -572,6 +811,7 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons else #endif // BUILD_BRIDGE { + bool use16Outs; setLastError("Invalid or unsupported plugin type"); switch (ptype) @@ -580,7 +820,34 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons break; case PLUGIN_INTERNAL: - plugin = CarlaPlugin::newNative(init); + if (std::strcmp(label, "Csound") == 0) + { + plugin = CarlaPlugin::newCsound(init); + } + else if (std::strcmp(label, "FluidSynth") == 0) + { + use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true")); + plugin = CarlaPlugin::newFluidSynth(init, use16Outs); + } + else if (std::strcmp(label, "LinuxSampler (GIG)") == 0) + { + use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true")); + plugin = CarlaPlugin::newLinuxSampler(init, "GIG", use16Outs); + } + else if (std::strcmp(label, "LinuxSampler (SF2)") == 0) + { + use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true")); + plugin = CarlaPlugin::newLinuxSampler(init, "SF2", use16Outs); + } + else if (std::strcmp(label, "LinuxSampler (SFZ)") == 0) + { + use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true")); + plugin = CarlaPlugin::newLinuxSampler(init, "SFZ", use16Outs); + } + else + { + plugin = CarlaPlugin::newNative(init); + } break; case PLUGIN_LADSPA: @@ -604,19 +871,21 @@ bool CarlaEngine::addPlugin(const BinaryType btype, const PluginType ptype, cons break; case PLUGIN_FILE_CSD: - plugin = CarlaPlugin::newCsound(init); + plugin = CarlaPlugin::newFileCSD(init); break; case PLUGIN_FILE_GIG: - plugin = CarlaPlugin::newGIG(init, (extra != nullptr && std::strcmp((const char*)extra, "true"))); + use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true")); + plugin = CarlaPlugin::newFileGIG(init, use16Outs); break; case PLUGIN_FILE_SF2: - plugin = CarlaPlugin::newSF2(init, (extra != nullptr && std::strcmp((const char*)extra, "true"))); + use16Outs = (extra != nullptr && std::strcmp((const char*)extra, "true")); + plugin = CarlaPlugin::newFileSF2(init, use16Outs); break; case PLUGIN_FILE_SFZ: - plugin = CarlaPlugin::newSFZ(init, (extra != nullptr && std::strcmp((const char*)extra, "true"))); + plugin = CarlaPlugin::newFileSFZ(init); break; } } @@ -1263,6 +1532,200 @@ void CarlaEngine::setCallback(const EngineCallbackFunc func, void* const ptr) no pData->callbackPtr = ptr; } +#ifndef BUILD_BRIDGE +// ----------------------------------------------------------------------- +// Patchbay + +bool CarlaEngine::patchbayConnect(const int portA, const int portB) +{ + CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); + CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); + carla_debug("CarlaEngineRtAudio::patchbayConnect(%i, %i)", portA, portB); + + if (pData->bufAudio.usePatchbay) + { + // not implemented yet + return false; + } + + EngineRackBuffers* const rack(pData->bufAudio.rack); + + CARLA_SAFE_ASSERT_RETURN_ERR(portA > RACK_PATCHBAY_PORT_MAX, "Invalid output port"); + CARLA_SAFE_ASSERT_RETURN_ERR(portB > RACK_PATCHBAY_PORT_MAX, "Invalid input port"); + + // only allow connections between Carla and other ports + if (portA < 0 && portB < 0) + { + setLastError("Invalid connection (1)"); + return false; + } + if (portA >= 0 && portB >= 0) + { + setLastError("Invalid connection (2)"); + return false; + } + + const int carlaPort = (portA < 0) ? portA : portB; + const int targetPort = (carlaPort == portA) ? portB : portA; + bool makeConnection = false; + + switch (carlaPort) + { + case RACK_PATCHBAY_PORT_AUDIO_IN1: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); + rack->connectLock.lock(); + rack->connectedIns[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_AUDIO_IN2: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); + rack->connectLock.lock(); + rack->connectedIns[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_AUDIO_OUT1: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); + rack->connectLock.lock(); + rack->connectedOuts[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_AUDIO_OUT2: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); + rack->connectLock.lock(); + rack->connectedOuts[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + rack->connectLock.unlock(); + makeConnection = true; + break; + + case RACK_PATCHBAY_PORT_MIDI_IN: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_IN*1000+999); + makeConnection = connectRackMidiInPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_IN*1000); + break; + + case RACK_PATCHBAY_PORT_MIDI_OUT: + CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000); + CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_OUT*1000+999); + makeConnection = connectRackMidiOutPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_OUT*1000); + break; + } + + if (! makeConnection) + { + setLastError("Invalid connection (3)"); + return false; + } + + ConnectionToId connectionToId; + connectionToId.id = rack->lastConnectionId; + connectionToId.portOut = portA; + connectionToId.portIn = portB; + + callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, portA, portB, 0.0f, nullptr); + + rack->usedConnections.append(connectionToId); + rack->lastConnectionId++; + + return true; +} + +bool CarlaEngine::patchbayDisconnect(const int connectionId) +{ + CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); + CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); + carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); + + if (pData->bufAudio.usePatchbay) + { + // not implemented yet + return false; + } + + EngineRackBuffers* const rack(pData->bufAudio.rack); + + CARLA_SAFE_ASSERT_RETURN_ERR(rack->usedConnections.count() > 0, "No connections available"); + + for (LinkedList::Itenerator it=rack->usedConnections.begin(); it.valid(); it.next()) + { + const ConnectionToId& connection(it.getValue()); + + if (connection.id == connectionId) + { + const int targetPort((connection.portOut >= 0) ? connection.portOut : connection.portIn); + const int carlaPort((targetPort == connection.portOut) ? connection.portIn : connection.portOut); + + if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000) + { + const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000); + disconnectRackMidiInPort(portId); + } + else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000) + { + const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000); + disconnectRackMidiOutPort(portId); + } + else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000) + { + CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2, false); + + const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); + + rack->connectLock.lock(); + + if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1) + rack->connectedOuts[0].removeAll(portId); + else + rack->connectedOuts[1].removeAll(portId); + + rack->connectLock.unlock(); + } + else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000) + { + CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2, false); + + const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000); + + rack->connectLock.lock(); + + if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1) + rack->connectedIns[0].removeAll(portId); + else + rack->connectedIns[1].removeAll(portId); + + rack->connectLock.unlock(); + } + else + { + CARLA_SAFE_ASSERT_RETURN(false, false); + } + + callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, connection.portOut, connection.portIn, 0.0f, nullptr); + + rack->usedConnections.remove(it); + break; + } + } + + return true; +} + +bool CarlaEngine::patchbayRefresh() +{ + setLastError("Unsupported operation"); + return false; +} +#endif + // ----------------------------------------------------------------------- // Transport @@ -1400,6 +1863,45 @@ void CarlaEngine::setOption(const EngineOption option, const int value, const ch } } +// ----------------------------------------------------------------------- +// OSC Stuff + +#ifdef BUILD_BRIDGE +bool CarlaEngine::isOscBridgeRegistered() const noexcept +{ + return (pData->oscData != nullptr); +} +#else +bool CarlaEngine::isOscControlRegistered() const noexcept +{ + return pData->osc.isControlRegistered(); +} +#endif + +void CarlaEngine::idleOsc() const noexcept +{ + try { + pData->osc.idle(); + } catch(...) {} +} + +const char* CarlaEngine::getOscServerPathTCP() const noexcept +{ + return pData->osc.getServerPathTCP(); +} + +const char* CarlaEngine::getOscServerPathUDP() const noexcept +{ + return pData->osc.getServerPathUDP(); +} + +#ifdef BUILD_BRIDGE +void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) const noexcept +{ + pData->oscData = oscData; +} +#endif + // ----------------------------------------------------------------------- // Helper functions @@ -1486,6 +1988,672 @@ void CarlaEngine::setPluginPeaks(const unsigned int pluginId, float const inPeak pluginData.outsPeak[1] = outPeaks[1]; } +// ----------------------------------------------------------------------- +// Bridge/Controller OSC stuff + +#ifdef BUILD_BRIDGE +void CarlaEngine::oscSend_bridge_plugin_info1(const PluginCategory category, const uint hints, const long uniqueId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_plugin_info1(%i:%s, %X, %l)", category, PluginCategory2Str(category), hints, uniqueId); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_plugin_info1"); + try_lo_send(pData->oscData->target, targetPath, "iih", static_cast(category), static_cast(hints), static_cast(uniqueId)); +} + +void CarlaEngine::oscSend_bridge_plugin_info2(const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); + CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_plugin_info2(\"%s\", \"%s\", \"%s\", \"%s\")", realName, label, maker, copyright); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_plugin_info2"); + try_lo_send(pData->oscData->target, targetPath, "ssss", realName, label, maker, copyright); +} + +void CarlaEngine::oscSend_bridge_audio_count(const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_audio_count(%i, %i)", ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+20]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_audio_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_bridge_midi_count(const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_midi_count(%i, %i)", ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+19]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_midi_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_bridge_parameter_count(const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_count(%i, %i)", ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_bridge_program_count(const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_program_count(%i)", count); + + char targetPath[std::strlen(pData->oscData->path)+22]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_program_count"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); +} + +void CarlaEngine::oscSend_bridge_midi_program_count(const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_midi_program_count(%i)", count); + + char targetPath[std::strlen(pData->oscData->path)+27]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_midi_program_count"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); +} + +void CarlaEngine::oscSend_bridge_parameter_data(const uint32_t index, const int32_t rindex, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", index, rindex, type, ParameterType2Str(type), hints, name, unit); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_data"); + try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(index), static_cast(rindex), static_cast(type), static_cast(hints), name, unit); +} + +void CarlaEngine::oscSend_bridge_parameter_ranges1(const uint32_t index, const float def, const float min, const float max) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, def, min, max); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_ranges1"); + try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), def, min, max); +} + +void CarlaEngine::oscSend_bridge_parameter_ranges2(const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, step, stepSmall, stepLarge); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_ranges2"); + try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), step, stepSmall, stepLarge); +} + +void CarlaEngine::oscSend_bridge_parameter_midi_cc(const uint32_t index, const int16_t cc) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_cc(%i, %i)", index, cc); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_midi_cc"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(cc)); +} + +void CarlaEngine::oscSend_bridge_parameter_midi_channel(const uint32_t index, const uint8_t channel) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_channel(%i, %i)", index, channel); + + char targetPath[std::strlen(pData->oscData->path)+31]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_midi_channel"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(channel)); +} + +void CarlaEngine::oscSend_bridge_parameter_value(const int32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); + carla_debug("CarlaEngine::oscSend_bridge_parameter_value(%i, %f)", index, value); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_parameter_value"); + try_lo_send(pData->oscData->target, targetPath, "if", index, value); +} + +void CarlaEngine::oscSend_bridge_default_value(const uint32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_default_value(%i, %f)", index, value); + + char targetPath[std::strlen(pData->oscData->path)+22]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_default_value"); + try_lo_send(pData->oscData->target, targetPath, "if", static_cast(index), value); +} + +void CarlaEngine::oscSend_bridge_current_program(const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_current_program(%i)", index); + + char targetPath[std::strlen(pData->oscData->path)+20]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_current_program"); + try_lo_send(pData->oscData->target, targetPath, "i", index); +} + +void CarlaEngine::oscSend_bridge_current_midi_program(const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_current_midi_program(%i)", index); + + char targetPath[std::strlen(pData->oscData->path)+25]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_current_midi_program"); + try_lo_send(pData->oscData->target, targetPath, "i", index); +} + +void CarlaEngine::oscSend_bridge_program_name(const uint32_t index, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_program_name(%i, \"%s\")", index, name); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_program_name"); + try_lo_send(pData->oscData->target, targetPath, "is", static_cast(index), name); +} + +void CarlaEngine::oscSend_bridge_midi_program_data(const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_midi_program_data(%i, %i, %i, \"%s\")", index, bank, program, name); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_midi_program_data"); + try_lo_send(pData->oscData->target, targetPath, "iiis", static_cast(index), static_cast(bank), static_cast(program), name); +} + +void CarlaEngine::oscSend_bridge_configure(const char* const key, const char* const value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(value != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_configure(\"%s\", \"%s\")", key, value); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_configure"); + try_lo_send(pData->oscData->target, targetPath, "ss", key, value); +} + +void CarlaEngine::oscSend_bridge_set_custom_data(const char* const type, const char* const key, const char* const value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_bridge_set_custom_data(\"%s\", \"%s\", \"%s\")", type, key, value); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_set_custom_data"); + try_lo_send(pData->oscData->target, targetPath, "sss", type, key, value); +} + +void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(chunkFile != nullptr && chunkFile[0] != '\0',); + carla_debug("CarlaEngine::oscSend_bridge_set_chunk_data(\"%s\")", chunkFile); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/bridge_set_chunk_data"); + try_lo_send(pData->oscData->target, targetPath, "s", chunkFile); +} + +// TODO? +//void oscSend_bridge_set_peaks() const; + +#else +void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',); + carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/add_plugin_start"); + try_lo_send(pData->oscData->target, targetPath, "is", static_cast(pluginId), pluginName); +} + +void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId); + + char targetPath[std::strlen(pData->oscData->path)+16]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/add_plugin_end"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); +} + +void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId); + + char targetPath[std::strlen(pData->oscData->path)+15]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/remove_plugin"); + try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); +} + +void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const long uniqueId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,); + carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, %l)", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_plugin_info1"); + try_lo_send(pData->oscData->target, targetPath, "iiiih", static_cast(pluginId), static_cast(type), static_cast(category), static_cast(hints), static_cast(uniqueId)); +} + +void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); + CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_plugin_info2"); + try_lo_send(pData->oscData->target, targetPath, "issss", static_cast(pluginId), realName, label, maker, copyright); +} + +void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_audio_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_midi_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_count"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); +} + +void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count); + + char targetPath[std::strlen(pData->oscData->path)+19]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_program_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); +} + +void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count); + + char targetPath[std::strlen(pData->oscData->path)+24]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_midi_program_count"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); +} + +void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit); + + char targetPath[std::strlen(pData->oscData->path)+20]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_data"); + try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(pluginId), static_cast(index), static_cast(type), static_cast(hints), name, unit); +} + +void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(def <= min && def >= max,); + CARLA_SAFE_ASSERT_RETURN(min < max,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_ranges1"); + try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), def, min, max); +} + +void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(step <= stepSmall && step >= stepLarge,); + CARLA_SAFE_ASSERT_RETURN(stepSmall <= stepLarge,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_ranges"); + try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), step, stepSmall, stepLarge); +} + +void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(cc <= 0x5F,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_midi_cc"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(cc)); +} + +void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); + + char targetPath[std::strlen(pData->oscData->path)+28]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_midi_channel"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(channel)); +} + +void CarlaEngine::oscSend_control_set_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); + carla_debug("CarlaEngine::oscSend_control_set_parameter_value(%i, %i:%s, %f)", pluginId, index, (index < 0) ? InternalParameterIndex2Str(static_cast(index)) : "(none)", value); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_parameter_value"); + try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), index, value); +} + +void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value); + + char targetPath[std::strlen(pData->oscData->path)+19]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_default_value"); + try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), static_cast(index), value); +} + +void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index); + + char targetPath[std::strlen(pData->oscData->path)+21]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_current_program"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); +} + +void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index); + + char targetPath[std::strlen(pData->oscData->path)+26]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_current_midi_program"); + try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); +} + +void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); + + char targetPath[std::strlen(pData->oscData->path)+18]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_program_name"); + try_lo_send(pData->oscData->target, targetPath, "iis", static_cast(pluginId), static_cast(index), name); +} + +void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(name != nullptr,); + carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); + + char targetPath[std::strlen(pData->oscData->path)+23]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_midi_program_data"); + try_lo_send(pData->oscData->target, targetPath, "iiiis", static_cast(pluginId), static_cast(index), static_cast(bank), static_cast(program), name); +} + +void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,); + carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); + + char targetPath[std::strlen(pData->oscData->path)+9]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/note_on"); + try_lo_send(pData->oscData->target, targetPath, "iiii", static_cast(pluginId), static_cast(channel), static_cast(note), static_cast(velo)); +} + +void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); + CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); + carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note); + + char targetPath[std::strlen(pData->oscData->path)+10]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/note_off"); + try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(channel), static_cast(note)); +} + +void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); + + // TODO - try and see if we can get peaks[4] ref + const EnginePluginData& epData(pData->plugins[pluginId]); + + char targetPath[std::strlen(pData->oscData->path)+11]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/set_peaks"); + try_lo_send(pData->oscData->target, targetPath, "iffff", static_cast(pluginId), epData.insPeak[0], epData.insPeak[1], epData.outsPeak[0], epData.outsPeak[1]); +} + +void CarlaEngine::oscSend_control_exit() const noexcept +{ + CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); + CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); + carla_debug("CarlaEngine::oscSend_control_exit()"); + + char targetPath[std::strlen(pData->oscData->path)+6]; + std::strcpy(targetPath, pData->oscData->path); + std::strcat(targetPath, "/exit"); + try_lo_send(pData->oscData->target, targetPath, ""); +} +#endif + // ----------------------------------------------------------------------- CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngineInternal.cpp b/source/backend/engine/CarlaEngineInternal.cpp new file mode 100644 index 000000000..0e923ec3e --- /dev/null +++ b/source/backend/engine/CarlaEngineInternal.cpp @@ -0,0 +1,893 @@ +/* + * Carla Plugin Host + * Copyright (C) 2011-2014 Filipe Coelho + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * For a full copy of the GNU General Public License see the doc/GPL.txt file. + */ + +#include "CarlaEngineInternal.hpp" +#include "CarlaPlugin.hpp" + +#include "CarlaMIDI.h" + +#ifndef HAVE_JUCE +# include +#else +# include "juce_audio_basics.h" +using juce::FloatVectorOperations; +#endif + +// ----------------------------------------------------------------------- + +CARLA_BACKEND_START_NAMESPACE + +#if 0 +} // Fix editor indentation +#endif + +// ----------------------------------------------------------------------- +// EngineControlEvent + +void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept +{ + switch (type) + { + case kEngineControlEventTypeNull: + break; + + case kEngineControlEventTypeParameter: + if (MIDI_IS_CONTROL_BANK_SELECT(param)) + { + size = 3; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_BANK_SELECT; + data[2] = static_cast(value); + } + else + { + size = 3; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = static_cast(param); + data[2] = uint8_t(value * 127.0f); + } + break; + + case kEngineControlEventTypeMidiBank: + size = 3; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_BANK_SELECT; + data[2] = static_cast(param); + break; + + case kEngineControlEventTypeMidiProgram: + size = 2; + data[0] = static_cast(MIDI_STATUS_PROGRAM_CHANGE + channel); + data[1] = static_cast(param); + break; + + case kEngineControlEventTypeAllSoundOff: + size = 2; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_ALL_SOUND_OFF; + break; + + case kEngineControlEventTypeAllNotesOff: + size = 2; + data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); + data[1] = MIDI_CONTROL_ALL_NOTES_OFF; + break; + } +} + +// ----------------------------------------------------------------------- +// EngineEvent + +void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data) noexcept +{ + // get channel + channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)); + + // get status + const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data))); + + if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) + { + type = kEngineEventTypeControl; + + const uint8_t midiControl(data[1]); + + if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) + { + CARLA_SAFE_ASSERT_INT(size == 3, size); + + const uint8_t midiBank(data[2]); + + ctrl.type = kEngineControlEventTypeMidiBank; + ctrl.param = midiBank; + ctrl.value = 0.0f; + } + else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) + { + CARLA_SAFE_ASSERT_INT(size == 2, size); + + ctrl.type = kEngineControlEventTypeAllSoundOff; + ctrl.param = 0; + ctrl.value = 0.0f; + } + else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) + { + CARLA_SAFE_ASSERT_INT(size == 2, size); + + ctrl.type = kEngineControlEventTypeAllNotesOff; + ctrl.param = 0; + ctrl.value = 0.0f; + } + else + { + CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl); + + const uint8_t midiValue(data[2]); + + ctrl.type = kEngineControlEventTypeParameter; + ctrl.param = midiControl; + ctrl.value = float(midiValue)/127.0f; + } + } + else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) + { + CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]); + + type = kEngineEventTypeControl; + + const uint8_t midiProgram(data[1]); + + ctrl.type = kEngineControlEventTypeMidiProgram; + ctrl.param = midiProgram; + ctrl.value = 0.0f; + } + else + { + type = kEngineEventTypeMidi; + + midi.port = 0; + midi.size = size; + + if (size > EngineMidiEvent::kDataSize) + { + midi.dataExt = data; + std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize); + } + else + { + midi.data[0] = midiStatus; + + uint8_t i=1; + for (; i < midi.size; ++i) + midi.data[i] = data[i]; + for (; i < EngineMidiEvent::kDataSize; ++i) + midi.data[i] = 0; + + midi.dataExt = nullptr; + } + } +} + +// ----------------------------------------------------------------------- +// EngineOptions + +EngineOptions::EngineOptions() noexcept +#ifdef CARLA_OS_LINUX + : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS), + transportMode(ENGINE_TRANSPORT_MODE_JACK), +#else + : processMode(ENGINE_PROCESS_MODE_CONTINUOUS_RACK), + transportMode(ENGINE_TRANSPORT_MODE_INTERNAL), +#endif + forceStereo(false), + preferPluginBridges(false), + preferUiBridges(true), + uisAlwaysOnTop(true), + maxParameters(MAX_DEFAULT_PARAMETERS), + uiBridgesTimeout(4000), + audioNumPeriods(2), + audioBufferSize(512), + audioSampleRate(44100), + audioDevice(nullptr), + binaryDir(nullptr), + resourceDir(nullptr) {} + +EngineOptions::~EngineOptions() +{ + if (audioDevice != nullptr) + { + delete[] audioDevice; + audioDevice = nullptr; + } + + if (binaryDir != nullptr) + { + delete[] binaryDir; + binaryDir = nullptr; + } + + if (resourceDir != nullptr) + { + delete[] resourceDir; + resourceDir = nullptr; + } +} + +// ----------------------------------------------------------------------- +// EngineTimeInfoBBT + +EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept + : bar(0), + beat(0), + tick(0), + barStartTick(0.0), + beatsPerBar(0.0f), + beatType(0.0f), + ticksPerBeat(0.0), + beatsPerMinute(0.0) {} + +// ----------------------------------------------------------------------- +// EngineTimeInfo + +EngineTimeInfo::EngineTimeInfo() noexcept + : playing(false), + frame(0), + usecs(0), + valid(0x0) {} + +void EngineTimeInfo::clear() noexcept +{ + playing = false; + frame = 0; + usecs = 0; + valid = 0x0; +} + +bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept +{ + if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.valid != valid) + return false; + if ((valid & kValidBBT) == 0) + return true; + if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute) + return false; + return true; +} + +bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept +{ + return !operator==(timeInfo); +} + +// ----------------------------------------------------------------------- +// 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 EnginePatchbayBuffers::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); + } +} + +// ----------------------------------------------------------------------- +// 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(); +} + +// ----------------------------------------------------------------------- +// EnginePluginData + +void EnginePluginData::clear() noexcept +{ + plugin = nullptr; + insPeak[0] = insPeak[1] = 0.0f; + outsPeak[0] = outsPeak[1] = 0.0f; +} + +// ----------------------------------------------------------------------- +// CarlaEngineProtectedData + +CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) + : osc(engine), + thread(engine), + oscData(nullptr), + callback(nullptr), + callbackPtr(nullptr), + hints(0x0), + bufferSize(0), + sampleRate(0.0), + aboutToClose(false), + curPluginCount(0), + maxPluginNumber(0), + nextPluginId(0), + plugins(nullptr) {} + +CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept +{ + CARLA_ASSERT(curPluginCount == 0); + CARLA_ASSERT(maxPluginNumber == 0); + CARLA_ASSERT(nextPluginId == 0); + CARLA_ASSERT(plugins == nullptr); +} + +// ----------------------------------------------------------------------- + +void CarlaEngineProtectedData::doPluginRemove() noexcept +{ + CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,); + CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,); + --curPluginCount; + + // move all plugins 1 spot backwards + for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i) + { + CarlaPlugin* const plugin(plugins[i+1].plugin); + + CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); + + plugin->setId(i); + + plugins[i].plugin = plugin; + plugins[i].insPeak[0] = 0.0f; + plugins[i].insPeak[1] = 0.0f; + plugins[i].outsPeak[0] = 0.0f; + plugins[i].outsPeak[1] = 0.0f; + } + + const unsigned int id(curPluginCount); + + // reset last plugin (now removed) + plugins[id].plugin = nullptr; + plugins[id].insPeak[0] = 0.0f; + plugins[id].insPeak[1] = 0.0f; + plugins[id].outsPeak[0] = 0.0f; + plugins[id].outsPeak[1] = 0.0f; +} + +void CarlaEngineProtectedData::doPluginsSwitch() noexcept +{ + CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,); + + const unsigned int idA(nextAction.pluginId); + const unsigned int idB(nextAction.value); + + CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,); + CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,); + CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,); + +#if 0 + std::swap(plugins[idA].plugin, plugins[idB].plugin); +#else + CarlaPlugin* const tmp(plugins[idA].plugin); + + plugins[idA].plugin = plugins[idB].plugin; + plugins[idB].plugin = tmp; +#endif +} + +void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept +{ + switch (nextAction.opcode) + { + case kEnginePostActionNull: + break; + case kEnginePostActionZeroCount: + curPluginCount = 0; + break; + case kEnginePostActionRemovePlugin: + doPluginRemove(); + break; + case kEnginePostActionSwitchPlugins: + doPluginsSwitch(); + break; + } + + nextAction.opcode = kEnginePostActionNull; + nextAction.pluginId = 0; + nextAction.value = 0; + + if (unlock) + nextAction.mutex.unlock(); +} + +// ----------------------------------------------------------------------- + +#ifndef BUILD_BRIDGE +void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline) +{ + CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,); + CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,); + + // safe copy + float inBuf0[frames]; + float inBuf1[frames]; + float* inBuf[2] = { inBuf0, inBuf1 }; + + // initialize audio inputs + FLOAT_COPY(inBuf0, inBufReal[0], frames); + FLOAT_COPY(inBuf1, inBufReal[1], frames); + + // initialize audio outputs (zero) + FLOAT_CLEAR(outBuf[0], frames); + FLOAT_CLEAR(outBuf[1], frames); + + // initialize event outputs (zero) + carla_zeroStruct(bufEvents.out, EngineEvent::kMaxInternalCount); + + bool processed = false; + + uint32_t oldAudioInCount = 0; + uint32_t oldMidiOutCount = 0; + + // process plugins + for (unsigned int i=0; i < curPluginCount; ++i) + { + CarlaPlugin* const plugin = plugins[i].plugin; + + if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline)) + continue; + + if (processed) + { + // initialize audio inputs (from previous outputs) + FLOAT_COPY(inBuf0, outBuf[0], frames); + FLOAT_COPY(inBuf1, outBuf[1], frames); + + // initialize audio outputs (zero) + FLOAT_CLEAR(outBuf[0], frames); + FLOAT_CLEAR(outBuf[1], frames); + + // if plugin has no midi out, add previous events + if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull) + { + if (bufEvents.out[0].type != kEngineEventTypeNull) + { + // TODO: carefully add to input, sorted events + } + // else nothing needed + } + else + { + // initialize event inputs from previous outputs + carla_copyStruct(bufEvents.in, bufEvents.out, EngineEvent::kMaxInternalCount); + + // initialize event outputs (zero) + carla_zeroStruct(bufEvents.out, EngineEvent::kMaxInternalCount); + } + } + + oldAudioInCount = plugin->getAudioInCount(); + oldMidiOutCount = plugin->getMidiOutCount(); + + // process + plugin->initBuffers(); + plugin->process(inBuf, outBuf, frames); + plugin->unlock(); + + // if plugin has no audio inputs, add input buffer + if (oldAudioInCount == 0) + { + FLOAT_ADD(outBuf[0], inBuf0, frames); + FLOAT_ADD(outBuf[1], inBuf1, frames); + } + + // set peaks + { + EnginePluginData& pluginData(plugins[i]); + +#ifdef HAVE_JUCE + float tmpMin, tmpMax; + + if (oldAudioInCount > 0) + { + FloatVectorOperations::findMinAndMax(inBuf0, frames, tmpMin, tmpMax); + pluginData.insPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + + FloatVectorOperations::findMinAndMax(inBuf1, frames, tmpMin, tmpMax); + pluginData.insPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + } + else + { + pluginData.insPeak[0] = 0.0f; + pluginData.insPeak[1] = 0.0f; + } + + if (plugin->getAudioOutCount() > 0) + { + FloatVectorOperations::findMinAndMax(outBuf[0], frames, tmpMin, tmpMax); + pluginData.outsPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + + FloatVectorOperations::findMinAndMax(outBuf[1], frames, tmpMin, tmpMax); + pluginData.outsPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); + } + else + { + pluginData.outsPeak[0] = 0.0f; + pluginData.outsPeak[1] = 0.0f; + } +#else + float peak1, peak2; + + if (oldAudioInCount > 0) + { + peak1 = peak2 = 0.0f; + + for (uint32_t k=0; k < frames; ++k) + { + peak1 = carla_max(peak1, std::fabs(inBuf0[k]), 1.0f); + peak2 = carla_max(peak2, std::fabs(inBuf1[k]), 1.0f); + } + + pluginData.insPeak[0] = peak1; + pluginData.insPeak[1] = peak2; + } + else + { + pluginData.insPeak[0] = 0.0f; + pluginData.insPeak[1] = 0.0f; + } + + if (plugin->getAudioOutCount() > 0) + { + peak1 = peak2 = 0.0f; + + for (uint32_t k=0; k < frames; ++k) + { + peak1 = carla_max(peak1, std::fabs(outBuf[0][k]), 1.0f); + peak2 = carla_max(peak2, std::fabs(outBuf[1][k]), 1.0f); + } + + pluginData.outsPeak[0] = peak1; + pluginData.outsPeak[1] = peak2; + } + else + { + pluginData.outsPeak[0] = 0.0f; + pluginData.outsPeak[1] = 0.0f; + } +#endif + } + + processed = true; + } +} + +void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) +{ + EngineRackBuffers* const rack(bufAudio.rack); + + const CarlaMutex::ScopedLocker sl(rack->connectLock); + + // connect input buffers + if (rack->connectedIns[0].count() == 0) + { + FLOAT_CLEAR(rack->in[0], nframes); + } + else + { + bool first = true; + + for (LinkedList::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < inCount); + + if (first) + { + FLOAT_COPY(rack->in[0], inBuf[port], nframes); + first = false; + } + else + { + FLOAT_ADD(rack->in[0], inBuf[port], nframes); + } + } + + if (first) + FLOAT_CLEAR(rack->in[0], nframes); + } + + if (rack->connectedIns[1].count() == 0) + { + FLOAT_CLEAR(rack->in[1], nframes); + } + else + { + bool first = true; + + for (LinkedList::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < inCount); + + if (first) + { + FLOAT_COPY(rack->in[1], inBuf[port], nframes); + first = false; + } + else + { + FLOAT_ADD(rack->in[1], inBuf[port], nframes); + } + } + + if (first) + FLOAT_CLEAR(rack->in[1], nframes); + } + + FLOAT_CLEAR(rack->out[0], nframes); + FLOAT_CLEAR(rack->out[1], nframes); + + // process + processRack(rack->in, rack->out, nframes, isOffline); + + // connect output buffers + if (rack->connectedOuts[0].count() != 0) + { + for (LinkedList::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < outCount); + + FLOAT_ADD(outBuf[port], rack->out[0], nframes); + } + } + + if (rack->connectedOuts[1].count() != 0) + { + for (LinkedList::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next()) + { + const uint& port(it.getValue()); + CARLA_SAFE_ASSERT_CONTINUE(port < outCount); + + FLOAT_ADD(outBuf[port], rack->out[1], nframes); + } + } +} +#endif + +// ----------------------------------------------------------------------- +// 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 diff --git a/source/backend/engine/CarlaEngineInternal.hpp b/source/backend/engine/CarlaEngineInternal.hpp index c49672e95..7fe54d3fe 100644 --- a/source/backend/engine/CarlaEngineInternal.hpp +++ b/source/backend/engine/CarlaEngineInternal.hpp @@ -52,6 +52,7 @@ CARLA_BACKEND_START_NAMESPACE #endif // ----------------------------------------------------------------------- +// Rack Patchbay stuff enum RackPatchbayGroupIds { RACK_PATCHBAY_GROUP_CARLA = -1, @@ -84,9 +85,39 @@ struct ConnectionToId { }; // ----------------------------------------------------------------------- +// EngineRackBuffers -struct EngineRackBuffers; -struct EnginePatchbayBuffers; +struct EngineRackBuffers { + float* in[2]; + float* out[2]; + + // connections stuff + LinkedList connectedIns[2]; + LinkedList connectedOuts[2]; + CarlaMutex connectLock; + + int lastConnectionId; + LinkedList usedConnections; + + EngineRackBuffers(const uint32_t bufferSize); + ~EngineRackBuffers(); + void clear(); + void resize(const uint32_t bufferSize); +}; + +// ----------------------------------------------------------------------- +// EnginePatchbayBuffers + +struct EnginePatchbayBuffers { + // TODO + EnginePatchbayBuffers(const uint32_t bufferSize); + ~EnginePatchbayBuffers(); + void clear(); + void resize(const uint32_t bufferSize); +}; + +// ----------------------------------------------------------------------- +// InternalAudio struct InternalAudio { bool isReady; @@ -109,6 +140,7 @@ struct InternalAudio { }; // ----------------------------------------------------------------------- +// InternalEvents struct InternalEvents { EngineEvent* in; @@ -120,6 +152,7 @@ struct InternalEvents { }; // ----------------------------------------------------------------------- +// InternalTime struct InternalTime { bool playing; @@ -129,6 +162,7 @@ struct InternalTime { }; // ----------------------------------------------------------------------- +// NextAction enum EnginePostAction { kEnginePostActionNull, @@ -149,6 +183,7 @@ struct NextAction { }; // ----------------------------------------------------------------------- +// EnginePluginData struct EnginePluginData { CarlaPlugin* plugin; @@ -159,6 +194,7 @@ struct EnginePluginData { }; // ----------------------------------------------------------------------- +// CarlaEngineProtectedData struct CarlaEngineProtectedData { CarlaEngineOsc osc; diff --git a/source/backend/engine/CarlaEngineThread.cpp b/source/backend/engine/CarlaEngineThread.cpp index 412f23bff..43e9b7945 100644 --- a/source/backend/engine/CarlaEngineThread.cpp +++ b/source/backend/engine/CarlaEngineThread.cpp @@ -15,9 +15,8 @@ * For a full copy of the GNU General Public License see the doc/GPL.txt file. */ -#include "CarlaEngineThread.hpp" - #include "CarlaEngine.hpp" +#include "CarlaEngineThread.hpp" #include "CarlaPlugin.hpp" CARLA_BACKEND_START_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_data.cpp b/source/backend/engine/CarlaEngine_data.cpp deleted file mode 100644 index d45485822..000000000 --- a/source/backend/engine/CarlaEngine_data.cpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "CarlaEngine.hpp" -#include "CarlaMIDI.h" - -#include "CarlaUtils.hpp" - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_START_NAMESPACE - -#if 0 -} // Fix editor indentation -#endif - -// ----------------------------------------------------------------------- -// EngineControlEvent - -void EngineControlEvent::dumpToMidiData(const uint8_t channel, uint8_t& size, uint8_t data[3]) const noexcept -{ - switch (type) - { - case kEngineControlEventTypeNull: - break; - - case kEngineControlEventTypeParameter: - if (MIDI_IS_CONTROL_BANK_SELECT(param)) - { - size = 3; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_BANK_SELECT; - data[2] = static_cast(value); - } - else - { - size = 3; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = static_cast(param); - data[2] = uint8_t(value * 127.0f); - } - break; - - case kEngineControlEventTypeMidiBank: - size = 3; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_BANK_SELECT; - data[2] = static_cast(param); - break; - - case kEngineControlEventTypeMidiProgram: - size = 2; - data[0] = static_cast(MIDI_STATUS_PROGRAM_CHANGE + channel); - data[1] = static_cast(param); - break; - - case kEngineControlEventTypeAllSoundOff: - size = 2; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_ALL_SOUND_OFF; - break; - - case kEngineControlEventTypeAllNotesOff: - size = 2; - data[0] = static_cast(MIDI_STATUS_CONTROL_CHANGE + channel); - data[1] = MIDI_CONTROL_ALL_NOTES_OFF; - break; - } -} - -// ----------------------------------------------------------------------- -// EngineEvent - -void EngineEvent::fillFromMidiData(const uint8_t size, const uint8_t* const data) noexcept -{ - // get channel - channel = uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)); - - // get status - const uint8_t midiStatus(uint8_t(MIDI_GET_STATUS_FROM_DATA(data))); - - if (midiStatus == MIDI_STATUS_CONTROL_CHANGE) - { - type = kEngineEventTypeControl; - - const uint8_t midiControl(data[1]); - - if (MIDI_IS_CONTROL_BANK_SELECT(midiControl)) - { - CARLA_SAFE_ASSERT_INT(size == 3, size); - - const uint8_t midiBank(data[2]); - - ctrl.type = kEngineControlEventTypeMidiBank; - ctrl.param = midiBank; - ctrl.value = 0.0f; - } - else if (midiControl == MIDI_CONTROL_ALL_SOUND_OFF) - { - CARLA_SAFE_ASSERT_INT(size == 2, size); - - ctrl.type = kEngineControlEventTypeAllSoundOff; - ctrl.param = 0; - ctrl.value = 0.0f; - } - else if (midiControl == MIDI_CONTROL_ALL_NOTES_OFF) - { - CARLA_SAFE_ASSERT_INT(size == 2, size); - - ctrl.type = kEngineControlEventTypeAllNotesOff; - ctrl.param = 0; - ctrl.value = 0.0f; - } - else - { - CARLA_SAFE_ASSERT_INT2(size == 3, size, midiControl); - - const uint8_t midiValue(data[2]); - - ctrl.type = kEngineControlEventTypeParameter; - ctrl.param = midiControl; - ctrl.value = float(midiValue)/127.0f; - } - } - else if (midiStatus == MIDI_STATUS_PROGRAM_CHANGE) - { - CARLA_SAFE_ASSERT_INT2(size == 2, size, data[1]); - - type = kEngineEventTypeControl; - - const uint8_t midiProgram(data[1]); - - ctrl.type = kEngineControlEventTypeMidiProgram; - ctrl.param = midiProgram; - ctrl.value = 0.0f; - } - else - { - type = kEngineEventTypeMidi; - - midi.port = 0; - midi.size = size; - - if (size > EngineMidiEvent::kDataSize) - { - midi.dataExt = data; - std::memset(midi.data, 0, sizeof(uint8_t)*EngineMidiEvent::kDataSize); - } - else - { - midi.data[0] = midiStatus; - - uint8_t i=1; - for (; i < midi.size; ++i) - midi.data[i] = data[i]; - for (; i < EngineMidiEvent::kDataSize; ++i) - midi.data[i] = 0; - - midi.dataExt = nullptr; - } - } -} - -// ----------------------------------------------------------------------- -// EngineOptions - -EngineOptions::EngineOptions() noexcept -#ifdef CARLA_OS_LINUX - : processMode(ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS), - transportMode(ENGINE_TRANSPORT_MODE_JACK), -#else - : processMode(ENGINE_PROCESS_MODE_CONTINUOUS_RACK), - transportMode(ENGINE_TRANSPORT_MODE_INTERNAL), -#endif - forceStereo(false), - preferPluginBridges(false), - preferUiBridges(true), - uisAlwaysOnTop(true), - maxParameters(MAX_DEFAULT_PARAMETERS), - uiBridgesTimeout(4000), - audioNumPeriods(2), - audioBufferSize(512), - audioSampleRate(44100), - audioDevice(nullptr), - binaryDir(nullptr), - resourceDir(nullptr) {} - -EngineOptions::~EngineOptions() -{ - if (audioDevice != nullptr) - { - delete[] audioDevice; - audioDevice = nullptr; - } - - if (binaryDir != nullptr) - { - delete[] binaryDir; - binaryDir = nullptr; - } - - if (resourceDir != nullptr) - { - delete[] resourceDir; - resourceDir = nullptr; - } -} - -// ----------------------------------------------------------------------- -// EngineTimeInfoBBT - -EngineTimeInfoBBT::EngineTimeInfoBBT() noexcept - : bar(0), - beat(0), - tick(0), - barStartTick(0.0), - beatsPerBar(0.0f), - beatType(0.0f), - ticksPerBeat(0.0), - beatsPerMinute(0.0) {} - -// ----------------------------------------------------------------------- -// EngineTimeInfo - -EngineTimeInfo::EngineTimeInfo() noexcept - : playing(false), - frame(0), - usecs(0), - valid(0x0) {} - -void EngineTimeInfo::clear() noexcept -{ - playing = false; - frame = 0; - usecs = 0; - valid = 0x0; -} - -bool EngineTimeInfo::operator==(const EngineTimeInfo& timeInfo) const noexcept -{ - if (timeInfo.playing != playing || timeInfo.frame != frame || timeInfo.valid != valid) - return false; - if ((valid & kValidBBT) == 0) - return true; - if (timeInfo.bbt.beatsPerMinute != bbt.beatsPerMinute) - return false; - return true; -} - -bool EngineTimeInfo::operator!=(const EngineTimeInfo& timeInfo) const noexcept -{ - return !operator==(timeInfo); -} - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_internal.cpp b/source/backend/engine/CarlaEngine_internal.cpp deleted file mode 100644 index 68a7619be..000000000 --- a/source/backend/engine/CarlaEngine_internal.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "CarlaEngineInternal.hpp" -#include "CarlaPlugin.hpp" - -#ifndef HAVE_JUCE -# include -#else -# include "juce_audio_basics.h" -using juce::FloatVectorOperations; -#endif - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_START_NAMESPACE - -#if 0 -} // Fix editor indentation -#endif - -// ----------------------------------------------------------------------- -// InternalEvents - -InternalEvents::InternalEvents() noexcept - : in(nullptr), - out(nullptr) {} - -InternalEvents::~InternalEvents() noexcept -{ - CARLA_ASSERT(in == nullptr); - CARLA_ASSERT(out == nullptr); -} - -// ----------------------------------------------------------------------- -// InternalTime - -InternalTime::InternalTime() noexcept - : playing(false), - frame(0) {} - -// ----------------------------------------------------------------------- -// NextAction - -NextAction::NextAction() noexcept - : opcode(kEnginePostActionNull), - pluginId(0), - value(0) {} - -NextAction::~NextAction() noexcept -{ - CARLA_ASSERT(opcode == kEnginePostActionNull); -} - -void NextAction::ready() noexcept -{ - mutex.lock(); - mutex.unlock(); -} - -// ----------------------------------------------------------------------- - -void EnginePluginData::clear() noexcept -{ - plugin = nullptr; - insPeak[0] = insPeak[1] = 0.0f; - outsPeak[0] = outsPeak[1] = 0.0f; -} - -// ----------------------------------------------------------------------- - -CarlaEngineProtectedData::CarlaEngineProtectedData(CarlaEngine* const engine) - : osc(engine), - thread(engine), - oscData(nullptr), - callback(nullptr), - callbackPtr(nullptr), - hints(0x0), - bufferSize(0), - sampleRate(0.0), - aboutToClose(false), - curPluginCount(0), - maxPluginNumber(0), - nextPluginId(0), - plugins(nullptr) {} - -CarlaEngineProtectedData::~CarlaEngineProtectedData() noexcept -{ - CARLA_ASSERT(curPluginCount == 0); - CARLA_ASSERT(maxPluginNumber == 0); - CARLA_ASSERT(nextPluginId == 0); - CARLA_ASSERT(plugins == nullptr); -} - -// ----------------------------------------------------------------------- - -void CarlaEngineProtectedData::doPluginRemove() noexcept -{ - CARLA_SAFE_ASSERT_RETURN(curPluginCount > 0,); - CARLA_SAFE_ASSERT_RETURN(nextAction.pluginId < curPluginCount,); - --curPluginCount; - - // move all plugins 1 spot backwards - for (unsigned int i=nextAction.pluginId; i < curPluginCount; ++i) - { - CarlaPlugin* const plugin(plugins[i+1].plugin); - - CARLA_SAFE_ASSERT_BREAK(plugin != nullptr); - - plugin->setId(i); - - plugins[i].plugin = plugin; - plugins[i].insPeak[0] = 0.0f; - plugins[i].insPeak[1] = 0.0f; - plugins[i].outsPeak[0] = 0.0f; - plugins[i].outsPeak[1] = 0.0f; - } - - const unsigned int id(curPluginCount); - - // reset last plugin (now removed) - plugins[id].plugin = nullptr; - plugins[id].insPeak[0] = 0.0f; - plugins[id].insPeak[1] = 0.0f; - plugins[id].outsPeak[0] = 0.0f; - plugins[id].outsPeak[1] = 0.0f; -} - -void CarlaEngineProtectedData::doPluginsSwitch() noexcept -{ - CARLA_SAFE_ASSERT_RETURN(curPluginCount >= 2,); - - const unsigned int idA(nextAction.pluginId); - const unsigned int idB(nextAction.value); - - CARLA_SAFE_ASSERT_RETURN(idA < curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(idB < curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(plugins[idA].plugin != nullptr,); - CARLA_SAFE_ASSERT_RETURN(plugins[idB].plugin != nullptr,); - -#if 0 - std::swap(plugins[idA].plugin, plugins[idB].plugin); -#else - CarlaPlugin* const tmp(plugins[idA].plugin); - - plugins[idA].plugin = plugins[idB].plugin; - plugins[idB].plugin = tmp; -#endif -} - -void CarlaEngineProtectedData::doNextPluginAction(const bool unlock) noexcept -{ - switch (nextAction.opcode) - { - case kEnginePostActionNull: - break; - case kEnginePostActionZeroCount: - curPluginCount = 0; - break; - case kEnginePostActionRemovePlugin: - doPluginRemove(); - break; - case kEnginePostActionSwitchPlugins: - doPluginsSwitch(); - break; - } - - nextAction.opcode = kEnginePostActionNull; - nextAction.pluginId = 0; - nextAction.value = 0; - - if (unlock) - nextAction.mutex.unlock(); -} - -#ifndef BUILD_BRIDGE -void CarlaEngineProtectedData::processRack(float* inBufReal[2], float* outBuf[2], const uint32_t frames, const bool isOffline) -{ - CARLA_SAFE_ASSERT_RETURN(bufEvents.in != nullptr,); - CARLA_SAFE_ASSERT_RETURN(bufEvents.out != nullptr,); - - // safe copy - float inBuf0[frames]; - float inBuf1[frames]; - float* inBuf[2] = { inBuf0, inBuf1 }; - - // initialize audio inputs - FLOAT_COPY(inBuf0, inBufReal[0], frames); - FLOAT_COPY(inBuf1, inBufReal[1], frames); - - // initialize audio outputs (zero) - FLOAT_CLEAR(outBuf[0], frames); - FLOAT_CLEAR(outBuf[1], frames); - - // initialize event outputs (zero) - carla_zeroStruct(bufEvents.out, EngineEvent::kMaxInternalCount); - - bool processed = false; - - uint32_t oldAudioInCount = 0; - uint32_t oldMidiOutCount = 0; - - // process plugins - for (unsigned int i=0; i < curPluginCount; ++i) - { - CarlaPlugin* const plugin = plugins[i].plugin; - - if (plugin == nullptr || ! plugin->isEnabled() || ! plugin->tryLock(isOffline)) - continue; - - if (processed) - { - // initialize audio inputs (from previous outputs) - FLOAT_COPY(inBuf0, outBuf[0], frames); - FLOAT_COPY(inBuf1, outBuf[1], frames); - - // initialize audio outputs (zero) - FLOAT_CLEAR(outBuf[0], frames); - FLOAT_CLEAR(outBuf[1], frames); - - // if plugin has no midi out, add previous events - if (oldMidiOutCount == 0 && bufEvents.in[0].type != kEngineEventTypeNull) - { - if (bufEvents.out[0].type != kEngineEventTypeNull) - { - // TODO: carefully add to input, sorted events - } - // else nothing needed - } - else - { - // initialize event inputs from previous outputs - carla_copyStruct(bufEvents.in, bufEvents.out, EngineEvent::kMaxInternalCount); - - // initialize event outputs (zero) - carla_zeroStruct(bufEvents.out, EngineEvent::kMaxInternalCount); - } - } - - oldAudioInCount = plugin->getAudioInCount(); - oldMidiOutCount = plugin->getMidiOutCount(); - - // process - plugin->initBuffers(); - plugin->process(inBuf, outBuf, frames); - plugin->unlock(); - - // if plugin has no audio inputs, add input buffer - if (oldAudioInCount == 0) - { - FLOAT_ADD(outBuf[0], inBuf0, frames); - FLOAT_ADD(outBuf[1], inBuf1, frames); - } - - // set peaks - { - EnginePluginData& pluginData(plugins[i]); - -#ifdef HAVE_JUCE - float tmpMin, tmpMax; - - if (oldAudioInCount > 0) - { - FloatVectorOperations::findMinAndMax(inBuf0, frames, tmpMin, tmpMax); - pluginData.insPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - - FloatVectorOperations::findMinAndMax(inBuf1, frames, tmpMin, tmpMax); - pluginData.insPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - } - else - { - pluginData.insPeak[0] = 0.0f; - pluginData.insPeak[1] = 0.0f; - } - - if (plugin->getAudioOutCount() > 0) - { - FloatVectorOperations::findMinAndMax(outBuf[0], frames, tmpMin, tmpMax); - pluginData.outsPeak[0] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - - FloatVectorOperations::findMinAndMax(outBuf[1], frames, tmpMin, tmpMax); - pluginData.outsPeak[1] = carla_max(std::abs(tmpMin), std::abs(tmpMax), 1.0f); - } - else - { - pluginData.outsPeak[0] = 0.0f; - pluginData.outsPeak[1] = 0.0f; - } -#else - float peak1, peak2; - - if (oldAudioInCount > 0) - { - peak1 = peak2 = 0.0f; - - for (uint32_t k=0; k < frames; ++k) - { - peak1 = carla_max(peak1, std::fabs(inBuf0[k]), 1.0f); - peak2 = carla_max(peak2, std::fabs(inBuf1[k]), 1.0f); - } - - pluginData.insPeak[0] = peak1; - pluginData.insPeak[1] = peak2; - } - else - { - pluginData.insPeak[0] = 0.0f; - pluginData.insPeak[1] = 0.0f; - } - - if (plugin->getAudioOutCount() > 0) - { - peak1 = peak2 = 0.0f; - - for (uint32_t k=0; k < frames; ++k) - { - peak1 = carla_max(peak1, std::fabs(outBuf[0][k]), 1.0f); - peak2 = carla_max(peak2, std::fabs(outBuf[1][k]), 1.0f); - } - - pluginData.outsPeak[0] = peak1; - pluginData.outsPeak[1] = peak2; - } - else - { - pluginData.outsPeak[0] = 0.0f; - pluginData.outsPeak[1] = 0.0f; - } -#endif - } - - processed = true; - } -} -#endif - -// ----------------------------------------------------------------------- - -CarlaEngineProtectedData::ScopedActionLock::ScopedActionLock(CarlaEngineProtectedData* const data, const EnginePostAction action, const unsigned int pluginId, const unsigned int value, const bool lockWait) noexcept - : fData(data) -{ - fData->nextAction.mutex.lock(); - - CARLA_SAFE_ASSERT_RETURN(fData->nextAction.opcode == kEnginePostActionNull,); - - fData->nextAction.opcode = action; - fData->nextAction.pluginId = pluginId; - fData->nextAction.value = value; - - if (lockWait) - { - // block wait for unlock on processing side - carla_stdout("ScopedPluginAction(%i) - blocking START", pluginId); - fData->nextAction.mutex.lock(); - carla_stdout("ScopedPluginAction(%i) - blocking DONE", pluginId); - } - else - { - fData->doNextPluginAction(false); - } -} - -CarlaEngineProtectedData::ScopedActionLock::~ScopedActionLock() noexcept -{ - fData->nextAction.mutex.unlock(); -} - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_osc.cpp b/source/backend/engine/CarlaEngine_osc.cpp deleted file mode 100644 index 0028a371e..000000000 --- a/source/backend/engine/CarlaEngine_osc.cpp +++ /dev/null @@ -1,738 +0,0 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "CarlaEngineInternal.hpp" -#include "CarlaMIDI.h" - -#include "CarlaUtils.hpp" - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_START_NAMESPACE - -#if 0 -} // Fix editor indentation -#endif - -// ----------------------------------------------------------------------- -// OSC Stuff - -#ifdef BUILD_BRIDGE -bool CarlaEngine::isOscBridgeRegistered() const noexcept -{ - return (pData->oscData != nullptr); -} -#else -bool CarlaEngine::isOscControlRegistered() const noexcept -{ - return pData->osc.isControlRegistered(); -} -#endif - -void CarlaEngine::idleOsc() const noexcept -{ - try { - pData->osc.idle(); - } catch(...) {} -} - -const char* CarlaEngine::getOscServerPathTCP() const noexcept -{ - return pData->osc.getServerPathTCP(); -} - -const char* CarlaEngine::getOscServerPathUDP() const noexcept -{ - return pData->osc.getServerPathUDP(); -} - -#ifdef BUILD_BRIDGE -void CarlaEngine::setOscBridgeData(const CarlaOscData* const oscData) const noexcept -{ - pData->oscData = oscData; -} -#endif - -// ----------------------------------------------------------------------- -// Bridge/Controller OSC stuff - -#ifdef BUILD_BRIDGE -void CarlaEngine::oscSend_bridge_plugin_info1(const PluginCategory category, const uint hints, const long uniqueId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_plugin_info1(%i:%s, %X, %l)", category, PluginCategory2Str(category), hints, uniqueId); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_plugin_info1"); - try_lo_send(pData->oscData->target, targetPath, "iih", static_cast(category), static_cast(hints), static_cast(uniqueId)); -} - -void CarlaEngine::oscSend_bridge_plugin_info2(const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); - CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_plugin_info2(\"%s\", \"%s\", \"%s\", \"%s\")", realName, label, maker, copyright); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_plugin_info2"); - try_lo_send(pData->oscData->target, targetPath, "ssss", realName, label, maker, copyright); -} - -void CarlaEngine::oscSend_bridge_audio_count(const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_audio_count(%i, %i)", ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_audio_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_bridge_midi_count(const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_midi_count(%i, %i)", ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_midi_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_bridge_parameter_count(const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_count(%i, %i)", ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_bridge_program_count(const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_program_count(%i)", count); - - char targetPath[std::strlen(pData->oscData->path)+22]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_program_count"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); -} - -void CarlaEngine::oscSend_bridge_midi_program_count(const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_midi_program_count(%i)", count); - - char targetPath[std::strlen(pData->oscData->path)+27]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_midi_program_count"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(count)); -} - -void CarlaEngine::oscSend_bridge_parameter_data(const uint32_t index, const int32_t rindex, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", index, rindex, type, ParameterType2Str(type), hints, name, unit); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(index), static_cast(rindex), static_cast(type), static_cast(hints), name, unit); -} - -void CarlaEngine::oscSend_bridge_parameter_ranges1(const uint32_t index, const float def, const float min, const float max) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, def, min, max); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_ranges1"); - try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), def, min, max); -} - -void CarlaEngine::oscSend_bridge_parameter_ranges2(const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_ranges(%i, %f, %f, %f)", index, step, stepSmall, stepLarge); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_ranges2"); - try_lo_send(pData->oscData->target, targetPath, "ifff", static_cast(index), step, stepSmall, stepLarge); -} - -void CarlaEngine::oscSend_bridge_parameter_midi_cc(const uint32_t index, const int16_t cc) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_cc(%i, %i)", index, cc); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_midi_cc"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(cc)); -} - -void CarlaEngine::oscSend_bridge_parameter_midi_channel(const uint32_t index, const uint8_t channel) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_midi_channel(%i, %i)", index, channel); - - char targetPath[std::strlen(pData->oscData->path)+31]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_midi_channel"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(index), static_cast(channel)); -} - -void CarlaEngine::oscSend_bridge_parameter_value(const int32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); - carla_debug("CarlaEngine::oscSend_bridge_parameter_value(%i, %f)", index, value); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_parameter_value"); - try_lo_send(pData->oscData->target, targetPath, "if", index, value); -} - -void CarlaEngine::oscSend_bridge_default_value(const uint32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_default_value(%i, %f)", index, value); - - char targetPath[std::strlen(pData->oscData->path)+22]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_default_value"); - try_lo_send(pData->oscData->target, targetPath, "if", static_cast(index), value); -} - -void CarlaEngine::oscSend_bridge_current_program(const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_current_program(%i)", index); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_current_program"); - try_lo_send(pData->oscData->target, targetPath, "i", index); -} - -void CarlaEngine::oscSend_bridge_current_midi_program(const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_current_midi_program(%i)", index); - - char targetPath[std::strlen(pData->oscData->path)+25]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_current_midi_program"); - try_lo_send(pData->oscData->target, targetPath, "i", index); -} - -void CarlaEngine::oscSend_bridge_program_name(const uint32_t index, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_program_name(%i, \"%s\")", index, name); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_program_name"); - try_lo_send(pData->oscData->target, targetPath, "is", static_cast(index), name); -} - -void CarlaEngine::oscSend_bridge_midi_program_data(const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_midi_program_data(%i, %i, %i, \"%s\")", index, bank, program, name); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_midi_program_data"); - try_lo_send(pData->oscData->target, targetPath, "iiis", static_cast(index), static_cast(bank), static_cast(program), name); -} - -void CarlaEngine::oscSend_bridge_configure(const char* const key, const char* const value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(value != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_configure(\"%s\", \"%s\")", key, value); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_configure"); - try_lo_send(pData->oscData->target, targetPath, "ss", key, value); -} - -void CarlaEngine::oscSend_bridge_set_custom_data(const char* const type, const char* const key, const char* const value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_bridge_set_custom_data(\"%s\", \"%s\", \"%s\")", type, key, value); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_set_custom_data"); - try_lo_send(pData->oscData->target, targetPath, "sss", type, key, value); -} - -void CarlaEngine::oscSend_bridge_set_chunk_data(const char* const chunkFile) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(chunkFile != nullptr && chunkFile[0] != '\0',); - carla_debug("CarlaEngine::oscSend_bridge_set_chunk_data(\"%s\")", chunkFile); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/bridge_set_chunk_data"); - try_lo_send(pData->oscData->target, targetPath, "s", chunkFile); -} - -// TODO? -//void oscSend_bridge_set_peaks() const; - -#else -void CarlaEngine::oscSend_control_add_plugin_start(const uint pluginId, const char* const pluginName) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(pluginName != nullptr && pluginName[0] != '\0',); - carla_debug("CarlaEngine::oscSend_control_add_plugin_start(%i, \"%s\")", pluginId, pluginName); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/add_plugin_start"); - try_lo_send(pData->oscData->target, targetPath, "is", static_cast(pluginId), pluginName); -} - -void CarlaEngine::oscSend_control_add_plugin_end(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_add_plugin_end(%i)", pluginId); - - char targetPath[std::strlen(pData->oscData->path)+16]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/add_plugin_end"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); -} - -void CarlaEngine::oscSend_control_remove_plugin(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_remove_plugin(%i)", pluginId); - - char targetPath[std::strlen(pData->oscData->path)+15]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/remove_plugin"); - try_lo_send(pData->oscData->target, targetPath, "i", static_cast(pluginId)); -} - -void CarlaEngine::oscSend_control_set_plugin_info1(const uint pluginId, const PluginType type, const PluginCategory category, const uint hints, const long uniqueId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(type != PLUGIN_NONE,); - carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, %i:%s, %i:%s, %X, %l)", pluginId, type, PluginType2Str(type), category, PluginCategory2Str(category), hints, uniqueId); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_plugin_info1"); - try_lo_send(pData->oscData->target, targetPath, "iiiih", static_cast(pluginId), static_cast(type), static_cast(category), static_cast(hints), static_cast(uniqueId)); -} - -void CarlaEngine::oscSend_control_set_plugin_info2(const uint pluginId, const char* const realName, const char* const label, const char* const maker, const char* const copyright) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(realName != nullptr && realName[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(label != nullptr && label[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(maker != nullptr,); - CARLA_SAFE_ASSERT_RETURN(copyright != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_plugin_data(%i, \"%s\", \"%s\", \"%s\", \"%s\")", pluginId, realName, label, maker, copyright); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_plugin_info2"); - try_lo_send(pData->oscData->target, targetPath, "issss", static_cast(pluginId), realName, label, maker, copyright); -} - -void CarlaEngine::oscSend_control_set_audio_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_audio_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_audio_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_midi_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_midi_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_parameter_count(const uint pluginId, const uint32_t ins, const uint32_t outs) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_count(%i, %i, %i)", pluginId, ins, outs); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_count"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(ins), static_cast(outs)); -} - -void CarlaEngine::oscSend_control_set_program_count(const uint pluginId, const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_program_count(%i, %i)", pluginId, count); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_program_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); -} - -void CarlaEngine::oscSend_control_set_midi_program_count(const uint pluginId, const uint32_t count) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_midi_program_count(%i, %i)", pluginId, count); - - char targetPath[std::strlen(pData->oscData->path)+24]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_program_count"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), static_cast(count)); -} - -void CarlaEngine::oscSend_control_set_parameter_data(const uint pluginId, const uint32_t index, const ParameterType type, const uint hints, const char* const name, const char* const unit) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(unit != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_data(%i, %i, %i:%s, %X, \"%s\", \"%s\")", pluginId, index, type, ParameterType2Str(type), hints, name, unit); - - char targetPath[std::strlen(pData->oscData->path)+20]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiiss", static_cast(pluginId), static_cast(index), static_cast(type), static_cast(hints), name, unit); -} - -void CarlaEngine::oscSend_control_set_parameter_ranges1(const uint pluginId, const uint32_t index, const float def, const float min, const float max) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(def <= min && def >= max,); - CARLA_SAFE_ASSERT_RETURN(min < max,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges1(%i, %i, %f, %f, %f)", pluginId, index, def, min, max, def); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_ranges1"); - try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), def, min, max); -} - -void CarlaEngine::oscSend_control_set_parameter_ranges2(const uint pluginId, const uint32_t index, const float step, const float stepSmall, const float stepLarge) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(step <= stepSmall && step >= stepLarge,); - CARLA_SAFE_ASSERT_RETURN(stepSmall <= stepLarge,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_ranges2(%i, %i, %f, %f, %f)", pluginId, index, step, stepSmall, stepLarge); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_ranges"); - try_lo_send(pData->oscData->target, targetPath, "iifff", static_cast(pluginId), static_cast(index), step, stepSmall, stepLarge); -} - -void CarlaEngine::oscSend_control_set_parameter_midi_cc(const uint pluginId, const uint32_t index, const int16_t cc) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(cc <= 0x5F,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_cc(%i, %i, %i)", pluginId, index, cc); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_midi_cc"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(cc)); -} - -void CarlaEngine::oscSend_control_set_parameter_midi_channel(const uint pluginId, const uint32_t index, const uint8_t channel) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_midi_channel(%i, %i, %i)", pluginId, index, channel); - - char targetPath[std::strlen(pData->oscData->path)+28]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_midi_channel"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(index), static_cast(channel)); -} - -void CarlaEngine::oscSend_control_set_parameter_value(const uint pluginId, const int32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(index != PARAMETER_NULL,); - carla_debug("CarlaEngine::oscSend_control_set_parameter_value(%i, %i:%s, %f)", pluginId, index, (index < 0) ? InternalParameterIndex2Str(static_cast(index)) : "(none)", value); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_parameter_value"); - try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), index, value); -} - -void CarlaEngine::oscSend_control_set_default_value(const uint pluginId, const uint32_t index, const float value) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_default_value(%i, %i, %f)", pluginId, index, value); - - char targetPath[std::strlen(pData->oscData->path)+19]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_default_value"); - try_lo_send(pData->oscData->target, targetPath, "iif", static_cast(pluginId), static_cast(index), value); -} - -void CarlaEngine::oscSend_control_set_current_program(const uint pluginId, const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_current_program(%i, %i)", pluginId, index); - - char targetPath[std::strlen(pData->oscData->path)+21]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_current_program"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); -} - -void CarlaEngine::oscSend_control_set_current_midi_program(const uint pluginId, const int32_t index) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - carla_debug("CarlaEngine::oscSend_control_set_current_midi_program(%i, %i)", pluginId, index); - - char targetPath[std::strlen(pData->oscData->path)+26]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_current_midi_program"); - try_lo_send(pData->oscData->target, targetPath, "ii", static_cast(pluginId), index); -} - -void CarlaEngine::oscSend_control_set_program_name(const uint pluginId, const uint32_t index, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_program_name(%i, %i, \"%s\")", pluginId, index, name); - - char targetPath[std::strlen(pData->oscData->path)+18]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_program_name"); - try_lo_send(pData->oscData->target, targetPath, "iis", static_cast(pluginId), static_cast(index), name); -} - -void CarlaEngine::oscSend_control_set_midi_program_data(const uint pluginId, const uint32_t index, const uint32_t bank, const uint32_t program, const char* const name) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(name != nullptr,); - carla_debug("CarlaEngine::oscSend_control_set_midi_program_data(%i, %i, %i, %i, \"%s\")", pluginId, index, bank, program, name); - - char targetPath[std::strlen(pData->oscData->path)+23]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_midi_program_data"); - try_lo_send(pData->oscData->target, targetPath, "iiiis", static_cast(pluginId), static_cast(index), static_cast(bank), static_cast(program), name); -} - -void CarlaEngine::oscSend_control_note_on(const uint pluginId, const uint8_t channel, const uint8_t note, const uint8_t velo) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - CARLA_SAFE_ASSERT_RETURN(velo < MAX_MIDI_VALUE,); - carla_debug("CarlaEngine::oscSend_control_note_on(%i, %i, %i, %i)", pluginId, channel, note, velo); - - char targetPath[std::strlen(pData->oscData->path)+9]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/note_on"); - try_lo_send(pData->oscData->target, targetPath, "iiii", static_cast(pluginId), static_cast(channel), static_cast(note), static_cast(velo)); -} - -void CarlaEngine::oscSend_control_note_off(const uint pluginId, const uint8_t channel, const uint8_t note) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS,); - CARLA_SAFE_ASSERT_RETURN(note < MAX_MIDI_NOTE,); - carla_debug("CarlaEngine::oscSend_control_note_off(%i, %i, %i)", pluginId, channel, note); - - char targetPath[std::strlen(pData->oscData->path)+10]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/note_off"); - try_lo_send(pData->oscData->target, targetPath, "iii", static_cast(pluginId), static_cast(channel), static_cast(note)); -} - -void CarlaEngine::oscSend_control_set_peaks(const uint pluginId) const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pluginId < pData->curPluginCount,); - - // TODO - try and see if we can get peaks[4] ref - const EnginePluginData& epData(pData->plugins[pluginId]); - - char targetPath[std::strlen(pData->oscData->path)+11]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/set_peaks"); - try_lo_send(pData->oscData->target, targetPath, "iffff", static_cast(pluginId), epData.insPeak[0], epData.insPeak[1], epData.outsPeak[0], epData.outsPeak[1]); -} - -void CarlaEngine::oscSend_control_exit() const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(pData->oscData != nullptr,); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->path != nullptr && pData->oscData->path[0] != '\0',); - CARLA_SAFE_ASSERT_RETURN(pData->oscData->target != nullptr,); - carla_debug("CarlaEngine::oscSend_control_exit()"); - - char targetPath[std::strlen(pData->oscData->path)+6]; - std::strcpy(targetPath, pData->oscData->path); - std::strcat(targetPath, "/exit"); - try_lo_send(pData->oscData->target, targetPath, ""); -} -#endif - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_patchbay.cpp b/source/backend/engine/CarlaEngine_patchbay.cpp deleted file mode 100644 index 627a3d8f6..000000000 --- a/source/backend/engine/CarlaEngine_patchbay.cpp +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#ifdef BUILD_BRIDGE -# error This file should not be compiled if building bridge -#endif - -#include "CarlaEngineInternal.hpp" - -#include "LinkedList.hpp" - -#ifdef HAVE_JUCE -# include "juce_audio_basics.h" -using juce::FloatVectorOperations; -#endif - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_START_NAMESPACE - -#if 0 -} // Fix editor indentation -#endif - -// ----------------------------------------------------------------------- - -struct EngineRackBuffers { - float* in[2]; - float* out[2]; - - // connections stuff - LinkedList connectedIns[2]; - LinkedList connectedOuts[2]; - CarlaMutex connectLock; - - int lastConnectionId; - LinkedList usedConnections; - - EngineRackBuffers(const uint32_t bufferSize); - ~EngineRackBuffers(); - void clear(); - void resize(const uint32_t bufferSize); -}; - -// ----------------------------------------------------------------------- - -struct EnginePatchbayBuffers { - // TODO - EnginePatchbayBuffers(const uint32_t bufferSize); - ~EnginePatchbayBuffers(); - void clear(); - void resize(const uint32_t bufferSize); -}; - -// ----------------------------------------------------------------------- -// EngineRackBuffers - -EngineRackBuffers::EngineRackBuffers(const uint32_t bufferSize) - : lastConnectionId(0) -{ - resize(bufferSize); -} - -EngineRackBuffers::~EngineRackBuffers() -{ - clear(); -} - -void EngineRackBuffers::clear() -{ - lastConnectionId = 0; - - if (in[0] != nullptr) - { - delete[] in[0]; - in[0] = nullptr; - } - - if (in[1] != nullptr) - { - delete[] in[1]; - in[1] = nullptr; - } - - if (out[0] != nullptr) - { - delete[] out[0]; - out[0] = nullptr; - } - - if (out[1] != nullptr) - { - delete[] out[1]; - out[1] = nullptr; - } - - connectedIns[0].clear(); - connectedIns[1].clear(); - connectedOuts[0].clear(); - connectedOuts[1].clear(); - usedConnections.clear(); -} - -void EngineRackBuffers::resize(const uint32_t bufferSize) -{ - if (bufferSize > 0) - { - in[0] = new float[bufferSize]; - in[1] = new float[bufferSize]; - out[0] = new float[bufferSize]; - out[1] = new float[bufferSize]; - } - else - { - in[0] = nullptr; - in[1] = nullptr; - out[0] = nullptr; - out[1] = nullptr; - } -} - -// ----------------------------------------------------------------------- -// EnginePatchbayBuffers - -EnginePatchbayBuffers::EnginePatchbayBuffers(const uint32_t bufferSize) -{ - resize(bufferSize); -} - -EnginePatchbayBuffers::~EnginePatchbayBuffers() -{ - clear(); -} - -void EnginePatchbayBuffers::clear() -{ -} - -void EnginePatchbayBuffers::resize(const uint32_t /*bufferSize*/) -{ -} - -// ----------------------------------------------------------------------- -// InternalAudio - -InternalAudio::InternalAudio() noexcept - : isReady(false), - usePatchbay(false), - inCount(0), - outCount(0) -{ - rack = nullptr; -} - -InternalAudio::~InternalAudio() noexcept -{ - CARLA_ASSERT(! isReady); - CARLA_ASSERT(rack == nullptr); -} - -void InternalAudio::initPatchbay() noexcept -{ - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); - - rack->lastConnectionId = 0; - rack->usedConnections.clear(); - } -} - -void InternalAudio::clear() -{ - isReady = false; - inCount = 0; - outCount = 0; - - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); - delete patchbay; - patchbay = nullptr; - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); - delete rack; - rack = nullptr; - } -} - -void InternalAudio::create(const uint32_t bufferSize) -{ - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay == nullptr,); - patchbay = new EnginePatchbayBuffers(bufferSize); - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack == nullptr,); - rack = new EngineRackBuffers(bufferSize); - } - - isReady = true; -} - -void InternalAudio::resize(const uint32_t bufferSize) -{ - if (usePatchbay) - { - CARLA_SAFE_ASSERT_RETURN(patchbay != nullptr,); - patchbay->resize(bufferSize); - } - else - { - CARLA_SAFE_ASSERT_RETURN(rack != nullptr,); - rack->resize(bufferSize); - } -} - -void CarlaEngineProtectedData::processRackFull(float** const inBuf, const uint32_t inCount, float** const outBuf, const uint32_t outCount, const uint32_t nframes, const bool isOffline) -{ - EngineRackBuffers* const rack(bufAudio.rack); - - const CarlaMutex::ScopedLocker sl(rack->connectLock); - - // connect input buffers - if (rack->connectedIns[0].count() == 0) - { - FLOAT_CLEAR(rack->in[0], nframes); - } - else - { - bool first = true; - - for (LinkedList::Itenerator it = rack->connectedIns[0].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < inCount); - - if (first) - { - FLOAT_COPY(rack->in[0], inBuf[port], nframes); - first = false; - } - else - { - FLOAT_ADD(rack->in[0], inBuf[port], nframes); - } - } - - if (first) - FLOAT_CLEAR(rack->in[0], nframes); - } - - if (rack->connectedIns[1].count() == 0) - { - FLOAT_CLEAR(rack->in[1], nframes); - } - else - { - bool first = true; - - for (LinkedList::Itenerator it = rack->connectedIns[1].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < inCount); - - if (first) - { - FLOAT_COPY(rack->in[1], inBuf[port], nframes); - first = false; - } - else - { - FLOAT_ADD(rack->in[1], inBuf[port], nframes); - } - } - - if (first) - FLOAT_CLEAR(rack->in[1], nframes); - } - - FLOAT_CLEAR(rack->out[0], nframes); - FLOAT_CLEAR(rack->out[1], nframes); - - // process - processRack(rack->in, rack->out, nframes, isOffline); - - // connect output buffers - if (rack->connectedOuts[0].count() != 0) - { - for (LinkedList::Itenerator it = rack->connectedOuts[0].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < outCount); - - FLOAT_ADD(outBuf[port], rack->out[0], nframes); - } - } - - if (rack->connectedOuts[1].count() != 0) - { - for (LinkedList::Itenerator it = rack->connectedOuts[1].begin(); it.valid(); it.next()) - { - const uint& port(it.getValue()); - CARLA_SAFE_ASSERT_CONTINUE(port < outCount); - - FLOAT_ADD(outBuf[port], rack->out[1], nframes); - } - } -} - -// ----------------------------------------------------------------------- -// Patchbay - -bool CarlaEngine::patchbayConnect(const int portA, const int portB) -{ - CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); - CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); - carla_debug("CarlaEngineRtAudio::patchbayConnect(%i, %i)", portA, portB); - - if (pData->bufAudio.usePatchbay) - { - // not implemented yet - return false; - } - - EngineRackBuffers* const rack(pData->bufAudio.rack); - - CARLA_SAFE_ASSERT_RETURN_ERR(portA > RACK_PATCHBAY_PORT_MAX, "Invalid output port"); - CARLA_SAFE_ASSERT_RETURN_ERR(portB > RACK_PATCHBAY_PORT_MAX, "Invalid input port"); - - // only allow connections between Carla and other ports - if (portA < 0 && portB < 0) - { - setLastError("Invalid connection (1)"); - return false; - } - if (portA >= 0 && portB >= 0) - { - setLastError("Invalid connection (2)"); - return false; - } - - const int carlaPort = (portA < 0) ? portA : portB; - const int targetPort = (carlaPort == portA) ? portB : portA; - bool makeConnection = false; - - switch (carlaPort) - { - case RACK_PATCHBAY_PORT_AUDIO_IN1: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); - rack->connectLock.lock(); - rack->connectedIns[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_AUDIO_IN2: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_IN*1000+999); - rack->connectLock.lock(); - rack->connectedIns[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_AUDIO_OUT1: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); - rack->connectLock.lock(); - rack->connectedOuts[0].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_AUDIO_OUT2: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000+999); - rack->connectLock.lock(); - rack->connectedOuts[1].append(targetPort - RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - rack->connectLock.unlock(); - makeConnection = true; - break; - - case RACK_PATCHBAY_PORT_MIDI_IN: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_IN*1000+999); - makeConnection = connectRackMidiInPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_IN*1000); - break; - - case RACK_PATCHBAY_PORT_MIDI_OUT: - CARLA_SAFE_ASSERT_BREAK(targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000); - CARLA_SAFE_ASSERT_BREAK(targetPort <= RACK_PATCHBAY_GROUP_MIDI_OUT*1000+999); - makeConnection = connectRackMidiOutPort(targetPort - RACK_PATCHBAY_GROUP_MIDI_OUT*1000); - break; - } - - if (! makeConnection) - { - setLastError("Invalid connection (3)"); - return false; - } - - ConnectionToId connectionToId; - connectionToId.id = rack->lastConnectionId; - connectionToId.portOut = portA; - connectionToId.portIn = portB; - - callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_ADDED, rack->lastConnectionId, portA, portB, 0.0f, nullptr); - - rack->usedConnections.append(connectionToId); - rack->lastConnectionId++; - - return true; -} - -bool CarlaEngine::patchbayDisconnect(const int connectionId) -{ - CARLA_SAFE_ASSERT_RETURN(pData->options.processMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || pData->options.processMode == ENGINE_PROCESS_MODE_PATCHBAY, false); - CARLA_SAFE_ASSERT_RETURN(pData->bufAudio.isReady, false); - carla_debug("CarlaEngineRtAudio::patchbayDisconnect(%i)", connectionId); - - if (pData->bufAudio.usePatchbay) - { - // not implemented yet - return false; - } - - EngineRackBuffers* const rack(pData->bufAudio.rack); - - CARLA_SAFE_ASSERT_RETURN_ERR(rack->usedConnections.count() > 0, "No connections available"); - - for (LinkedList::Itenerator it=rack->usedConnections.begin(); it.valid(); it.next()) - { - const ConnectionToId& connection(it.getValue()); - - if (connection.id == connectionId) - { - const int targetPort((connection.portOut >= 0) ? connection.portOut : connection.portIn); - const int carlaPort((targetPort == connection.portOut) ? connection.portIn : connection.portOut); - - if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_OUT*1000) - { - const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_OUT*1000); - disconnectRackMidiInPort(portId); - } - else if (targetPort >= RACK_PATCHBAY_GROUP_MIDI_IN*1000) - { - const int portId(targetPort-RACK_PATCHBAY_GROUP_MIDI_IN*1000); - disconnectRackMidiOutPort(portId); - } - else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_OUT*1000) - { - CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT2, false); - - const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_OUT*1000); - - rack->connectLock.lock(); - - if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_OUT1) - rack->connectedOuts[0].removeAll(portId); - else - rack->connectedOuts[1].removeAll(portId); - - rack->connectLock.unlock(); - } - else if (targetPort >= RACK_PATCHBAY_GROUP_AUDIO_IN*1000) - { - CARLA_SAFE_ASSERT_RETURN(carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1 || carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN2, false); - - const int portId(targetPort-RACK_PATCHBAY_GROUP_AUDIO_IN*1000); - - rack->connectLock.lock(); - - if (carlaPort == RACK_PATCHBAY_PORT_AUDIO_IN1) - rack->connectedIns[0].removeAll(portId); - else - rack->connectedIns[1].removeAll(portId); - - rack->connectLock.unlock(); - } - else - { - CARLA_SAFE_ASSERT_RETURN(false, false); - } - - callback(ENGINE_CALLBACK_PATCHBAY_CONNECTION_REMOVED, connection.id, connection.portOut, connection.portIn, 0.0f, nullptr); - - rack->usedConnections.remove(it); - break; - } - } - - return true; -} - -bool CarlaEngine::patchbayRefresh() -{ - setLastError("Unsupported operation"); - return false; -} - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/CarlaEngine_ports.cpp b/source/backend/engine/CarlaEngine_ports.cpp deleted file mode 100644 index 5db5f6f00..000000000 --- a/source/backend/engine/CarlaEngine_ports.cpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Carla Plugin Host - * Copyright (C) 2011-2014 Filipe Coelho - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * For a full copy of the GNU General Public License see the doc/GPL.txt file. - */ - -#include "CarlaEngine.hpp" -#include "CarlaMIDI.h" - -#include "CarlaUtils.hpp" - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_START_NAMESPACE - -#if 0 -} // Fix editor indentation -#endif - -// ----------------------------------------------------------------------- -// Fallback data - -static const EngineEvent kFallbackEngineEvent = { kEngineEventTypeNull, 0, 0, {{ kEngineControlEventTypeNull, 0, 0.0f }} }; - -// ----------------------------------------------------------------------- -// Carla Engine port (Abstract) - -CarlaEnginePort::CarlaEnginePort(const CarlaEngine& engine, const bool isInput) - : fEngine(engine), - fIsInput(isInput) -{ - carla_debug("CarlaEnginePort::CarlaEnginePort(%s)", bool2str(isInput)); -} - -CarlaEnginePort::~CarlaEnginePort() -{ - carla_debug("CarlaEnginePort::~CarlaEnginePort()"); -} - -// ----------------------------------------------------------------------- -// Carla Engine Audio port - -CarlaEngineAudioPort::CarlaEngineAudioPort(const CarlaEngine& engine, const bool isInput) - : CarlaEnginePort(engine, isInput), - fBuffer(nullptr) -{ - carla_debug("CarlaEngineAudioPort::CarlaEngineAudioPort(%s)", bool2str(isInput)); -} - -CarlaEngineAudioPort::~CarlaEngineAudioPort() -{ - carla_debug("CarlaEngineAudioPort::~CarlaEngineAudioPort()"); -} - -void CarlaEngineAudioPort::initBuffer() -{ -} - -// ----------------------------------------------------------------------- -// Carla Engine CV port - -CarlaEngineCVPort::CarlaEngineCVPort(const CarlaEngine& engine, const bool isInput) - : CarlaEnginePort(engine, isInput), - fBuffer(nullptr), - fProcessMode(engine.getProccessMode()) -{ - carla_debug("CarlaEngineCVPort::CarlaEngineCVPort(%s)", bool2str(isInput)); - - if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) - fBuffer = new float[engine.getBufferSize()]; -} - -CarlaEngineCVPort::~CarlaEngineCVPort() -{ - carla_debug("CarlaEngineCVPort::~CarlaEngineCVPort()"); - - if (fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS) - { - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - - delete[] fBuffer; - fBuffer = nullptr; - } -} - -void CarlaEngineCVPort::initBuffer() -{ - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); - - carla_zeroFloat(fBuffer, fEngine.getBufferSize()); -} - -void CarlaEngineCVPort::setBufferSize(const uint32_t bufferSize) -{ - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS,); - - delete[] fBuffer; - fBuffer = new float[bufferSize]; -} - -// ----------------------------------------------------------------------- -// Carla Engine Event port - -CarlaEngineEventPort::CarlaEngineEventPort(const CarlaEngine& engine, const bool isInput) - : CarlaEnginePort(engine, isInput), - fBuffer(nullptr), - fProcessMode(engine.getProccessMode()) -{ - carla_debug("CarlaEngineEventPort::CarlaEngineEventPort(%s)", bool2str(isInput)); - - if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) - fBuffer = new EngineEvent[EngineEvent::kMaxInternalCount]; -} - -CarlaEngineEventPort::~CarlaEngineEventPort() -{ - carla_debug("CarlaEngineEventPort::~CarlaEngineEventPort()"); - - if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY) - { - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr,); - - delete[] fBuffer; - fBuffer = nullptr; - } -} - -void CarlaEngineEventPort::initBuffer() -{ - if (fProcessMode == ENGINE_PROCESS_MODE_CONTINUOUS_RACK || fProcessMode == ENGINE_PROCESS_MODE_BRIDGE) - fBuffer = fEngine.getInternalEventBuffer(fIsInput); - else if (fProcessMode == ENGINE_PROCESS_MODE_PATCHBAY && ! fIsInput) - carla_zeroStruct(fBuffer, EngineEvent::kMaxInternalCount); -} - -uint32_t CarlaEngineEventPort::getEventCount() const noexcept -{ - CARLA_SAFE_ASSERT_RETURN(fIsInput, 0); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, 0); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, 0); - - uint32_t i=0; - - for (; i < EngineEvent::kMaxInternalCount; ++i) - { - if (fBuffer[i].type == kEngineEventTypeNull) - break; - } - - return i; -} - -const EngineEvent& CarlaEngineEventPort::getEvent(const uint32_t index) noexcept -{ - CARLA_SAFE_ASSERT_RETURN(fIsInput, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, kFallbackEngineEvent); - CARLA_SAFE_ASSERT_RETURN(index < EngineEvent::kMaxInternalCount, kFallbackEngineEvent); - - return fBuffer[index]; -} - -const EngineEvent& CarlaEngineEventPort::getEventUnchecked(const uint32_t index) noexcept -{ - return fBuffer[index]; -} - -bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEventType type, const uint16_t param, const float value) -{ - CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); - CARLA_SAFE_ASSERT_RETURN(type != kEngineControlEventTypeNull, false); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); - CARLA_SAFE_ASSERT(value >= 0.0f && value <= 1.0f); - - if (type == kEngineControlEventTypeParameter) { - CARLA_SAFE_ASSERT(! MIDI_IS_CONTROL_BANK_SELECT(param)); - } - - const float fixedValue(carla_fixValue(0.0f, 1.0f, value)); - - for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) - { - if (fBuffer[i].type != kEngineEventTypeNull) - continue; - - EngineEvent& event(fBuffer[i]); - - event.type = kEngineEventTypeControl; - event.time = time; - event.channel = channel; - - event.ctrl.type = type; - event.ctrl.param = param; - event.ctrl.value = fixedValue; - - return true; - } - - carla_stderr2("CarlaEngineEventPort::writeControlEvent() - buffer full"); - return false; -} - -bool CarlaEngineEventPort::writeControlEvent(const uint32_t time, const uint8_t channel, const EngineControlEvent& ctrl) -{ - return writeControlEvent(time, channel, ctrl.type, ctrl.param, ctrl.value); -} - -bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const uint8_t port, const uint8_t size, const uint8_t* const data) -{ - CARLA_SAFE_ASSERT_RETURN(! fIsInput, false); - CARLA_SAFE_ASSERT_RETURN(fBuffer != nullptr, false); - CARLA_SAFE_ASSERT_RETURN(fProcessMode != ENGINE_PROCESS_MODE_SINGLE_CLIENT && fProcessMode != ENGINE_PROCESS_MODE_MULTIPLE_CLIENTS, false); - CARLA_SAFE_ASSERT_RETURN(channel < MAX_MIDI_CHANNELS, false); - CARLA_SAFE_ASSERT_RETURN(size > 0 && size <= EngineMidiEvent::kDataSize, false); - CARLA_SAFE_ASSERT_RETURN(data != nullptr, false); - - for (uint32_t i=0; i < EngineEvent::kMaxInternalCount; ++i) - { - if (fBuffer[i].type != kEngineEventTypeNull) - continue; - - EngineEvent& event(fBuffer[i]); - - event.type = kEngineEventTypeMidi; - event.time = time; - event.channel = channel; - - event.midi.port = port; - event.midi.size = size; - - event.midi.data[0] = uint8_t(MIDI_GET_STATUS_FROM_DATA(data)); - - uint8_t j=1; - for (; j < size; ++j) - event.midi.data[j] = data[j]; - for (; j < EngineMidiEvent::kDataSize; ++j) - event.midi.data[j] = 0; - - return true; - } - - carla_stderr2("CarlaEngineEventPort::writeMidiEvent() - buffer full"); - return false; -} - -bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t size, const uint8_t* const data) -{ - return writeMidiEvent(time, uint8_t(MIDI_GET_CHANNEL_FROM_DATA(data)), 0, size, data); -} - -bool CarlaEngineEventPort::writeMidiEvent(const uint32_t time, const uint8_t channel, const EngineMidiEvent& midi) -{ - return writeMidiEvent(time, channel, midi.port, midi.size, midi.data); -} - -// ----------------------------------------------------------------------- - -CARLA_BACKEND_END_NAMESPACE diff --git a/source/backend/engine/Makefile b/source/backend/engine/Makefile index fe5c9f6e7..2ead5b41e 100644 --- a/source/backend/engine/Makefile +++ b/source/backend/engine/Makefile @@ -10,11 +10,7 @@ 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 \ + CarlaEngineInternal.cpp.o \ CarlaEngineOsc.cpp.o \ CarlaEngineThread.cpp.o