Cleanup
[carla.git] / source / backend / plugin / CarlaPluginInternal.cpp
blob3f7bbd2e979808158b772e2d48467f9aa8677113
1 /*
2 * Carla Plugin
3 * Copyright (C) 2011-2020 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #include "CarlaPluginInternal.hpp"
19 #include "CarlaEngine.hpp"
21 #include "CarlaLibCounter.hpp"
22 #include "CarlaMathUtils.hpp"
23 #include "CarlaMIDI.h"
25 CARLA_BACKEND_START_NAMESPACE
27 // -------------------------------------------------------------------
28 // Fallback data
30 static const MidiProgramData kMidiProgramDataNull = { 0, 0, nullptr };
31 static /* */ CustomData kCustomDataFallbackNC = { nullptr, nullptr, nullptr };
33 // -----------------------------------------------------------------------
34 // PluginAudioData
36 PluginAudioData::PluginAudioData() noexcept
37 : count(0),
38 ports(nullptr) {}
40 PluginAudioData::~PluginAudioData() noexcept
42 CARLA_SAFE_ASSERT_INT(count == 0, count);
43 CARLA_SAFE_ASSERT(ports == nullptr);
46 void PluginAudioData::createNew(const uint32_t newCount)
48 CARLA_SAFE_ASSERT_INT(count == 0, count);
49 CARLA_SAFE_ASSERT_RETURN(ports == nullptr,);
50 CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
52 ports = new PluginAudioPort[newCount];
53 carla_zeroStructs(ports, newCount);
55 count = newCount;
58 void PluginAudioData::clear() noexcept
60 if (ports != nullptr)
62 for (uint32_t i=0; i < count; ++i)
64 if (ports[i].port != nullptr)
66 delete ports[i].port;
67 ports[i].port = nullptr;
71 delete[] ports;
72 ports = nullptr;
75 count = 0;
78 void PluginAudioData::initBuffers() const noexcept
80 for (uint32_t i=0; i < count; ++i)
82 if (ports[i].port != nullptr)
83 ports[i].port->initBuffer();
87 // -----------------------------------------------------------------------
88 // PluginCVData
90 PluginCVData::PluginCVData() noexcept
91 : count(0),
92 ports(nullptr) {}
94 PluginCVData::~PluginCVData() noexcept
96 CARLA_SAFE_ASSERT_INT(count == 0, count);
97 CARLA_SAFE_ASSERT(ports == nullptr);
100 void PluginCVData::createNew(const uint32_t newCount)
102 CARLA_SAFE_ASSERT_INT(count == 0, count);
103 CARLA_SAFE_ASSERT_RETURN(ports == nullptr,);
104 CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
106 ports = new PluginCVPort[newCount];
107 carla_zeroStructs(ports, newCount);
109 count = newCount;
112 void PluginCVData::clear() noexcept
114 if (ports != nullptr)
116 for (uint32_t i=0; i < count; ++i)
118 if (ports[i].port != nullptr)
120 delete ports[i].port;
121 ports[i].port = nullptr;
125 delete[] ports;
126 ports = nullptr;
129 count = 0;
132 void PluginCVData::initBuffers() const noexcept
134 for (uint32_t i=0; i < count; ++i)
136 if (ports[i].port != nullptr)
137 ports[i].port->initBuffer();
141 // -----------------------------------------------------------------------
142 // PluginEventData
144 PluginEventData::PluginEventData() noexcept
145 : portIn(nullptr),
146 portOut(nullptr)
147 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
148 , cvSourcePorts(nullptr)
149 #endif
153 PluginEventData::~PluginEventData() noexcept
155 CARLA_SAFE_ASSERT(portIn == nullptr);
156 CARLA_SAFE_ASSERT(portOut == nullptr);
157 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
158 CARLA_SAFE_ASSERT(cvSourcePorts == nullptr);
159 #endif
162 void PluginEventData::clear() noexcept
164 if (portIn != nullptr)
166 delete portIn;
167 portIn = nullptr;
170 if (portOut != nullptr)
172 delete portOut;
173 portOut = nullptr;
176 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
177 if (cvSourcePorts != nullptr)
179 cvSourcePorts->cleanup();
180 cvSourcePorts = nullptr;
182 #endif
185 void PluginEventData::initBuffers() const noexcept
187 if (portIn != nullptr)
188 portIn->initBuffer();
190 if (portOut != nullptr)
191 portOut->initBuffer();
194 // -----------------------------------------------------------------------
195 // PluginParameterData
197 PluginParameterData::PluginParameterData() noexcept
198 : count(0),
199 data(nullptr),
200 ranges(nullptr),
201 special(nullptr) {}
203 PluginParameterData::~PluginParameterData() noexcept
205 CARLA_SAFE_ASSERT_INT(count == 0, count);
206 CARLA_SAFE_ASSERT(data == nullptr);
207 CARLA_SAFE_ASSERT(ranges == nullptr);
208 CARLA_SAFE_ASSERT(special == nullptr);
211 void PluginParameterData::createNew(const uint32_t newCount, const bool withSpecial)
213 CARLA_SAFE_ASSERT_INT(count == 0, count);
214 CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
215 CARLA_SAFE_ASSERT_RETURN(ranges == nullptr,);
216 CARLA_SAFE_ASSERT_RETURN(special == nullptr,);
217 CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
219 data = new ParameterData[newCount];
220 carla_zeroStructs(data, newCount);
222 for (uint32_t i=0; i < newCount; ++i)
224 data[i].index = PARAMETER_NULL;
225 data[i].rindex = PARAMETER_NULL;
226 data[i].mappedControlIndex = CONTROL_INDEX_NONE;
227 data[i].mappedMinimum = -1.0f;
228 data[i].mappedMaximum = 1.0f;
231 ranges = new ParameterRanges[newCount];
232 carla_zeroStructs(ranges, newCount);
234 if (withSpecial)
236 special = new SpecialParameterType[newCount];
237 carla_zeroStructs(special, newCount);
240 count = newCount;
243 void PluginParameterData::clear() noexcept
245 if (data != nullptr)
247 delete[] data;
248 data = nullptr;
251 if (ranges != nullptr)
253 delete[] ranges;
254 ranges = nullptr;
257 if (special != nullptr)
259 delete[] special;
260 special = nullptr;
263 count = 0;
266 float PluginParameterData::getFixedValue(const uint32_t parameterId, float value) const noexcept
268 CARLA_SAFE_ASSERT_RETURN(parameterId < count, 0.0f);
270 const uint paramHints (data[parameterId].hints);
271 const ParameterRanges& paramRanges(ranges[parameterId]);
273 // if boolean, return either min or max
274 if (paramHints & PARAMETER_IS_BOOLEAN)
276 const float middlePoint = paramRanges.min + (paramRanges.max-paramRanges.min)/2.0f;
277 return value >= middlePoint ? paramRanges.max : paramRanges.min;
280 // if integer, round first
281 if (paramHints & PARAMETER_IS_INTEGER)
282 return paramRanges.getFixedValue(std::round(value));
284 // normal mode
285 return paramRanges.getFixedValue(value);
288 // copied from ParameterRanges::getUnnormalizedValue
289 static float _getUnnormalizedValue(const float min, const float max, const float value) noexcept
291 if (value <= 0.0f)
292 return min;
293 if (value >= 1.0f)
294 return max;
296 return value * (max - min) + min;
299 // copied from ParameterRanges::getUnnormalizedLogValue
300 static float _getUnnormalizedLogValue(const float min, const float max, const float value) noexcept
302 if (value <= 0.0f)
303 return min;
304 if (value >= 1.0f)
305 return max;
307 float rmin = min;
309 if (std::abs(min) < std::numeric_limits<float>::epsilon())
310 rmin = 0.00001f;
312 return rmin * std::pow(max/rmin, value);
315 float PluginParameterData::getFinalUnnormalizedValue(const uint32_t parameterId,
316 const float normalizedValue) const noexcept
318 float min, max, value;
320 if (data[parameterId].mappedControlIndex != CONTROL_INDEX_CV
321 && (data[parameterId].hints & PARAMETER_MAPPED_RANGES_SET) != 0x0)
323 min = data[parameterId].mappedMinimum;
324 max = data[parameterId].mappedMaximum;
326 else
328 min = ranges[parameterId].min;
329 max = ranges[parameterId].max;
332 if (data[parameterId].hints & PARAMETER_IS_BOOLEAN)
334 value = (normalizedValue < 0.5f) ? min : max;
336 else
338 if (data[parameterId].hints & PARAMETER_IS_LOGARITHMIC)
339 value = _getUnnormalizedLogValue(min, max, normalizedValue);
340 else
341 value = _getUnnormalizedValue(min, max, normalizedValue);
343 if (data[parameterId].hints & PARAMETER_IS_INTEGER)
344 value = std::rint(value);
347 return value;
350 float PluginParameterData::getFinalValueWithMidiDelta(const uint32_t parameterId,
351 float value, int8_t delta) const noexcept
353 if (delta < 0)
354 return value;
355 if (data[parameterId].mappedControlIndex <= 0 || data[parameterId].mappedControlIndex >= MAX_MIDI_CONTROL)
356 return value;
358 float min, max;
360 if ((data[parameterId].hints & PARAMETER_MAPPED_RANGES_SET) != 0x0)
362 min = data[parameterId].mappedMinimum;
363 max = data[parameterId].mappedMaximum;
365 else
367 min = ranges[parameterId].min;
368 max = ranges[parameterId].max;
371 if (data[parameterId].hints & PARAMETER_IS_BOOLEAN)
373 value = delta > 63 ? min : max;
375 else
377 if (data[parameterId].hints & PARAMETER_IS_INTEGER)
379 if (delta > 63)
380 value += delta - 128.0f;
381 else
382 value += delta;
384 else
386 if (delta > 63)
387 delta = static_cast<int8_t>(delta - 128);
389 value += (max - min) * (static_cast<float>(delta) / 127.0f);
392 if (value < min)
393 value = min;
394 else if (value > max)
395 value = max;
398 return value;
401 // -----------------------------------------------------------------------
402 // PluginProgramData
404 PluginProgramData::PluginProgramData() noexcept
405 : count(0),
406 current(-1),
407 names(nullptr) {}
409 PluginProgramData::~PluginProgramData() noexcept
411 CARLA_SAFE_ASSERT_INT(count == 0, count);
412 CARLA_SAFE_ASSERT_INT(current == -1, current);
413 CARLA_SAFE_ASSERT(names == nullptr);
416 void PluginProgramData::createNew(const uint32_t newCount)
418 CARLA_SAFE_ASSERT_INT(count == 0, count);
419 CARLA_SAFE_ASSERT_INT(current == -1, current);
420 CARLA_SAFE_ASSERT_RETURN(names == nullptr,);
421 CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
423 names = new ProgramName[newCount];
424 carla_zeroStructs(names, newCount);
426 count = newCount;
427 current = -1;
430 void PluginProgramData::clear() noexcept
432 if (names != nullptr)
434 for (uint32_t i=0; i < count; ++i)
436 if (names[i] != nullptr)
438 delete[] names[i];
439 names[i] = nullptr;
443 delete[] names;
444 names = nullptr;
447 count = 0;
448 current = -1;
451 // -----------------------------------------------------------------------
452 // PluginMidiProgramData
454 PluginMidiProgramData::PluginMidiProgramData() noexcept
455 : count(0),
456 current(-1),
457 data(nullptr) {}
459 PluginMidiProgramData::~PluginMidiProgramData() noexcept
461 CARLA_SAFE_ASSERT_INT(count == 0, count);
462 CARLA_SAFE_ASSERT_INT(current == -1, current);
463 CARLA_SAFE_ASSERT(data == nullptr);
466 void PluginMidiProgramData::createNew(const uint32_t newCount)
468 CARLA_SAFE_ASSERT_INT(count == 0, count);
469 CARLA_SAFE_ASSERT_INT(current == -1, current);
470 CARLA_SAFE_ASSERT_RETURN(data == nullptr,);
471 CARLA_SAFE_ASSERT_RETURN(newCount > 0,);
473 data = new MidiProgramData[newCount];
474 carla_zeroStructs(data, newCount);
476 count = newCount;
477 current = -1;
480 void PluginMidiProgramData::clear() noexcept
482 if (data != nullptr)
484 for (uint32_t i=0; i < count; ++i)
486 if (data[i].name != nullptr)
488 delete[] data[i].name;
489 data[i].name = nullptr;
493 delete[] data;
494 data = nullptr;
497 count = 0;
498 current = -1;
501 const MidiProgramData& PluginMidiProgramData::getCurrent() const noexcept
503 CARLA_SAFE_ASSERT_RETURN(current >= 0 && current < static_cast<int32_t>(count), kMidiProgramDataNull);
504 return data[current];
507 // -----------------------------------------------------------------------
508 // ProtectedData::ExternalNotes
510 CarlaPlugin::ProtectedData::ExternalNotes::ExternalNotes() noexcept
511 : mutex(),
512 dataPool("CarlaPlugin::ProtectedData::ExternalNotes", 32, 152),
513 data(dataPool) {}
515 CarlaPlugin::ProtectedData::ExternalNotes::~ExternalNotes() noexcept
517 clear();
520 void CarlaPlugin::ProtectedData::ExternalNotes::appendNonRT(const ExternalMidiNote& note) noexcept
522 mutex.lock();
523 data.append_sleepy(note);
524 mutex.unlock();
527 void CarlaPlugin::ProtectedData::ExternalNotes::clear() noexcept
529 mutex.lock();
530 data.clear();
531 mutex.unlock();
534 // -----------------------------------------------------------------------
535 // ProtectedData::Latency
537 CarlaPlugin::ProtectedData::Latency::Latency() noexcept
538 #ifdef BUILD_BRIDGE
539 : frames(0) {}
540 #else
541 : frames(0),
542 channels(0),
543 buffers(nullptr) {}
544 #endif
546 #ifndef BUILD_BRIDGE
547 CarlaPlugin::ProtectedData::Latency::~Latency() noexcept
549 clearBuffers();
552 void CarlaPlugin::ProtectedData::Latency::clearBuffers() noexcept
554 if (buffers != nullptr)
556 for (uint32_t i=0; i < channels; ++i)
558 CARLA_SAFE_ASSERT_CONTINUE(buffers[i] != nullptr);
560 delete[] buffers[i];
561 buffers[i] = nullptr;
564 delete[] buffers;
565 buffers = nullptr;
568 channels = 0;
569 frames = 0;
572 void CarlaPlugin::ProtectedData::Latency::recreateBuffers(const uint32_t newChannels, const uint32_t newFrames)
574 CARLA_SAFE_ASSERT_RETURN(channels != newChannels || frames != newFrames,);
576 const bool retrieveOldBuffer = (channels == newChannels && channels > 0 && frames > 0 && newFrames > 0);
577 float** const oldBuffers = buffers;
578 const uint32_t oldFrames = frames;
580 channels = newChannels;
581 frames = newFrames;
583 if (channels > 0 && frames > 0)
585 buffers = new float*[channels];
587 for (uint32_t i=0; i < channels; ++i)
589 buffers[i] = new float[frames];
591 if (retrieveOldBuffer)
593 if (oldFrames > frames)
595 const uint32_t diff = oldFrames - frames;
596 carla_copyFloats(buffers[i], oldBuffers[i] + diff, frames);
598 else
600 const uint32_t diff = frames - oldFrames;
601 carla_zeroFloats(buffers[i], diff);
602 carla_copyFloats(buffers[i] + diff, oldBuffers[i], oldFrames);
605 else
607 carla_zeroFloats(buffers[i], frames);
611 else
613 buffers = nullptr;
616 // delete old buffer
617 if (oldBuffers != nullptr)
619 for (uint32_t i=0; i < channels; ++i)
621 CARLA_SAFE_ASSERT_CONTINUE(oldBuffers[i] != nullptr);
623 delete[] oldBuffers[i];
624 oldBuffers[i] = nullptr;
627 delete[] oldBuffers;
630 #endif
632 // -----------------------------------------------------------------------
633 // ProtectedData::PostRtEvents
635 CarlaPlugin::ProtectedData::PostRtEvents::PostRtEvents() noexcept
636 : dataPool("CarlaPlugin::ProtectedData::PostRtEvents", 512, 512),
637 data(dataPool),
638 dataPendingRT(dataPool),
639 dataMutex(),
640 dataPendingMutex(),
641 poolMutex() {}
643 CarlaPlugin::ProtectedData::PostRtEvents::~PostRtEvents() noexcept
645 const CarlaMutexLocker cml1(dataMutex);
646 const CarlaMutexLocker cml2(dataPendingMutex);
647 const CarlaMutexLocker cml3(poolMutex);
649 data.clear();
650 dataPendingRT.clear();
653 void CarlaPlugin::ProtectedData::PostRtEvents::appendRT(const PluginPostRtEvent& e) noexcept
655 CARLA_SAFE_ASSERT_INT_RETURN(dataPendingMutex.tryLock(), e.type,);
657 const CarlaMutexLocker cml(poolMutex);
658 dataPendingRT.append(e);
660 dataPendingMutex.unlock();
663 void CarlaPlugin::ProtectedData::PostRtEvents::trySplice() noexcept
665 const CarlaMutexTryLocker cmtl(dataPendingMutex);
667 if (cmtl.wasLocked() && dataPendingRT.isNotEmpty() && dataMutex.tryLock())
670 const CarlaMutexLocker cml(poolMutex);
671 dataPendingRT.moveTo(data, true);
673 dataMutex.unlock();
677 // -----------------------------------------------------------------------
678 // ProtectedData::PostUiEvents
680 CarlaPlugin::ProtectedData::PostUiEvents::PostUiEvents() noexcept
681 : mutex(),
682 data() {}
684 CarlaPlugin::ProtectedData::PostUiEvents::~PostUiEvents() noexcept
686 clear();
689 void CarlaPlugin::ProtectedData::PostUiEvents::append(const PluginPostRtEvent& e) noexcept
691 mutex.lock();
692 data.append(e);
693 mutex.unlock();
696 void CarlaPlugin::ProtectedData::PostUiEvents::clear() noexcept
698 mutex.lock();
699 data.clear();
700 mutex.unlock();
703 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
704 // -----------------------------------------------------------------------
705 // ProtectedData::PostProc
707 CarlaPlugin::ProtectedData::PostProc::PostProc() noexcept
708 : dryWet(1.0f),
709 volume(1.0f),
710 balanceLeft(-1.0f),
711 balanceRight(1.0f),
712 panning(0.0f),
713 extraBuffer(nullptr) {}
714 #endif
716 // -----------------------------------------------------------------------
718 CarlaPlugin::ProtectedData::ProtectedData(CarlaEngine* const eng, const uint idx) noexcept
719 : engine(eng),
720 client(nullptr),
721 id(idx),
722 hints(0x0),
723 options(0x0),
724 nodeId(0),
725 active(false),
726 enabled(false),
727 needsReset(false),
728 engineBridged(eng->getType() == kEngineTypeBridge),
729 enginePlugin(eng->getType() == kEngineTypePlugin),
730 lib(nullptr),
731 uiLib(nullptr),
732 ctrlChannel(0),
733 extraHints(0x0),
734 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
735 midiLearnParameterIndex(-1),
736 transientTryCounter(0),
737 transientFirstTry(true),
738 #endif
739 name(nullptr),
740 filename(nullptr),
741 iconName(nullptr),
742 audioIn(),
743 audioOut(),
744 cvIn(),
745 cvOut(),
746 event(),
747 param(),
748 prog(),
749 midiprog(),
750 custom(),
751 masterMutex(),
752 singleMutex(),
753 stateSave(),
754 uiTitle(),
755 extNotes(),
756 latency(),
757 postRtEvents(),
758 postUiEvents()
759 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
760 , postProc()
761 #endif
764 CarlaPlugin::ProtectedData::~ProtectedData() noexcept
766 CARLA_SAFE_ASSERT(! (active && needsReset));
767 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
768 CARLA_SAFE_ASSERT(transientTryCounter == 0);
769 #endif
772 // mutex MUST have been locked before
773 const bool lockMaster(masterMutex.tryLock());
774 const bool lockSingle(singleMutex.tryLock());
775 CARLA_SAFE_ASSERT(! lockMaster);
776 CARLA_SAFE_ASSERT(! lockSingle);
779 if (client != nullptr)
781 if (client->isActive())
783 // must not happen
784 carla_safe_assert("client->isActive()", __FILE__, __LINE__);
785 client->deactivate(true);
788 clearBuffers();
790 delete client;
791 client = nullptr;
794 if (name != nullptr)
796 delete[] name;
797 name = nullptr;
800 if (filename != nullptr)
802 delete[] filename;
803 filename = nullptr;
806 if (iconName != nullptr)
808 delete[] iconName;
809 iconName = nullptr;
812 for (LinkedList<CustomData>::Itenerator it = custom.begin2(); it.valid(); it.next())
814 CustomData& customData(it.getValue(kCustomDataFallbackNC));
815 //CARLA_SAFE_ASSERT_CONTINUE(customData.isValid());
817 if (customData.type != nullptr)
819 delete[] customData.type;
820 customData.type = nullptr;
822 else
823 carla_safe_assert("customData.type != nullptr", __FILE__, __LINE__);
825 if (customData.key != nullptr)
827 delete[] customData.key;
828 customData.key = nullptr;
830 else
831 carla_safe_assert("customData.key != nullptr", __FILE__, __LINE__);
833 if (customData.value != nullptr)
835 delete[] customData.value;
836 customData.value = nullptr;
838 else
839 carla_safe_assert("customData.value != nullptr", __FILE__, __LINE__);
842 prog.clear();
843 midiprog.clear();
844 custom.clear();
846 // MUST have been locked before
847 masterMutex.unlock();
848 singleMutex.unlock();
850 CARLA_SAFE_ASSERT(uiLib == nullptr);
852 if (lib != nullptr)
853 libClose();
856 // -----------------------------------------------------------------------
857 // Buffer functions
859 void CarlaPlugin::ProtectedData::clearBuffers() noexcept
861 audioIn.clear();
862 audioOut.clear();
863 cvIn.clear();
864 cvOut.clear();
865 param.clear();
866 event.clear();
867 #ifndef BUILD_BRIDGE
868 latency.clearBuffers();
869 #endif
870 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
871 if (postProc.extraBuffer != nullptr)
873 delete[] postProc.extraBuffer;
874 postProc.extraBuffer = nullptr;
876 #endif
879 // -----------------------------------------------------------------------
880 // Post-poned events
882 void CarlaPlugin::ProtectedData::postponeRtEvent(const PluginPostRtEvent& rtEvent) noexcept
884 CARLA_SAFE_ASSERT_RETURN(rtEvent.type != kPluginPostRtEventNull,);
886 postRtEvents.appendRT(rtEvent);
889 void CarlaPlugin::ProtectedData::postponeParameterChangeRtEvent(const bool sendCallbackLater,
890 const int32_t index,
891 const float value) noexcept
893 PluginPostRtEvent rtEvent = { kPluginPostRtEventParameterChange, sendCallbackLater, {} };
894 rtEvent.parameter.index = index;
895 rtEvent.parameter.value = value;
897 postRtEvents.appendRT(rtEvent);
900 void CarlaPlugin::ProtectedData::postponeProgramChangeRtEvent(const bool sendCallbackLater,
901 const uint32_t index) noexcept
903 PluginPostRtEvent rtEvent = { kPluginPostRtEventProgramChange, sendCallbackLater, {} };
904 rtEvent.program.index = index;
906 postRtEvents.appendRT(rtEvent);
909 void CarlaPlugin::ProtectedData::postponeMidiProgramChangeRtEvent(const bool sendCallbackLater,
910 const uint32_t index) noexcept
912 PluginPostRtEvent rtEvent = { kPluginPostRtEventMidiProgramChange, sendCallbackLater, {} };
913 rtEvent.program.index = index;
915 postRtEvents.appendRT(rtEvent);
918 void CarlaPlugin::ProtectedData::postponeNoteOnRtEvent(const bool sendCallbackLater,
919 const uint8_t channel,
920 const uint8_t note,
921 const uint8_t velocity) noexcept
923 PluginPostRtEvent rtEvent = { kPluginPostRtEventNoteOn, sendCallbackLater, {} };
924 rtEvent.note.channel = channel;
925 rtEvent.note.note = note;
926 rtEvent.note.velocity = velocity;
928 postRtEvents.appendRT(rtEvent);
930 void CarlaPlugin::ProtectedData::postponeNoteOffRtEvent(const bool sendCallbackLater,
931 const uint8_t channel,
932 const uint8_t note) noexcept
934 PluginPostRtEvent rtEvent = { kPluginPostRtEventNoteOff, sendCallbackLater, {} };
935 rtEvent.note.channel = channel;
936 rtEvent.note.note = note;
938 postRtEvents.appendRT(rtEvent);
940 void CarlaPlugin::ProtectedData::postponeMidiLearnRtEvent(const bool sendCallbackLater,
941 const uint32_t parameter,
942 const uint8_t cc,
943 const uint8_t channel) noexcept
945 PluginPostRtEvent rtEvent = { kPluginPostRtEventMidiLearn, sendCallbackLater, {} };
946 rtEvent.midiLearn.parameter = parameter;
947 rtEvent.midiLearn.cc = cc;
948 rtEvent.midiLearn.channel = channel;
950 postRtEvents.appendRT(rtEvent);
953 // -----------------------------------------------------------------------
954 // Library functions
956 static LibCounter sLibCounter;
958 const char* CarlaPlugin::ProtectedData::libError(const char* const fname) noexcept
960 return lib_error(fname);
963 bool CarlaPlugin::ProtectedData::libOpen(const char* const fname) noexcept
965 lib = sLibCounter.open(fname);
966 return (lib != nullptr);
969 bool CarlaPlugin::ProtectedData::libClose() noexcept
971 const bool ret = sLibCounter.close(lib);
972 lib = nullptr;
973 return ret;
976 void CarlaPlugin::ProtectedData::setCanDeleteLib(const bool canDelete) noexcept
978 sLibCounter.setCanDelete(lib, canDelete);
981 bool CarlaPlugin::ProtectedData::uiLibOpen(const char* const fname, const bool canDelete) noexcept
983 uiLib = sLibCounter.open(fname, canDelete);
984 return (uiLib != nullptr);
987 bool CarlaPlugin::ProtectedData::uiLibClose() noexcept
989 const bool ret = sLibCounter.close(uiLib);
990 uiLib = nullptr;
991 return ret;
994 // -----------------------------------------------------------------------
996 #ifndef BUILD_BRIDGE_ALTERNATIVE_ARCH
997 void CarlaPlugin::ProtectedData::tryTransient() noexcept
999 if (engine->getOptions().frontendWinId != 0)
1000 transientTryCounter = 1;
1002 #endif
1004 void CarlaPlugin::ProtectedData::updateParameterValues(CarlaPlugin* const plugin,
1005 const bool sendCallback,
1006 const bool sendOsc,
1007 const bool useDefault) noexcept
1009 CARLA_SAFE_ASSERT_RETURN(sendOsc || sendCallback || useDefault,);
1011 for (uint32_t i=0; i < param.count; ++i)
1013 const float value(param.ranges[i].getFixedValue(plugin->getParameterValue(i)));
1015 if (useDefault)
1016 param.ranges[i].def = value;
1018 if (useDefault) {
1019 engine->callback(sendCallback, sendOsc,
1020 ENGINE_CALLBACK_PARAMETER_DEFAULT_CHANGED,
1022 static_cast<int>(i),
1023 0, 0,
1024 value,
1025 nullptr);
1028 engine->callback(sendCallback, sendOsc,
1029 ENGINE_CALLBACK_PARAMETER_VALUE_CHANGED,
1031 static_cast<int>(i),
1032 0, 0,
1033 value,
1034 nullptr);
1038 void CarlaPlugin::ProtectedData::updateDefaultParameterValues(CarlaPlugin* const plugin) noexcept
1040 for (uint32_t i=0; i < param.count; ++i)
1041 param.ranges[i].def = param.ranges[i].getFixedValue(plugin->getParameterValue(i));
1044 // -----------------------------------------------------------------------
1046 CARLA_BACKEND_END_NAMESPACE