diff --git a/source/backend/engine/CarlaEngineBridge.cpp b/source/backend/engine/CarlaEngineBridge.cpp index d4b6b24c1..ea7891f18 100644 --- a/source/backend/engine/CarlaEngineBridge.cpp +++ b/source/backend/engine/CarlaEngineBridge.cpp @@ -511,22 +511,232 @@ public: void idle() noexcept override { + CarlaPlugin* const plugin(pData->plugins[0].plugin); + CARLA_SAFE_ASSERT_RETURN(plugin != nullptr,); + if (fFirstIdle) { fFirstIdle = false; fLastPingCounter = 0; + char bufStr[STR_MAX+1]; + uint32_t bufStrSize; + const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); - // TODO - send plugin data + // kPluginBridgeNonRtServerPluginInfo1 + { + // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPluginInfo1); + fShmNonRtServerControl.writeUInt(plugin->getCategory()); + fShmNonRtServerControl.writeUInt(plugin->getHints()); + fShmNonRtServerControl.writeUInt(plugin->getOptionsAvailable()); + fShmNonRtServerControl.writeUInt(plugin->getOptionsEnabled()); + fShmNonRtServerControl.writeLong(plugin->getUniqueId()); + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerPluginInfo2 + { + // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerPluginInfo2); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getRealName(bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getLabel(bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getMaker(bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getCopyright(bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerAudioCount + { + // uint/ins, uint/outs + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerAudioCount); + fShmNonRtServerControl.writeUInt(plugin->getAudioInCount()); + fShmNonRtServerControl.writeUInt(plugin->getAudioOutCount()); + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerMidiCount + { + // uint/ins, uint/outs + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiCount); + fShmNonRtServerControl.writeUInt(plugin->getMidiInCount()); + fShmNonRtServerControl.writeUInt(plugin->getMidiOutCount()); + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerParameter* + if (const uint32_t count = plugin->getParameterCount()) + { + uint32_t paramIns, paramOuts; + plugin->getParameterCountInfo(paramIns, paramOuts); + + // uint/ins, uint/outs + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterCount); + fShmNonRtServerControl.writeUInt(paramIns); + fShmNonRtServerControl.writeUInt(paramOuts); + fShmNonRtServerControl.commitWrite(); + + for (uint32_t i=0, maxParams=pData->options.maxParameters; igetParameterData(i)); + + // uint/index, int/rindex, uint/type, uint/hints, short/cc + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterData1); + fShmNonRtServerControl.writeUInt(i); + fShmNonRtServerControl.writeInt(paramData.rindex); + fShmNonRtServerControl.writeUInt(paramData.type); + fShmNonRtServerControl.writeUInt(paramData.hints); + fShmNonRtServerControl.writeShort(paramData.midiCC); + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerParameterData2 + { + // uint/index, uint/size, str[] (name), uint/size, str[] (unit) + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterData2); + fShmNonRtServerControl.writeUInt(i); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getParameterName(i, bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getParameterUnit(i, bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerParameterRanges + { + const ParameterRanges& paramRanges(plugin->getParameterRanges(i)); + + // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterRanges); + fShmNonRtServerControl.writeUInt(i); + fShmNonRtServerControl.writeFloat(paramRanges.def); + fShmNonRtServerControl.writeFloat(paramRanges.min); + fShmNonRtServerControl.writeFloat(paramRanges.max); + fShmNonRtServerControl.writeFloat(paramRanges.step); + fShmNonRtServerControl.writeFloat(paramRanges.stepSmall); + fShmNonRtServerControl.writeFloat(paramRanges.stepLarge); + fShmNonRtServerControl.commitWrite(); + } + + // kPluginBridgeNonRtServerParameterValue2 + { + // uint/index float/value (used for init/output parameters only, don't resend values) + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterValue2); + fShmNonRtServerControl.writeUInt(i); + fShmNonRtServerControl.writeFloat(plugin->getParameterValue(i)); + fShmNonRtServerControl.commitWrite(); + } + } + } + + // kPluginBridgeNonRtServerProgram* + if (const uint32_t count = plugin->getProgramCount()) + { + // uint/count + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerProgramCount); + fShmNonRtServerControl.writeUInt(count); + fShmNonRtServerControl.commitWrite(); + + for (uint32_t i=0; i < count; ++i) + { + // uint/index, uint/size, str[] (name) + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerProgramName); + fShmNonRtServerControl.writeUInt(i); + + carla_zeroChar(bufStr, STR_MAX); + plugin->getProgramName(i, bufStr); + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(bufStr))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(bufStr, bufStrSize); + + fShmNonRtServerControl.commitWrite(); + } + } + + // kPluginBridgeNonRtServerMidiProgram* + if (const uint32_t count = plugin->getMidiProgramCount()) + { + // uint/count + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiProgramCount); + fShmNonRtServerControl.writeUInt(count); + fShmNonRtServerControl.commitWrite(); + + for (uint32_t i=0; i < count; ++i) + { + const MidiProgramData& mpData(plugin->getMidiProgramData(i)); + CARLA_SAFE_ASSERT_CONTINUE(mpData.name != nullptr); + + // uint/index, uint/bank, uint/program, uint/size, str[] (name) + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerMidiProgramData); + fShmNonRtServerControl.writeUInt(i); + fShmNonRtServerControl.writeUInt(mpData.bank); + fShmNonRtServerControl.writeUInt(mpData.program); + + bufStrSize = carla_fixValue(1U, 32U, static_cast(std::strlen(mpData.name))); + fShmNonRtServerControl.writeUInt(bufStrSize); + fShmNonRtServerControl.writeCustomData(mpData.name, bufStrSize); + + fShmNonRtServerControl.commitWrite(); + } + } + // ready! fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerReady); fShmNonRtServerControl.commitWrite(); carla_stdout("Carla Client Ready!"); } - // TODO - send output parameters to server + if (const uint32_t count = plugin->getParameterCount()) + { + const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); + + for (uint32_t i=0; i < count; ++i) + { + if (! plugin->isParameterOutput(i)) + continue; + + fShmNonRtServerControl.writeOpcode(kPluginBridgeNonRtServerParameterValue2); + fShmNonRtServerControl.writeUInt(i); + fShmNonRtServerControl.writeFloat(plugin->getParameterValue(i)); + + if (! fShmNonRtServerControl.commitWrite()) + break; + } + } CarlaEngine::idle(); @@ -749,7 +959,7 @@ public: const CarlaString valueBase64(CarlaString::asBase64(valueMemStream.getData(), valueMemStream.getDataSize())); const uint32_t valueBase64Len(static_cast(valueBase64.length())); - CARLA_SAFE_ASSERT_CONTINUE(valueBase64.length() > 0); + CARLA_SAFE_ASSERT_CONTINUE(valueBase64Len > 0); { const CarlaMutexLocker _cml(fShmNonRtServerControl.mutex); diff --git a/source/backend/engine/CarlaEngineThread.cpp b/source/backend/engine/CarlaEngineThread.cpp index 1d09e7dce..8e93a10ce 100644 --- a/source/backend/engine/CarlaEngineThread.cpp +++ b/source/backend/engine/CarlaEngineThread.cpp @@ -89,16 +89,11 @@ void CarlaEngineThread::run() noexcept value = plugin->getParameterValue(j); +#ifndef BUILD_BRIDGE // Update OSC engine client if (oscRegisted) - { -#ifdef BUILD_BRIDGE - //kEngine->oscSend_bridge_parameter_value(j, value); -#else kEngine->oscSend_control_set_parameter_value(i, static_cast(j), value); #endif - } - // Update UI if (needsUiUpdates) plugin->uiParameterChange(j, value); diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 6d1d3291c..5aa1a511f 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -1438,11 +1438,12 @@ void CarlaPlugin::registerToOscClient() noexcept // Base data { - // TODO - clear buf - char bufName[STR_MAX+1] = { '\0' }; - char bufLabel[STR_MAX+1] = { '\0' }; - char bufMaker[STR_MAX+1] = { '\0' }; - char bufCopyright[STR_MAX+1] = { '\0' }; + char bufName[STR_MAX+1], bufLabel[STR_MAX+1], bufMaker[STR_MAX+1], bufCopyright[STR_MAX+1]; + carla_zeroChar(bufName, STR_MAX); + carla_zeroChar(bufLabel, STR_MAX); + carla_zeroChar(bufMaker, STR_MAX); + carla_zeroChar(bufCopyright, STR_MAX); + getRealName(bufName); getLabel(bufLabel); getMaker(bufMaker); @@ -1463,11 +1464,11 @@ void CarlaPlugin::registerToOscClient() noexcept } // Plugin Parameters - if (pData->param.count > 0) + if (const uint32_t count = pData->param.count) { char bufName[STR_MAX+1], bufUnit[STR_MAX+1]; - for (uint32_t i=0, count=pData->param.count, maxParams=pData->engine->getOptions().maxParameters; iengine->getOptions().maxParameters; iprog.count > 0) + if (const uint32_t count = pData->prog.count) { - pData->engine->oscSend_control_set_program_count(pData->id, pData->prog.count); + pData->engine->oscSend_control_set_program_count(pData->id, count); - for (uint32_t i=0; i < pData->prog.count; ++i) + for (uint32_t i=0; i < count; ++i) pData->engine->oscSend_control_set_program_name(pData->id, i, pData->prog.names[i]); pData->engine->oscSend_control_set_current_program(pData->id, pData->prog.current); } // MIDI Programs - if (pData->midiprog.count > 0) + if (const uint32_t count = pData->midiprog.count) { - pData->engine->oscSend_control_set_midi_program_count(pData->id, pData->midiprog.count); + pData->engine->oscSend_control_set_midi_program_count(pData->id, count); - for (uint32_t i=0; i < pData->midiprog.count; ++i) + for (uint32_t i=0; i < count; ++i) { const MidiProgramData& mpData(pData->midiprog.data[i]); diff --git a/source/backend/plugin/CarlaPluginBridge.cpp b/source/backend/plugin/CarlaPluginBridge.cpp index 3ad2bfe13..d4ded70c1 100644 --- a/source/backend/plugin/CarlaPluginBridge.cpp +++ b/source/backend/plugin/CarlaPluginBridge.cpp @@ -2020,12 +2020,15 @@ public: } } break; - case kPluginBridgeNonRtServerParameterRanges1: { - // uint/index, float/def, float/min, float/max + case kPluginBridgeNonRtServerParameterRanges: { + // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge const uint32_t index = fShmNonRtServerControl.readUInt(); const float def = fShmNonRtServerControl.readFloat(); const float min = fShmNonRtServerControl.readFloat(); const float max = fShmNonRtServerControl.readFloat(); + const float step = fShmNonRtServerControl.readFloat(); + const float stepSmall = fShmNonRtServerControl.readFloat(); + const float stepLarge = fShmNonRtServerControl.readFloat(); CARLA_SAFE_ASSERT_BREAK(min < max); CARLA_SAFE_ASSERT_BREAK(def >= min); @@ -2037,27 +2040,29 @@ public: pData->param.ranges[index].def = def; pData->param.ranges[index].min = min; pData->param.ranges[index].max = max; + pData->param.ranges[index].step = step; + pData->param.ranges[index].stepSmall = stepSmall; + pData->param.ranges[index].stepLarge = stepLarge; } } break; - case kPluginBridgeNonRtServerParameterRanges2: { - // uint/index float/step, float/stepSmall, float/stepLarge - const uint32_t index = fShmNonRtServerControl.readUInt(); - const float step = fShmNonRtServerControl.readFloat(); - const float stepSmall = fShmNonRtServerControl.readFloat(); - const float stepLarge = fShmNonRtServerControl.readFloat(); + case kPluginBridgeNonRtServerParameterValue: { + // uint/index float/value + const uint32_t index = fShmNonRtServerControl.readUInt(); + const float value = fShmNonRtServerControl.readFloat(); CARLA_SAFE_ASSERT_INT2(index < pData->param.count, index, pData->param.count); if (index < pData->param.count) { - pData->param.ranges[index].step = step; - pData->param.ranges[index].stepSmall = stepSmall; - pData->param.ranges[index].stepLarge = stepLarge; + const float fixedValue(pData->param.getFixedValue(index, value)); + fParams[index].value = fixedValue; + + CarlaPlugin::setParameterValue(index, fixedValue, false, true, true); } } break; - case kPluginBridgeNonRtServerParameterValue: { + case kPluginBridgeNonRtServerParameterValue2: { // uint/index float/value const uint32_t index = fShmNonRtServerControl.readUInt(); const float value = fShmNonRtServerControl.readFloat(); @@ -2068,8 +2073,6 @@ public: { const float fixedValue(pData->param.getFixedValue(index, value)); fParams[index].value = fixedValue; - - CarlaPlugin::setParameterValue(index, fixedValue, false, true, true); } } break; diff --git a/source/utils/CarlaBridgeUtils.hpp b/source/utils/CarlaBridgeUtils.hpp index 001580df9..6bf48a388 100644 --- a/source/utils/CarlaBridgeUtils.hpp +++ b/source/utils/CarlaBridgeUtils.hpp @@ -75,26 +75,26 @@ enum PluginBridgeNonRtClientOpcode { enum PluginBridgeNonRtServerOpcode { kPluginBridgeNonRtServerNull = 0, kPluginBridgeNonRtServerPong, - kPluginBridgeNonRtServerPluginInfo1, // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId - kPluginBridgeNonRtServerPluginInfo2, // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) - kPluginBridgeNonRtServerAudioCount, // uint/ins, uint/outs - kPluginBridgeNonRtServerMidiCount, // uint/ins, uint/outs - kPluginBridgeNonRtServerParameterCount, // uint/ins, uint/outs - kPluginBridgeNonRtServerProgramCount, // uint/count - kPluginBridgeNonRtServerMidiProgramCount, // uint/count - kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc - kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (unit) - kPluginBridgeNonRtServerParameterRanges1, // uint/index, float/def, float/min, float/max - kPluginBridgeNonRtServerParameterRanges2, // uint/index float/step, float/stepSmall, float/stepLarge - kPluginBridgeNonRtServerParameterValue, // uint/index float/value - kPluginBridgeNonRtServerDefaultValue, // uint/index float/value - kPluginBridgeNonRtServerCurrentProgram, // int/index - kPluginBridgeNonRtServerCurrentMidiProgram, // int/index - kPluginBridgeNonRtServerProgramName, // uint/index, uint/size, str[] (name) - kPluginBridgeNonRtServerMidiProgramData, // uint/index, uint/bank, uint/program, uint/size, str[] (name) - kPluginBridgeNonRtServerSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[] (base64, compressed) - kPluginBridgeNonRtServerSetChunkDataFile, // uint/size, str[] (filename, base64 content) - kPluginBridgeNonRtServerSetLatency, // uint + kPluginBridgeNonRtServerPluginInfo1, // uint/category, uint/hints, uint/optionsAvailable, uint/optionsEnabled, long/uniqueId + kPluginBridgeNonRtServerPluginInfo2, // uint/size, str[] (realName), uint/size, str[] (label), uint/size, str[] (maker), uint/size, str[] (copyright) + kPluginBridgeNonRtServerAudioCount, // uint/ins, uint/outs + kPluginBridgeNonRtServerMidiCount, // uint/ins, uint/outs + kPluginBridgeNonRtServerParameterCount, // uint/ins, uint/outs + kPluginBridgeNonRtServerProgramCount, // uint/count + kPluginBridgeNonRtServerMidiProgramCount, // uint/count + kPluginBridgeNonRtServerParameterData1, // uint/index, int/rindex, uint/type, uint/hints, short/cc + kPluginBridgeNonRtServerParameterData2, // uint/index, uint/size, str[] (name), uint/size, str[] (unit) + kPluginBridgeNonRtServerParameterRanges, // uint/index, float/def, float/min, float/max, float/step, float/stepSmall, float/stepLarge + kPluginBridgeNonRtServerParameterValue, // uint/index float/value + kPluginBridgeNonRtServerParameterValue2, // uint/index float/value (used for init/output parameters only, don't resend values) + kPluginBridgeNonRtServerDefaultValue, // uint/index float/value + kPluginBridgeNonRtServerCurrentProgram, // int/index + kPluginBridgeNonRtServerCurrentMidiProgram, // int/index + kPluginBridgeNonRtServerProgramName, // uint/index, uint/size, str[] (name) + kPluginBridgeNonRtServerMidiProgramData, // uint/index, uint/bank, uint/program, uint/size, str[] (name) + kPluginBridgeNonRtServerSetCustomData, // uint/size, str[], uint/size, str[], uint/size, str[] (base64, compressed) + kPluginBridgeNonRtServerSetChunkDataFile, // uint/size, str[] (filename, base64 content) + kPluginBridgeNonRtServerSetLatency, // uint kPluginBridgeNonRtServerReady, kPluginBridgeNonRtServerSaved, kPluginBridgeNonRtServerUiClosed, @@ -271,12 +271,12 @@ const char* PluginBridgeNonRtServerOpcode2str(const PluginBridgeNonRtServerOpcod return "kPluginBridgeNonRtServerParameterData1"; case kPluginBridgeNonRtServerParameterData2: return "kPluginBridgeNonRtServerParameterData2"; - case kPluginBridgeNonRtServerParameterRanges1: - return "kPluginBridgeNonRtServerParameterRanges1"; - case kPluginBridgeNonRtServerParameterRanges2: - return "kPluginBridgeNonRtServerParameterRanges2"; + case kPluginBridgeNonRtServerParameterRanges: + return "kPluginBridgeNonRtServerParameterRanges"; case kPluginBridgeNonRtServerParameterValue: return "kPluginBridgeNonRtServerParameterValue"; + case kPluginBridgeNonRtServerParameterValue2: + return "kPluginBridgeNonRtServerParameterValue2"; case kPluginBridgeNonRtServerDefaultValue: return "kPluginBridgeNonRtServerDefaultValue"; case kPluginBridgeNonRtServerCurrentProgram: