DistrhoPlugin.cpp (7646B)
1 /* 2 * DISTRHO Plugin Framework (DPF) 3 * Copyright (C) 2012-2024 Filipe Coelho <falktx@falktx.com> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any purpose with 6 * or without fee is hereby granted, provided that the above copyright notice and this 7 * permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD 10 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN 11 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER 13 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #include "DistrhoPluginInternal.hpp" 18 19 START_NAMESPACE_DISTRHO 20 21 /* ------------------------------------------------------------------------------------------------------------ 22 * Static data, see DistrhoPluginInternal.hpp */ 23 24 uint32_t d_nextBufferSize = 0; 25 double d_nextSampleRate = 0.0; 26 const char* d_nextBundlePath = nullptr; 27 bool d_nextPluginIsDummy = false; 28 bool d_nextPluginIsSelfTest = false; 29 bool d_nextCanRequestParameterValueChanges = false; 30 31 /* ------------------------------------------------------------------------------------------------------------ 32 * Static fallback data, see DistrhoPluginInternal.hpp */ 33 34 const String PluginExporter::sFallbackString; 35 /* */ AudioPortWithBusId PluginExporter::sFallbackAudioPort; 36 const ParameterRanges PluginExporter::sFallbackRanges; 37 const ParameterEnumerationValues PluginExporter::sFallbackEnumValues; 38 const PortGroupWithId PluginExporter::sFallbackPortGroup; 39 40 /* ------------------------------------------------------------------------------------------------------------ 41 * Plugin */ 42 43 Plugin::Plugin(uint32_t parameterCount, uint32_t programCount, uint32_t stateCount) 44 : pData(new PrivateData()) 45 { 46 #if DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS > 0 47 pData->audioPorts = new AudioPortWithBusId[DISTRHO_PLUGIN_NUM_INPUTS+DISTRHO_PLUGIN_NUM_OUTPUTS]; 48 #endif 49 50 #if defined(DPF_ABORT_ON_ERROR) || defined(DPF_RUNTIME_TESTING) 51 #define DPF_ABORT abort(); 52 #else 53 #define DPF_ABORT 54 #endif 55 56 if (parameterCount > 0) 57 { 58 pData->parameterCount = parameterCount; 59 pData->parameters = new Parameter[parameterCount]; 60 } 61 62 if (programCount > 0) 63 { 64 #if DISTRHO_PLUGIN_WANT_PROGRAMS 65 pData->programCount = programCount; 66 pData->programNames = new String[programCount]; 67 #else 68 d_stderr2("DPF warning: Plugins with programs must define `DISTRHO_PLUGIN_WANT_PROGRAMS` to 1"); 69 DPF_ABORT 70 #endif 71 } 72 73 if (stateCount > 0) 74 { 75 #if DISTRHO_PLUGIN_WANT_STATE 76 pData->stateCount = stateCount; 77 pData->states = new State[stateCount]; 78 #else 79 d_stderr2("DPF warning: Plugins with state must define `DISTRHO_PLUGIN_WANT_STATE` to 1"); 80 DPF_ABORT 81 #endif 82 } 83 84 #undef DPF_ABORT 85 } 86 87 Plugin::~Plugin() 88 { 89 delete pData; 90 } 91 92 /* ------------------------------------------------------------------------------------------------------------ 93 * Host state */ 94 95 uint32_t Plugin::getBufferSize() const noexcept 96 { 97 return pData->bufferSize; 98 } 99 100 double Plugin::getSampleRate() const noexcept 101 { 102 return pData->sampleRate; 103 } 104 105 const char* Plugin::getBundlePath() const noexcept 106 { 107 return pData->bundlePath; 108 } 109 110 bool Plugin::isDummyInstance() const noexcept 111 { 112 return pData->isDummy; 113 } 114 115 bool Plugin::isSelfTestInstance() const noexcept 116 { 117 return pData->isSelfTest; 118 } 119 120 #if DISTRHO_PLUGIN_WANT_TIMEPOS 121 const TimePosition& Plugin::getTimePosition() const noexcept 122 { 123 return pData->timePosition; 124 } 125 #endif 126 127 #if DISTRHO_PLUGIN_WANT_LATENCY 128 void Plugin::setLatency(const uint32_t frames) noexcept 129 { 130 pData->latency = frames; 131 } 132 #endif 133 134 #if DISTRHO_PLUGIN_WANT_MIDI_OUTPUT 135 bool Plugin::writeMidiEvent(const MidiEvent& midiEvent) noexcept 136 { 137 return pData->writeMidiCallback(midiEvent); 138 } 139 #endif 140 141 #if DISTRHO_PLUGIN_WANT_PARAMETER_VALUE_CHANGE_REQUEST 142 bool Plugin::canRequestParameterValueChanges() const noexcept 143 { 144 return pData->canRequestParameterValueChanges; 145 } 146 147 bool Plugin::requestParameterValueChange(const uint32_t index, const float value) noexcept 148 { 149 return pData->requestParameterValueChangeCallback(index, value); 150 } 151 #endif 152 153 #if DISTRHO_PLUGIN_WANT_STATE 154 bool Plugin::updateStateValue(const char* const key, const char* const value) noexcept 155 { 156 return pData->updateStateValueCallback(key, value); 157 } 158 #endif 159 160 /* ------------------------------------------------------------------------------------------------------------ 161 * Init */ 162 163 void Plugin::initAudioPort(bool input, uint32_t index, AudioPort& port) 164 { 165 if (port.hints & kAudioPortIsCV) 166 { 167 port.name = input ? "CV Input " : "CV Output "; 168 port.name += String(index+1); 169 port.symbol = input ? "cv_in_" : "cv_out_"; 170 port.symbol += String(index+1); 171 } 172 else 173 { 174 port.name = input ? "Audio Input " : "Audio Output "; 175 port.name += String(index+1); 176 port.symbol = input ? "audio_in_" : "audio_out_"; 177 port.symbol += String(index+1); 178 } 179 } 180 181 void Plugin::initParameter(uint32_t, Parameter&) {} 182 183 void Plugin::initPortGroup(const uint32_t groupId, PortGroup& portGroup) 184 { 185 fillInPredefinedPortGroupData(groupId, portGroup); 186 } 187 188 #if DISTRHO_PLUGIN_WANT_PROGRAMS 189 void Plugin::initProgramName(uint32_t, String&) {} 190 #endif 191 192 #if DISTRHO_PLUGIN_WANT_STATE 193 void Plugin::initState(const uint32_t index, State& state) 194 { 195 uint hints = 0x0; 196 String stateKey, defaultStateValue; 197 198 #if defined(_MSC_VER) 199 #pragma warning(push) 200 #pragma warning(disable:4996) 201 #elif defined(__clang__) 202 #pragma clang diagnostic push 203 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 204 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) 205 #pragma GCC diagnostic push 206 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 207 #endif 208 initState(index, stateKey, defaultStateValue); 209 if (isStateFile(index)) 210 hints = kStateIsFilenamePath; 211 #if defined(_MSC_VER) 212 #pragma warning(pop) 213 #elif defined(__clang__) 214 #pragma clang diagnostic pop 215 #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) 216 #pragma GCC diagnostic pop 217 #endif 218 219 state.hints = hints; 220 state.key = stateKey; 221 state.label = stateKey; 222 state.defaultValue = defaultStateValue; 223 } 224 #endif 225 226 /* ------------------------------------------------------------------------------------------------------------ 227 * Init */ 228 229 float Plugin::getParameterValue(uint32_t) const { return 0.0f; } 230 void Plugin::setParameterValue(uint32_t, float) {} 231 232 #if DISTRHO_PLUGIN_WANT_PROGRAMS 233 void Plugin::loadProgram(uint32_t) {} 234 #endif 235 236 #if DISTRHO_PLUGIN_WANT_FULL_STATE 237 String Plugin::getState(const char*) const { return String(); } 238 #endif 239 240 #if DISTRHO_PLUGIN_WANT_STATE 241 void Plugin::setState(const char*, const char*) {} 242 #endif 243 244 /* ------------------------------------------------------------------------------------------------------------ 245 * Callbacks (optional) */ 246 247 void Plugin::bufferSizeChanged(uint32_t) {} 248 void Plugin::sampleRateChanged(double) {} 249 void Plugin::ioChanged(uint16_t, uint16_t) {} 250 251 // ----------------------------------------------------------------------------------------------------------- 252 253 END_NAMESPACE_DISTRHO