ExamplePluginMeters.cpp (8430B)
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 "DistrhoPlugin.hpp" 18 19 START_NAMESPACE_DISTRHO 20 21 // ----------------------------------------------------------------------------------------------------------- 22 23 /** 24 Plugin to demonstrate parameter outputs using meters. 25 */ 26 class ExamplePluginMeters : public Plugin 27 { 28 public: 29 ExamplePluginMeters() 30 : Plugin(3, 0, 0), // 3 parameters, 0 programs, 0 states 31 fColor(0.0f), 32 fOutLeft(0.0f), 33 fOutRight(0.0f), 34 fNeedsReset(true) 35 { 36 } 37 38 protected: 39 /* -------------------------------------------------------------------------------------------------------- 40 * Information */ 41 42 /** 43 Get the plugin label. 44 A plugin label follows the same rules as Parameter::symbol, with the exception that it can start with numbers. 45 */ 46 const char* getLabel() const override 47 { 48 return "meters"; 49 } 50 51 /** 52 Get an extensive comment/description about the plugin. 53 */ 54 const char* getDescription() const override 55 { 56 return "Plugin to demonstrate parameter outputs using meters."; 57 } 58 59 /** 60 Get the plugin author/maker. 61 */ 62 const char* getMaker() const override 63 { 64 return "DISTRHO"; 65 } 66 67 /** 68 Get the plugin homepage. 69 */ 70 const char* getHomePage() const override 71 { 72 return "https://github.com/DISTRHO/DPF"; 73 } 74 75 /** 76 Get the plugin license name (a single line of text). 77 For commercial plugins this should return some short copyright information. 78 */ 79 const char* getLicense() const override 80 { 81 return "ISC"; 82 } 83 84 /** 85 Get the plugin version, in hexadecimal. 86 */ 87 uint32_t getVersion() const override 88 { 89 return d_version(1, 0, 0); 90 } 91 92 /* -------------------------------------------------------------------------------------------------------- 93 * Init */ 94 95 /** 96 Initialize the audio port @a index.@n 97 This function will be called once, shortly after the plugin is created. 98 */ 99 void initAudioPort(bool input, uint32_t index, AudioPort& port) override 100 { 101 // treat meter audio ports as stereo 102 port.groupId = kPortGroupStereo; 103 104 // everything else is as default 105 Plugin::initAudioPort(input, index, port); 106 } 107 108 /** 109 Initialize the parameter @a index.@n 110 This function will be called once, shortly after the plugin is created. 111 */ 112 void initParameter(uint32_t index, Parameter& parameter) override 113 { 114 /** 115 All parameters in this plugin have the same ranges. 116 */ 117 parameter.ranges.min = 0.0f; 118 parameter.ranges.max = 1.0f; 119 parameter.ranges.def = 0.0f; 120 121 /** 122 Set parameter data. 123 */ 124 switch (index) 125 { 126 case 0: 127 parameter.hints = kParameterIsAutomatable|kParameterIsInteger; 128 parameter.name = "color"; 129 parameter.symbol = "color"; 130 parameter.enumValues.count = 2; 131 parameter.enumValues.restrictedMode = true; 132 { 133 ParameterEnumerationValue* const values = new ParameterEnumerationValue[2]; 134 parameter.enumValues.values = values; 135 136 values[0].label = "Green"; 137 values[0].value = METER_COLOR_GREEN; 138 values[1].label = "Blue"; 139 values[1].value = METER_COLOR_BLUE; 140 } 141 break; 142 case 1: 143 parameter.hints = kParameterIsAutomatable|kParameterIsOutput; 144 parameter.name = "out-left"; 145 parameter.symbol = "out_left"; 146 break; 147 case 2: 148 parameter.hints = kParameterIsAutomatable|kParameterIsOutput; 149 parameter.name = "out-right"; 150 parameter.symbol = "out_right"; 151 break; 152 } 153 } 154 155 /** 156 Set a state key and default value. 157 This function will be called once, shortly after the plugin is created. 158 */ 159 void initState(uint32_t, String&, String&) override 160 { 161 // we are using states but don't want them saved in the host 162 } 163 164 /* -------------------------------------------------------------------------------------------------------- 165 * Internal data */ 166 167 /** 168 Get the current value of a parameter. 169 */ 170 float getParameterValue(uint32_t index) const override 171 { 172 switch (index) 173 { 174 case 0: return fColor; 175 case 1: return fOutLeft; 176 case 2: return fOutRight; 177 } 178 179 return 0.0f; 180 } 181 182 /** 183 Change a parameter value. 184 */ 185 void setParameterValue(uint32_t index, float value) override 186 { 187 // this is only called for input paramters, and we only have one of those. 188 if (index != 0) return; 189 190 fColor = value; 191 } 192 193 /** 194 Change an internal state. 195 */ 196 void setState(const char* key, const char*) override 197 { 198 if (std::strcmp(key, "reset") != 0) 199 return; 200 201 fNeedsReset = true; 202 } 203 204 /* -------------------------------------------------------------------------------------------------------- 205 * Process */ 206 207 /** 208 Run/process function for plugins without MIDI input. 209 */ 210 void run(const float** inputs, float** outputs, uint32_t frames) override 211 { 212 float tmp; 213 float tmpLeft = 0.0f; 214 float tmpRight = 0.0f; 215 216 for (uint32_t i=0; i<frames; ++i) 217 { 218 // left 219 tmp = std::abs(inputs[0][i]); 220 221 if (tmp > tmpLeft) 222 tmpLeft = tmp; 223 224 // right 225 tmp = std::abs(inputs[1][i]); 226 227 if (tmp > tmpRight) 228 tmpRight = tmp; 229 } 230 231 if (tmpLeft > 1.0f) 232 tmpLeft = 1.0f; 233 if (tmpRight > 1.0f) 234 tmpRight = 1.0f; 235 236 if (fNeedsReset) 237 { 238 fOutLeft = tmpLeft; 239 fOutRight = tmpRight; 240 fNeedsReset = false; 241 } 242 else 243 { 244 if (tmpLeft > fOutLeft) 245 fOutLeft = tmpLeft; 246 if (tmpRight > fOutRight) 247 fOutRight = tmpRight; 248 } 249 250 // copy inputs over outputs if needed 251 if (outputs[0] != inputs[0]) 252 std::memcpy(outputs[0], inputs[0], sizeof(float)*frames); 253 254 if (outputs[1] != inputs[1]) 255 std::memcpy(outputs[1], inputs[1], sizeof(float)*frames); 256 } 257 258 // ------------------------------------------------------------------------------------------------------- 259 260 private: 261 /** 262 Parameters. 263 */ 264 float fColor, fOutLeft, fOutRight; 265 266 /** 267 Boolean used to reset meter values. 268 The UI will send a "reset" message which sets this as true. 269 */ 270 volatile bool fNeedsReset; 271 272 /** 273 Set our plugin class as non-copyable and add a leak detector just in case. 274 */ 275 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginMeters) 276 }; 277 278 /* ------------------------------------------------------------------------------------------------------------ 279 * Plugin entry point, called by DPF to create a new plugin instance. */ 280 281 Plugin* createPlugin() 282 { 283 return new ExamplePluginMeters(); 284 } 285 286 // ----------------------------------------------------------------------------------------------------------- 287 288 END_NAMESPACE_DISTRHO