diff --git a/source/backend/CarlaPlugin.hpp b/source/backend/CarlaPlugin.hpp index f6535e088..c80a2e1d0 100644 --- a/source/backend/CarlaPlugin.hpp +++ b/source/backend/CarlaPlugin.hpp @@ -688,6 +688,16 @@ public: */ void recreateLatencyBuffers(); + /*! + * TODO. + */ + bool tryLock(); + + /*! + * TODO. + */ + void unlock(); + // ------------------------------------------------------------------- // OSC stuff diff --git a/source/backend/plugin/CarlaPlugin.cpp b/source/backend/plugin/CarlaPlugin.cpp index 21cb5412d..f9f1321de 100644 --- a/source/backend/plugin/CarlaPlugin.cpp +++ b/source/backend/plugin/CarlaPlugin.cpp @@ -24,8 +24,6 @@ //#include -// TODO - save&load options - CARLA_BACKEND_START_NAMESPACE // ------------------------------------------------------------------- @@ -73,19 +71,19 @@ CarlaPlugin::CarlaPlugin(CarlaEngine* const engine, const unsigned int id) { case PROCESS_MODE_SINGLE_CLIENT: case PROCESS_MODE_MULTIPLE_CLIENTS: - kData->ctrlChannel = 0; + CARLA_ASSERT(id < MAX_DEFAULT_PLUGINS); break; case PROCESS_MODE_CONTINUOUS_RACK: - CARLA_ASSERT(id < MAX_RACK_PLUGINS && id < MAX_MIDI_CHANNELS); - - if (id < MAX_RACK_PLUGINS && id < MAX_MIDI_CHANNELS) - kData->ctrlChannel = id; - + CARLA_ASSERT(id < MAX_RACK_PLUGINS); break; case PROCESS_MODE_PATCHBAY: + CARLA_ASSERT(id < MAX_PATCHBAY_PLUGINS); + break; + case PROCESS_MODE_BRIDGE: + CARLA_ASSERT(id == 0); break; } @@ -390,6 +388,10 @@ void CarlaPlugin::getParameterCountInfo(uint32_t* const ins, uint32_t* const out // ------------------------------------------------------------------- // Set data (state) +void CarlaPlugin::prepareForSave() +{ +} + const SaveState& CarlaPlugin::getSaveState() { static SaveState saveState; @@ -448,6 +450,7 @@ const SaveState& CarlaPlugin::getSaveState() saveState.balanceLeft = kData->postProc.balanceLeft; saveState.balanceRight = kData->postProc.balanceRight; saveState.panning = kData->postProc.panning; + saveState.ctrlChannel = kData->ctrlChannel; // ---------------------------- // Current Program @@ -735,6 +738,7 @@ void CarlaPlugin::loadSaveState(const SaveState& saveState) setBalanceLeft(saveState.balanceLeft, true, true); setBalanceRight(saveState.balanceRight, true, true); setPanning(saveState.panning, true, true); + setCtrlChannel(saveState.ctrlChannel, true, true); setActive(saveState.active, true, true); } @@ -820,6 +824,9 @@ void CarlaPlugin::setEnabled(const bool yesNo) void CarlaPlugin::setActive(const bool active, const bool sendOsc, const bool sendCallback) { + if (kData->active == active) + return; + kData->active = active; const float value = active ? 1.0f : 0.0f; @@ -846,6 +853,9 @@ void CarlaPlugin::setDryWet(const float value, const bool sendOsc, const bool se const float fixedValue = carla_fixValue(0.0f, 1.0f, value); + if (kData->postProc.dryWet == fixedValue) + return; + kData->postProc.dryWet = fixedValue; #ifndef BUILD_BRIDGE @@ -870,6 +880,9 @@ void CarlaPlugin::setVolume(const float value, const bool sendOsc, const bool se const float fixedValue = carla_fixValue(0.0f, 1.27f, value); + if (kData->postProc.volume == fixedValue) + return; + kData->postProc.volume = fixedValue; #ifndef BUILD_BRIDGE @@ -894,6 +907,9 @@ void CarlaPlugin::setBalanceLeft(const float value, const bool sendOsc, const bo const float fixedValue = carla_fixValue(-1.0f, 1.0f, value); + if (kData->postProc.balanceLeft == fixedValue) + return; + kData->postProc.balanceLeft = fixedValue; #ifndef BUILD_BRIDGE @@ -918,6 +934,9 @@ void CarlaPlugin::setBalanceRight(const float value, const bool sendOsc, const b const float fixedValue = carla_fixValue(-1.0f, 1.0f, value); + if (kData->postProc.balanceRight == fixedValue) + return; + kData->postProc.balanceRight = fixedValue; #ifndef BUILD_BRIDGE @@ -942,6 +961,9 @@ void CarlaPlugin::setPanning(const float value, const bool sendOsc, const bool s const float fixedValue = carla_fixValue(-1.0f, 1.0f, value); + if (kData->postProc.panning == fixedValue) + return; + kData->postProc.panning = fixedValue; #ifndef BUILD_BRIDGE @@ -962,35 +984,27 @@ 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) { - CARLA_SAFE_ASSERT(kData->engine->getProccessMode() != PROCESS_MODE_CONTINUOUS_RACK); - - if (kData->engine->getProccessMode() == PROCESS_MODE_CONTINUOUS_RACK) + if (kData->ctrlChannel == channel) return; - if (kData->ctrlChannel != channel) - { - { - const ScopedProcessLocker spl(this, true); - kData->ctrlChannel = channel; - } + kData->ctrlChannel = channel; #ifndef BUILD_BRIDGE - const float ctrlf = channel; + const float ctrlf = channel; - if (sendOsc) - kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_CTRL_CHANNEL, ctrlf); + if (sendOsc) + kData->engine->osc_send_control_set_parameter_value(fId, PARAMETER_CTRL_CHANNEL, ctrlf); #else - // unused - (void)sendOsc; + // unused + (void)sendOsc; #endif - if (sendCallback) - kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_CTRL_CHANNEL, 0, channel, nullptr); + if (sendCallback) + kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, PARAMETER_CTRL_CHANNEL, 0, channel, nullptr); #ifndef BUILD_BRIDGE - else if (fHints & PLUGIN_IS_BRIDGE) - osc_send_control(&kData->osc.data, PARAMETER_CTRL_CHANNEL, ctrlf); + else if (fHints & PLUGIN_IS_BRIDGE) + osc_send_control(&kData->osc.data, PARAMETER_CTRL_CHANNEL, ctrlf); #endif - } } // ------------------------------------------------------------------- @@ -1013,6 +1027,10 @@ void CarlaPlugin::setParameterValue(const uint32_t parameterId, const float valu if (sendCallback) kData->engine->callback(CALLBACK_PARAMETER_VALUE_CHANGED, fId, parameterId, 0, value, nullptr); +#ifndef BUILD_BRIDGE + else if (fHints & PLUGIN_IS_BRIDGE) + osc_send_control(&kData->osc.data, parameterId, value); +#endif } void CarlaPlugin::setParameterValueByRIndex(const int32_t rindex, const float value, const bool sendGui, const bool sendOsc, const bool sendCallback) @@ -1024,7 +1042,7 @@ void CarlaPlugin::setParameterValueByRIndex(const int32_t rindex, const float va if (rindex == PARAMETER_NULL) return; if (rindex == PARAMETER_ACTIVE) - return setActive(value > 0.0, sendOsc, sendCallback); + return setActive((value > 0.0f), sendOsc, sendCallback); if (rindex == PARAMETER_DRYWET) return setDryWet(value, sendOsc, sendCallback); if (rindex == PARAMETER_VOLUME) @@ -1065,6 +1083,10 @@ void CarlaPlugin::setParameterMidiChannel(const uint32_t parameterId, uint8_t ch if (sendCallback) kData->engine->callback(CALLBACK_PARAMETER_MIDI_CHANNEL_CHANGED, fId, parameterId, channel, 0.0f, nullptr); +#ifndef BUILD_BRIDGE + else if (fHints & PLUGIN_IS_BRIDGE) + {} // TODO +#endif } void CarlaPlugin::setParameterMidiCC(const uint32_t parameterId, int16_t cc, const bool sendOsc, const bool sendCallback) @@ -1087,16 +1109,20 @@ void CarlaPlugin::setParameterMidiCC(const uint32_t parameterId, int16_t cc, con if (sendCallback) kData->engine->callback(CALLBACK_PARAMETER_MIDI_CC_CHANGED, fId, parameterId, cc, 0.0f, nullptr); +#ifndef BUILD_BRIDGE + else if (fHints & PLUGIN_IS_BRIDGE) + {} // TODO +#endif } void CarlaPlugin::setCustomData(const char* const type, const char* const key, const char* const value, const bool sendGui) { - CARLA_ASSERT(type != nullptr); - CARLA_ASSERT(key != nullptr); + CARLA_ASSERT(type != nullptr); + CARLA_ASSERT(key != nullptr); CARLA_ASSERT(value != nullptr); if (type == nullptr) - return carla_stderr2("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is invalid", type, key, value, bool2str(sendGui)); + return carla_stderr2("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - type is null", type, key, value, bool2str(sendGui)); if (key == nullptr) return carla_stderr2("CarlaPlugin::setCustomData(\"%s\", \"%s\", \"%s\", %s) - key is null", type, key, value, bool2str(sendGui)); @@ -1291,10 +1317,6 @@ void CarlaPlugin::reloadPrograms(const bool) { } -void CarlaPlugin::prepareForSave() -{ -} - // ------------------------------------------------------------------- // Plugin processing @@ -1312,13 +1334,18 @@ void CarlaPlugin::sampleRateChanged(const double) void CarlaPlugin::recreateLatencyBuffers() { -#if 0 - if (kData->latencyBuffers) + if (kData->latencyBuffers != nullptr) { for (uint32_t i=0; i < kData->audioIn.count; i++) - delete[] kData->latencyBuffers[i]; + { + CARLA_ASSERT(kData->latencyBuffers[i] != nullptr); + + if (kData->latencyBuffers[i] != nullptr) + delete[] kData->latencyBuffers[i]; + } delete[] kData->latencyBuffers; + kData->latencyBuffers = nullptr; } if (kData->audioIn.count > 0 && kData->latency > 0) @@ -1326,11 +1353,21 @@ void CarlaPlugin::recreateLatencyBuffers() kData->latencyBuffers = new float*[kData->audioIn.count]; for (uint32_t i=0; i < kData->audioIn.count; i++) + { kData->latencyBuffers[i] = new float[kData->latency]; + carla_zeroFloat(kData->latencyBuffers[i], kData->latency); + } } - else - kData->latencyBuffers = nullptr; -#endif +} + +bool CarlaPlugin::tryLock() +{ + return kData->mutex.tryLock(); +} + +void CarlaPlugin::unlock() +{ + kData->mutex.unlock(); } // ------------------------------------------------------------------- diff --git a/source/backend/plugin/CarlaPluginInternal.hpp b/source/backend/plugin/CarlaPluginInternal.hpp index d0a11e78c..5bb1fda76 100644 --- a/source/backend/plugin/CarlaPluginInternal.hpp +++ b/source/backend/plugin/CarlaPluginInternal.hpp @@ -548,11 +548,11 @@ struct CarlaPluginProtectedData { activeBefore(false), needsReset(false), lib(nullptr), - ctrlChannel(-1), + ctrlChannel(0), extraHints(0x0), latency(0), latencyBuffers(nullptr), - osc(engine_, plugin) {} + osc(engine, plugin) {} CarlaPluginProtectedData() = delete; CarlaPluginProtectedData(CarlaPluginProtectedData&) = delete; diff --git a/source/carla_shared.py b/source/carla_shared.py index dcd118f91..0d123aeaa 100644 --- a/source/carla_shared.py +++ b/source/carla_shared.py @@ -1437,7 +1437,7 @@ class PluginEdit(QDialog): self.fCurrentProgram = -1 self.fCurrentMidiProgram = -1 self.fCurrentStateFilename = None - self.fControlChannel = pluginId+1 if Carla.processMode == PROCESS_MODE_CONTINUOUS_RACK else 1 + self.fControlChannel = 0 self.fParameterCount = 0 self.fParameterList = [] # (type, id, widget) @@ -1465,7 +1465,7 @@ class PluginEdit(QDialog): self.ui.keyboard.setMode(self.ui.keyboard.HORIZONTAL) self.ui.keyboard.setOctaves(6) - self.ui.sb_ctrl_channel.setValue(self.fControlChannel) + self.ui.sb_ctrl_channel.setValue(self.fControlChannel+1) self.ui.scrollArea.ensureVisible(self.ui.keyboard.width() / 5, 0) self.ui.scrollArea.setEnabled(False) @@ -1794,7 +1794,7 @@ class PluginEdit(QDialog): mpName = cString(mpData['name']) mpName = mpName[:40] + (mpName[40:] and "...") - self.ui.cb_midi_programs.addItem("%03i:%03i - %s" % (mpBank, mpProg, mpName)) + self.ui.cb_midi_programs.addItem("%03i:%03i - %s" % (mpBank+1, mpProg+1, mpName)) self.fCurrentMidiProgram = Carla.host.get_current_midi_program_index(self.fPluginId) self.ui.cb_midi_programs.setCurrentIndex(self.fCurrentMidiProgram) @@ -1814,6 +1814,7 @@ class PluginEdit(QDialog): if self.ui.cb_programs.count() > 0: pIndex = self.ui.cb_programs.currentIndex() pName = cString(Carla.host.get_program_name(self.fPluginId, pIndex)) + pName = pName[:40] + (pName[40:] and "...") self.ui.cb_programs.setItemText(pIndex, pName) # Update current midi program text @@ -1822,8 +1823,9 @@ class PluginEdit(QDialog): mpData = Carla.host.get_midi_program_data(self.fPluginId, mpIndex) mpBank = int(mpData['bank']) mpProg = int(mpData['program']) - mpLabel = cString(mpData['name']) - self.ui.cb_midi_programs.setItemText(mpIndex, "%03i:%03i - %s" % (mpBank, mpProg, mpLabel)) + mpName = cString(mpData['name']) + mpName = mpName[:40] + (mpName[40:] and "...") + self.ui.cb_midi_programs.setItemText(mpIndex, "%03i:%03i - %s" % (mpBank+1, mpProg+1, mpName)) # Update all parameter values for paramType, paramId, paramWidget in self.fParameterList: diff --git a/source/utils/CarlaStateUtils.hpp b/source/utils/CarlaStateUtils.hpp index cf947884e..406e81c81 100644 --- a/source/utils/CarlaStateUtils.hpp +++ b/source/utils/CarlaStateUtils.hpp @@ -83,12 +83,13 @@ struct SaveState { const char* binary; long uniqueID; - bool active; - double dryWet; - double volume; - double balanceLeft; - double balanceRight; - double panning; + bool active; + float dryWet; + float volume; + float balanceLeft; + float balanceRight; + float panning; + int8_t ctrlChannel; int32_t currentProgramIndex; const char* currentProgramName; @@ -106,11 +107,12 @@ struct SaveState { binary(nullptr), uniqueID(0), active(false), - dryWet(1.0), - volume(1.0), - balanceLeft(-1.0), - balanceRight(1.0), - panning(0.0), + dryWet(1.0f), + volume(1.0f), + balanceLeft(-1.0f), + balanceRight(1.0f), + panning(0.0f), + ctrlChannel(0), currentProgramIndex(-1), currentProgramName(nullptr), currentMidiBank(-1), @@ -162,11 +164,12 @@ struct SaveState { uniqueID = 0; active = false; - dryWet = 1.0; - volume = 1.0; - balanceLeft = -1.0; - balanceRight = 1.0; - panning = 0.0; + dryWet = 1.0f; + volume = 1.0f; + balanceLeft = -1.0f; + balanceRight = 1.0f; + panning = 0.0f; + ctrlChannel = 0; currentProgramIndex = -1; currentMidiBank = -1; currentMidiProgram = -1; @@ -299,6 +302,13 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) float value = text.toFloat(&ok); if (ok) saveState.panning = value; } + else if (tag.compare("ControlChannel", Qt::CaseInsensitive) == 0) + { + bool ok; + short value = text.toShort(&ok); + if (ok && value < INT8_MAX) + saveState.ctrlChannel = static_cast(value-1); + } // ---------------------------------------------- // Program (current) @@ -307,7 +317,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) { bool ok; int value = text.toInt(&ok); - if (ok) saveState.currentProgramIndex = value; + if (ok) saveState.currentProgramIndex = value-1; } else if (tag.compare("CurrentProgramName", Qt::CaseInsensitive) == 0) { @@ -321,13 +331,13 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) { bool ok; int value = text.toInt(&ok); - if (ok) saveState.currentMidiBank = value; + if (ok) saveState.currentMidiBank = value-1; } else if (tag.compare("CurrentMidiProgram", Qt::CaseInsensitive) == 0) { bool ok; int value = text.toInt(&ok); - if (ok) saveState.currentMidiProgram = value; + if (ok) saveState.currentMidiProgram = value-1; } // ---------------------------------------------- @@ -367,7 +377,7 @@ const SaveState& getSaveStateDictFromXML(const QDomNode& xmlNode) else if (pTag.compare("MidiChannel", Qt::CaseInsensitive) == 0) { bool ok; - uint channel = pText.toUInt(&ok); + ushort channel = pText.toUShort(&ok); if (ok && channel < 16) stateParameter->midiChannel = static_cast(channel); } @@ -499,6 +509,8 @@ QString getXMLFromSaveState(const SaveState& saveState) if (saveState.panning != 0.0f) data += QString(" %1\n").arg(saveState.panning); + data += QString(" %1\n").arg(saveState.ctrlChannel+1); + content += data; } @@ -530,7 +542,7 @@ QString getXMLFromSaveState(const SaveState& saveState) if (saveState.currentProgramIndex >= 0) { QString program("\n"); - program += QString(" %1\n").arg(saveState.currentProgramIndex); + program += QString(" %1\n").arg(saveState.currentProgramIndex+1); program += QString(" %1\n").arg(xmlSafeString(saveState.currentProgramName, true)); content += program; @@ -539,8 +551,8 @@ QString getXMLFromSaveState(const SaveState& saveState) if (saveState.currentMidiBank >= 0 && saveState.currentMidiProgram >= 0) { QString midiProgram("\n"); - midiProgram += QString(" %1\n").arg(saveState.currentMidiBank); - midiProgram += QString(" %1\n").arg(saveState.currentMidiProgram); + midiProgram += QString(" %1\n").arg(saveState.currentMidiBank+1); + midiProgram += QString(" %1\n").arg(saveState.currentMidiProgram+1); content += midiProgram; }