1 /*
2 * DISTRHO Plugin Framework (DPF)
3 * Copyright (C) 2012-2018 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:
ExamplePluginMeters()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 */
getLabel() const46 const char* getLabel() const override
47 {
48 return "meters";
49 }
50
51 /**
52 Get an extensive comment/description about the plugin.
53 */
getDescription() const54 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 */
getMaker() const62 const char* getMaker() const override
63 {
64 return "DISTRHO";
65 }
66
67 /**
68 Get the plugin homepage.
69 */
getHomePage() const70 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 */
getLicense() const79 const char* getLicense() const override
80 {
81 return "ISC";
82 }
83
84 /**
85 Get the plugin version, in hexadecimal.
86 */
getVersion() const87 uint32_t getVersion() const override
88 {
89 return d_version(1, 0, 0);
90 }
91
92 /**
93 Get the plugin unique Id.
94 This value is used by LADSPA, DSSI and VST plugin formats.
95 */
getUniqueId() const96 int64_t getUniqueId() const override
97 {
98 return d_cconst('d', 'M', 't', 'r');
99 }
100
101 /* --------------------------------------------------------------------------------------------------------
102 * Init */
103
104 /**
105 Initialize the parameter @a index.
106 This function will be called once, shortly after the plugin is created.
107 */
initParameter(uint32_t index,Parameter & parameter)108 void initParameter(uint32_t index, Parameter& parameter) override
109 {
110 /**
111 All parameters in this plugin have the same ranges.
112 */
113 parameter.ranges.min = 0.0f;
114 parameter.ranges.max = 1.0f;
115 parameter.ranges.def = 0.0f;
116
117 /**
118 Set parameter data.
119 */
120 switch (index)
121 {
122 case 0:
123 parameter.hints = kParameterIsAutomable|kParameterIsInteger;
124 parameter.name = "color";
125 parameter.symbol = "color";
126 parameter.enumValues.count = 2;
127 parameter.enumValues.restrictedMode = true;
128 {
129 ParameterEnumerationValue* const values = new ParameterEnumerationValue[2];
130 parameter.enumValues.values = values;
131
132 values[0].label = "Green";
133 values[0].value = METER_COLOR_GREEN;
134 values[1].label = "Blue";
135 values[1].value = METER_COLOR_BLUE;
136 }
137 break;
138 case 1:
139 parameter.hints = kParameterIsAutomable|kParameterIsOutput;
140 parameter.name = "out-left";
141 parameter.symbol = "out_left";
142 break;
143 case 2:
144 parameter.hints = kParameterIsAutomable|kParameterIsOutput;
145 parameter.name = "out-right";
146 parameter.symbol = "out_right";
147 break;
148 }
149 }
150
151 /**
152 Set a state key and default value.
153 This function will be called once, shortly after the plugin is created.
154 */
initState(uint32_t,String &,String &)155 void initState(uint32_t, String&, String&) override
156 {
157 // we are using states but don't want them saved in the host
158 }
159
160 /* --------------------------------------------------------------------------------------------------------
161 * Internal data */
162
163 /**
164 Get the current value of a parameter.
165 */
getParameterValue(uint32_t index) const166 float getParameterValue(uint32_t index) const override
167 {
168 switch (index)
169 {
170 case 0: return fColor;
171 case 1: return fOutLeft;
172 case 2: return fOutRight;
173 }
174
175 return 0.0f;
176 }
177
178 /**
179 Change a parameter value.
180 */
setParameterValue(uint32_t index,float value)181 void setParameterValue(uint32_t index, float value) override
182 {
183 // this is only called for input paramters, and we only have one of those.
184 if (index != 0) return;
185
186 fColor = value;
187 }
188
189 /**
190 Change an internal state.
191 */
setState(const char * key,const char *)192 void setState(const char* key, const char*) override
193 {
194 if (std::strcmp(key, "reset") != 0)
195 return;
196
197 fNeedsReset = true;
198 }
199
200 /* --------------------------------------------------------------------------------------------------------
201 * Process */
202
203 /**
204 Run/process function for plugins without MIDI input.
205 */
run(const float ** inputs,float ** outputs,uint32_t frames)206 void run(const float** inputs, float** outputs, uint32_t frames) override
207 {
208 float tmp;
209 float tmpLeft = 0.0f;
210 float tmpRight = 0.0f;
211
212 for (uint32_t i=0; i<frames; ++i)
213 {
214 // left
215 tmp = std::abs(inputs[0][i]);
216
217 if (tmp > tmpLeft)
218 tmpLeft = tmp;
219
220 // right
221 tmp = std::abs(inputs[1][i]);
222
223 if (tmp > tmpRight)
224 tmpRight = tmp;
225 }
226
227 if (tmpLeft > 1.0f)
228 tmpLeft = 1.0f;
229 if (tmpRight > 1.0f)
230 tmpRight = 1.0f;
231
232 if (fNeedsReset)
233 {
234 fOutLeft = tmpLeft;
235 fOutRight = tmpRight;
236 fNeedsReset = false;
237 }
238 else
239 {
240 if (tmpLeft > fOutLeft)
241 fOutLeft = tmpLeft;
242 if (tmpRight > fOutRight)
243 fOutRight = tmpRight;
244 }
245
246 // copy inputs over outputs if needed
247 if (outputs[0] != inputs[0])
248 std::memcpy(outputs[0], inputs[0], sizeof(float)*frames);
249
250 if (outputs[1] != inputs[1])
251 std::memcpy(outputs[1], inputs[1], sizeof(float)*frames);
252 }
253
254 // -------------------------------------------------------------------------------------------------------
255
256 private:
257 /**
258 Parameters.
259 */
260 float fColor, fOutLeft, fOutRight;
261
262 /**
263 Boolean used to reset meter values.
264 The UI will send a "reset" message which sets this as true.
265 */
266 volatile bool fNeedsReset;
267
268 /**
269 Set our plugin class as non-copyable and add a leak detector just in case.
270 */
271 DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ExamplePluginMeters)
272 };
273
274 /* ------------------------------------------------------------------------------------------------------------
275 * Plugin entry point, called by DPF to create a new plugin instance. */
276
createPlugin()277 Plugin* createPlugin()
278 {
279 return new ExamplePluginMeters();
280 }
281
282 // -----------------------------------------------------------------------------------------------------------
283
284 END_NAMESPACE_DISTRHO
285