| @@ -181,34 +181,67 @@ public: | |||
| case kPluginBridgeOpcodeReadyWait: | |||
| { | |||
| const int size = rdwr_readInt(&fShmControl.data->ringBuffer); | |||
| const int size(rdwr_readInt(&fShmControl.data->ringBuffer)); | |||
| fShmAudioPool.data = (float*)carla_shm_map(fShmAudioPool.shm, size); | |||
| break; | |||
| } | |||
| case kPluginBridgeOpcodeSetBufferSize: | |||
| { | |||
| const int bufferSize = rdwr_readInt(&fShmControl.data->ringBuffer); | |||
| const int bufferSize(rdwr_readInt(&fShmControl.data->ringBuffer)); | |||
| bufferSizeChanged(bufferSize); | |||
| break; | |||
| } | |||
| case kPluginBridgeOpcodeSetSampleRate: | |||
| { | |||
| const float sampleRate = rdwr_readFloat(&fShmControl.data->ringBuffer); | |||
| const float sampleRate(rdwr_readFloat(&fShmControl.data->ringBuffer)); | |||
| sampleRateChanged(sampleRate); | |||
| break; | |||
| } | |||
| case kPluginBridgeOpcodeSetParameter: | |||
| { | |||
| const int index = rdwr_readInt(&fShmControl.data->ringBuffer); | |||
| const float value = rdwr_readFloat(&fShmControl.data->ringBuffer); | |||
| const int index(rdwr_readInt(&fShmControl.data->ringBuffer)); | |||
| const float value(rdwr_readFloat(&fShmControl.data->ringBuffer)); | |||
| CarlaPlugin* const plugin(getPluginUnchecked(0)); | |||
| if (plugin != nullptr && plugin->enabled()) | |||
| { | |||
| plugin->setParameterValueByRealIndex(index, value, false, false, false); | |||
| plugin->postponeRtEvent(kPluginPostRtEventParameterChange, index, 0, value); | |||
| } | |||
| break; | |||
| } | |||
| case kPluginBridgeOpcodeSetProgram: | |||
| { | |||
| const int index(rdwr_readInt(&fShmControl.data->ringBuffer)); | |||
| CarlaPlugin* const plugin(getPluginUnchecked(0)); | |||
| if (plugin != nullptr && plugin->enabled()) | |||
| { | |||
| plugin->setProgram(index, false, false, false); | |||
| plugin->postponeRtEvent(kPluginPostRtEventProgramChange, index, 0, 0.0f); | |||
| } | |||
| break; | |||
| } | |||
| case kPluginBridgeOpcodeSetMidiProgram: | |||
| { | |||
| const int index(rdwr_readInt(&fShmControl.data->ringBuffer)); | |||
| CarlaPlugin* const plugin(getPluginUnchecked(0)); | |||
| if (plugin != nullptr && plugin->enabled()) | |||
| { | |||
| plugin->setMidiProgram(index, false, false, false); | |||
| plugin->postponeRtEvent(kPluginPostRtEventMidiProgramChange, index, 0, 0.0f); | |||
| } | |||
| break; | |||
| } | |||
| @@ -220,8 +253,8 @@ public: | |||
| if (plugin != nullptr && plugin->enabled() && plugin->tryLock()) | |||
| { | |||
| const uint32_t inCount = plugin->audioInCount(); | |||
| const uint32_t outCount = plugin->audioOutCount(); | |||
| const uint32_t inCount(plugin->audioInCount()); | |||
| const uint32_t outCount(plugin->audioOutCount()); | |||
| float* inBuffer[inCount]; | |||
| float* outBuffer[outCount]; | |||
| @@ -340,6 +340,54 @@ public: | |||
| CarlaPlugin::setParameterValue(parameterId, fixedValue, sendGui, sendOsc, sendCallback); | |||
| } | |||
| void setProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override | |||
| { | |||
| CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->prog.count)); | |||
| if (index < -1) | |||
| index = -1; | |||
| else if (index > static_cast<int32_t>(kData->prog.count)) | |||
| return; | |||
| const bool doLock(sendGui || sendOsc || sendCallback); | |||
| if (doLock) | |||
| kData->singleMutex.lock(); | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetProgram); | |||
| rdwr_writeInt(&fShmControl.data->ringBuffer, index); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| if (doLock) | |||
| kData->singleMutex.unlock(); | |||
| CarlaPlugin::setProgram(index, sendGui, sendOsc, sendCallback); | |||
| } | |||
| void setMidiProgram(int32_t index, const bool sendGui, const bool sendOsc, const bool sendCallback) override | |||
| { | |||
| CARLA_ASSERT(index >= -1 && index < static_cast<int32_t>(kData->midiprog.count)); | |||
| if (index < -1) | |||
| index = -1; | |||
| else if (index > static_cast<int32_t>(kData->midiprog.count)) | |||
| return; | |||
| const bool doLock(sendGui || sendOsc || sendCallback); | |||
| if (doLock) | |||
| kData->singleMutex.lock(); | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetMidiProgram); | |||
| rdwr_writeInt(&fShmControl.data->ringBuffer, index); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| if (doLock) | |||
| kData->singleMutex.unlock(); | |||
| CarlaPlugin::setMidiProgram(index, sendGui, sendOsc, sendCallback); | |||
| } | |||
| #if 0 | |||
| void setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) override | |||
| { | |||
| @@ -533,6 +581,24 @@ public: | |||
| // ------------------------------------------------------------------- | |||
| // Plugin processing | |||
| void activate() override | |||
| { | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetParameter); | |||
| rdwr_writeInt(&fShmControl.data->ringBuffer, PARAMETER_ACTIVE); | |||
| rdwr_writeFloat(&fShmControl.data->ringBuffer, 1.0f); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| waitForServer(); | |||
| } | |||
| void deactivate() override | |||
| { | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetParameter); | |||
| rdwr_writeInt(&fShmControl.data->ringBuffer, PARAMETER_ACTIVE); | |||
| rdwr_writeFloat(&fShmControl.data->ringBuffer, 0.0f); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| waitForServer(); | |||
| } | |||
| void process(float** const inBuffer, float** const outBuffer, const uint32_t frames) override | |||
| { | |||
| uint32_t i/*, k*/; | |||
| @@ -693,6 +759,23 @@ public: | |||
| return true; | |||
| } | |||
| void bufferSizeChanged(const uint32_t newBufferSize) override | |||
| { | |||
| resizeAudioPool(newBufferSize); | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetBufferSize); | |||
| rdwr_writeInt(&fShmControl.data->ringBuffer, newBufferSize); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| } | |||
| void sampleRateChanged(const double newSampleRate) override | |||
| { | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetSampleRate); | |||
| rdwr_writeFloat(&fShmControl.data->ringBuffer, newSampleRate); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| } | |||
| // ------------------------------------------------------------------- | |||
| // Plugin buffers | |||
| @@ -710,102 +793,7 @@ public: | |||
| // ------------------------------------------------------------------- | |||
| // Post-poned UI Stuff | |||
| void uiParameterChange(const uint32_t index, const float value) override | |||
| { | |||
| CARLA_ASSERT(index < kData->param.count); | |||
| if (index >= kData->param.count) | |||
| return; | |||
| if (kData->osc.data.target == nullptr) | |||
| return; | |||
| osc_send_control(&kData->osc.data, kData->param.data[index].rindex, value); | |||
| } | |||
| void uiProgramChange(const uint32_t index) override | |||
| { | |||
| CARLA_ASSERT(index < kData->prog.count); | |||
| if (index >= kData->prog.count) | |||
| return; | |||
| if (kData->osc.data.target == nullptr) | |||
| return; | |||
| osc_send_program(&kData->osc.data, index); | |||
| } | |||
| void uiMidiProgramChange(const uint32_t index) override | |||
| { | |||
| CARLA_ASSERT(index < kData->midiprog.count); | |||
| if (index >= kData->midiprog.count) | |||
| return; | |||
| if (kData->osc.data.target == nullptr) | |||
| return; | |||
| osc_send_midi_program(&kData->osc.data, index); | |||
| } | |||
| void uiNoteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) override | |||
| { | |||
| CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
| CARLA_ASSERT(note < MAX_MIDI_NOTE); | |||
| CARLA_ASSERT(velo > 0 && velo < MAX_MIDI_VALUE); | |||
| if (channel >= MAX_MIDI_CHANNELS) | |||
| return; | |||
| if (note >= MAX_MIDI_NOTE) | |||
| return; | |||
| if (velo >= MAX_MIDI_VALUE) | |||
| return; | |||
| if (kData->osc.data.target == nullptr) | |||
| return; | |||
| uint8_t midiData[4] = { 0 }; | |||
| midiData[1] = MIDI_STATUS_NOTE_ON + channel; | |||
| midiData[2] = note; | |||
| midiData[3] = velo; | |||
| osc_send_midi(&kData->osc.data, midiData); | |||
| } | |||
| void uiNoteOff(const uint8_t channel, const uint8_t note) override | |||
| { | |||
| CARLA_ASSERT(channel < MAX_MIDI_CHANNELS); | |||
| CARLA_ASSERT(note < MAX_MIDI_NOTE); | |||
| if (channel >= MAX_MIDI_CHANNELS) | |||
| return; | |||
| if (note >= MAX_MIDI_NOTE) | |||
| return; | |||
| if (kData->osc.data.target == nullptr) | |||
| return; | |||
| uint8_t midiData[4] = { 0 }; | |||
| midiData[1] = MIDI_STATUS_NOTE_OFF + channel; | |||
| midiData[2] = note; | |||
| osc_send_midi(&kData->osc.data, midiData); | |||
| } | |||
| void bufferSizeChanged(const uint32_t newBufferSize) override | |||
| { | |||
| resizeAudioPool(newBufferSize); | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetBufferSize); | |||
| rdwr_writeInt(&fShmControl.data->ringBuffer, newBufferSize); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| } | |||
| void sampleRateChanged(const double newSampleRate) override | |||
| { | |||
| rdwr_writeOpcode(&fShmControl.data->ringBuffer, kPluginBridgeOpcodeSetSampleRate); | |||
| rdwr_writeFloat(&fShmControl.data->ringBuffer, newSampleRate); | |||
| rdwr_commitWrite(&fShmControl.data->ringBuffer); | |||
| } | |||
| // nothing | |||
| // ------------------------------------------------------------------- | |||
| @@ -1043,7 +1043,9 @@ void CarlaPlugin::setEnabled(const bool yesNo) | |||
| void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| CARLA_ASSERT(sendOsc || sendCallback); // never call this from RT | |||
| #endif | |||
| if (kData->active == active) | |||
| return; | |||
| @@ -1067,9 +1069,6 @@ void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool se | |||
| if (sendCallback) | |||
| kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_ACTIVE, 0, value, nullptr); | |||
| if (fHints & PLUGIN_IS_BRIDGE) | |||
| osc_send_control(&kData->osc.data, PARAMETER_ACTIVE, value); | |||
| #else | |||
| return; | |||
| @@ -1173,7 +1172,9 @@ void CarlaPlugin::setPanning(const float value, const bool sendOsc, const bool s | |||
| void CarlaPlugin::setCtrlChannel(const int8_t channel, const bool sendOsc, const bool sendCallback) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| CARLA_ASSERT(sendOsc || sendCallback); // never call this from RT | |||
| #endif | |||
| CARLA_ASSERT_INT(channel >= -1 && channel < MAX_MIDI_CHANNELS, channel); | |||
| if (kData->ctrlChannel == channel) | |||
| @@ -1666,7 +1667,7 @@ void CarlaPlugin::registerToOscClient() | |||
| } | |||
| // Plugin Parameters | |||
| if (kData->param.count > 0 /*&& kData->param.count < kData->engine->getOptions().maxParameters*/) | |||
| if (kData->param.count > 0 && kData->param.count < kData->engine->getOptions().maxParameters) | |||
| { | |||
| char bufName[STR_MAX+1], bufUnit[STR_MAX+1]; | |||
| @@ -1937,7 +1938,7 @@ void CarlaPlugin::postRtEventsRun() | |||
| while (! kData->postRtEvents.data.isEmpty()) | |||
| { | |||
| const PluginPostRtEvent& event = kData->postRtEvents.data.getFirst(true); | |||
| const PluginPostRtEvent& event(kData->postRtEvents.data.getFirst(true)); | |||
| switch (event.type) | |||
| { | |||
| @@ -1945,7 +1946,9 @@ void CarlaPlugin::postRtEventsRun() | |||
| break; | |||
| case kPluginPostRtEventDebug: | |||
| #ifndef BUILD_BRIDGE | |||
| kData->engine->callback(CALLBACK_DEBUG, fId, event.value1, event.value2, event.value3, nullptr); | |||
| #endif | |||
| break; | |||
| case kPluginPostRtEventParameterChange: | |||
| @@ -1957,10 +1960,10 @@ void CarlaPlugin::postRtEventsRun() | |||
| // Update OSC control client | |||
| if (kData->engine->isOscControlRegistered()) | |||
| kData->engine->osc_send_control_set_parameter_value(fId, event.value1, event.value3); | |||
| #endif | |||
| // Update Host | |||
| kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, event.value1, 0, event.value3, nullptr); | |||
| #endif | |||
| break; | |||
| case kPluginPostRtEventProgramChange: | |||
| @@ -1977,10 +1980,10 @@ void CarlaPlugin::postRtEventsRun() | |||
| for (uint32_t j=0; j < kData->param.count; ++j) | |||
| kData->engine->osc_send_control_set_default_value(fId, j, kData->param.ranges[j].def); | |||
| } | |||
| #endif | |||
| // Update Host | |||
| kData->engine->callback(CALLBACK_PROGRAM_CHANGED, fId, event.value1, 0, 0.0f, nullptr); | |||
| #endif | |||
| break; | |||
| case kPluginPostRtEventMidiProgramChange: | |||
| @@ -1997,10 +2000,10 @@ void CarlaPlugin::postRtEventsRun() | |||
| for (uint32_t j=0; j < kData->param.count; ++j) | |||
| kData->engine->osc_send_control_set_default_value(fId, j, kData->param.ranges[j].def); | |||
| } | |||
| #endif | |||
| // Update Host | |||
| kData->engine->callback(CALLBACK_MIDI_PROGRAM_CHANGED, fId, event.value1, 0, 0.0f, nullptr); | |||
| #endif | |||
| break; | |||
| case kPluginPostRtEventNoteOn: | |||
| @@ -2011,10 +2014,10 @@ void CarlaPlugin::postRtEventsRun() | |||
| // Update OSC control client | |||
| if (kData->engine->isOscControlRegistered()) | |||
| kData->engine->osc_send_control_note_on(fId, event.value1, event.value2, int(event.value3)); | |||
| #endif | |||
| // Update Host | |||
| kData->engine->callback(CALLBACK_NOTE_ON, fId, event.value1, event.value2, int(event.value3), nullptr); | |||
| #endif | |||
| break; | |||
| case kPluginPostRtEventNoteOff: | |||
| @@ -2025,10 +2028,10 @@ void CarlaPlugin::postRtEventsRun() | |||
| // Update OSC control client | |||
| if (kData->engine->isOscControlRegistered()) | |||
| kData->engine->osc_send_control_note_off(fId, event.value1, event.value2); | |||
| #endif | |||
| // Update Host | |||
| kData->engine->callback(CALLBACK_NOTE_OFF, fId, event.value1, event.value2, 0.0f, nullptr); | |||
| #endif | |||
| break; | |||
| } | |||
| } | |||
| @@ -2166,8 +2169,10 @@ CarlaPlugin::ScopedSingleProcessLocker::~ScopedSingleProcessLocker() | |||
| if (kBlock) | |||
| { | |||
| #ifndef BUILD_BRIDGE | |||
| if (kPlugin->kData->singleMutex.wasTryLockCalled()) | |||
| kPlugin->kData->needsReset = true; | |||
| #endif | |||
| kPlugin->kData->singleMutex.unlock(); | |||
| } | |||
| @@ -67,10 +67,9 @@ public: | |||
| // processing | |||
| virtual void setParameter(const int32_t rindex, const float value) = 0; | |||
| #ifndef BUILD_BRIDGE_PLUGIN | |||
| virtual void setProgram(const uint32_t index) = 0; | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| virtual void setMidiProgram(const uint32_t index) = 0; | |||
| #else | |||
| virtual void setMidiProgram(const uint32_t bank, const uint32_t program) = 0; | |||
| virtual void noteOn(const uint8_t channel, const uint8_t note, const uint8_t velo) = 0; | |||
| virtual void noteOff(const uint8_t channel, const uint8_t note) = 0; | |||
| @@ -162,11 +162,11 @@ int CarlaBridgeOsc::handleMessage(const char* const path, const int argc, const | |||
| return handleMsgConfigure(argc, argv, types); | |||
| if (std::strcmp(method, "control") == 0) | |||
| return handleMsgControl(argc, argv, types); | |||
| #ifndef BUILD_BRIDGE_PLUGIN | |||
| if (std::strcmp(method, "program") == 0) | |||
| return handleMsgProgram(argc, argv, types); | |||
| if (std::strcmp(method, "midi-program") == 0) | |||
| return handleMsgMidiProgram(argc, argv, types); | |||
| #ifndef BUILD_BRIDGE_PLUGIN | |||
| if (std::strcmp(method, "midi") == 0) | |||
| return handleMsgMidi(argc, argv, types); | |||
| #endif | |||
| @@ -246,6 +246,7 @@ int CarlaBridgeOsc::handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
| return 0; | |||
| } | |||
| #ifndef BUILD_BRIDGE_PLUGIN | |||
| int CarlaBridgeOsc::handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
| { | |||
| carla_debug("CarlaBridgeOsc::handleMsgProgram()"); | |||
| @@ -267,28 +268,6 @@ int CarlaBridgeOsc::handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
| return 0; | |||
| } | |||
| #ifdef BUILD_BRIDGE_PLUGIN | |||
| int CarlaBridgeOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
| { | |||
| carla_debug("CarlaBridgeOsc::handleMsgMidiProgram()"); | |||
| CARLA_ASSERT(kClient != nullptr); | |||
| CARLA_BRIDGE_OSC_CHECK_OSC_TYPES(1, "i"); | |||
| if (kClient == nullptr) | |||
| return 1; | |||
| const int32_t index = argv[0]->i; | |||
| CARLA_SAFE_ASSERT_INT(index >= 0, index); | |||
| if (index < 0) | |||
| return 1; | |||
| kClient->setMidiProgram(static_cast<uint32_t>(index)); | |||
| return 0; | |||
| } | |||
| #else | |||
| int CarlaBridgeOsc::handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS) | |||
| { | |||
| carla_debug("CarlaBridgeOsc::handleMsgMidiProgram()"); | |||
| @@ -99,9 +99,9 @@ private: | |||
| int handleMsgConfigure(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||
| int handleMsgControl(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||
| #ifndef BUILD_BRIDGE_PLUGIN | |||
| int handleMsgProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||
| int handleMsgMidiProgram(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||
| #ifndef BUILD_BRIDGE_PLUGIN | |||
| int handleMsgMidi(CARLA_BRIDGE_OSC_HANDLE_ARGS); | |||
| #endif | |||
| int handleMsgShow(); | |||
| @@ -18,6 +18,7 @@ | |||
| #include "CarlaBridgeClient.hpp" | |||
| #include "CarlaBridgeToolkit.hpp" | |||
| #include "CarlaBridgeUtils.hpp" | |||
| #include "CarlaStandalone.hpp" | |||
| #include "CarlaEngine.hpp" | |||
| #include "CarlaPlugin.hpp" | |||
| @@ -212,7 +213,7 @@ public: | |||
| for (uint32_t i=0; i < fPlugin->customDataCount(); i++) | |||
| { | |||
| const CarlaBackend::CustomData& cdata = fPlugin->customData(i); | |||
| const CarlaBackend::CustomData& cdata(fPlugin->customData(i)); | |||
| fEngine->osc_send_bridge_set_custom_data(cdata.type, cdata.key, cdata.value); | |||
| } | |||
| @@ -244,7 +245,7 @@ public: | |||
| } | |||
| } | |||
| //engine->osc_send_bridge_configure(CarlaBackend::CARLA_BRIDGE_MSG_SAVED, ""); | |||
| fEngine->osc_send_bridge_configure(CARLA_BRIDGE_MSG_SAVED, ""); | |||
| } | |||
| void setCustomData(const char* const type, const char* const key, const char* const value) | |||
| @@ -299,24 +300,6 @@ public: | |||
| fPlugin->setParameterValueByRealIndex(rindex, value, true, true, false); | |||
| } | |||
| void setProgram(const uint32_t index) | |||
| { | |||
| carla_debug("CarlaPluginClient::setProgram(%i)", index); | |||
| CARLA_ASSERT(fPlugin != nullptr); | |||
| if (fPlugin != nullptr) | |||
| fPlugin->setProgram(index, true, true, false); | |||
| } | |||
| void setMidiProgram(const uint32_t index) | |||
| { | |||
| carla_debug("CarlaPluginClient::setMidiProgram(%i)", index); | |||
| CARLA_ASSERT(fPlugin != nullptr); | |||
| if (fPlugin != nullptr) | |||
| fPlugin->setMidiProgram(index, true, true, false); | |||
| } | |||
| protected: | |||
| void handleCallback(const CarlaBackend::CallbackType action, const int value1, const int value2, const float value3, const char* const valueStr) | |||
| { | |||
| @@ -340,6 +323,7 @@ protected: | |||
| { | |||
| // hide gui | |||
| //sendOscConfigure(); | |||
| fEngine->osc_send_bridge_configure(CARLA_BRIDGE_MSG_HIDE_GUI, ""); | |||
| } | |||
| break; | |||
| default: | |||