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