Fix wine build
[carla.git] / source / native-plugins / lfo.c
blob8cd854fa586bc528f8cc45b5224ff1a3b85ec717
1 /*
2 * Carla Native Plugins
3 * Copyright (C) 2012-2019 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 "CarlaNative.h"
20 #include "CarlaDefines.h"
21 #include "CarlaMIDI.h"
23 #include <math.h>
24 #include <stdlib.h>
26 // -----------------------------------------------------------------------
28 typedef enum {
29 PARAM_MODE = 0,
30 PARAM_SPEED,
31 PARAM_MULTIPLIER,
32 PARAM_BASE_START,
33 PARAM_LFO_OUT,
34 PARAM_COUNT
35 } LfoParams;
37 typedef struct {
38 const NativeHostDescriptor* host;
39 int mode;
40 double speed;
41 float multiplier;
42 float baseStart;
43 float value;
44 } LfoHandle;
46 // -----------------------------------------------------------------------
48 static NativePluginHandle lfo_instantiate(const NativeHostDescriptor* host)
50 LfoHandle* const handle = (LfoHandle*)malloc(sizeof(LfoHandle));
52 if (handle == NULL)
53 return NULL;
55 handle->host = host;
56 handle->mode = 1;
57 handle->speed = 1.0f;
58 handle->multiplier = 1.0f;
59 handle->baseStart = 0.0f;
60 handle->value = 0.0f;
61 return handle;
64 #define handlePtr ((LfoHandle*)handle)
66 static void lfo_cleanup(NativePluginHandle handle)
68 free(handlePtr);
71 static uint32_t lfo_get_parameter_count(NativePluginHandle handle)
73 return PARAM_COUNT;
75 // unused
76 (void)handle;
79 static const NativeParameter* lfo_get_parameter_info(NativePluginHandle handle, uint32_t index)
81 if (index > PARAM_COUNT)
82 return NULL;
84 static NativeParameter param;
85 static NativeParameterScalePoint paramModes[5];
87 param.hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMATABLE;
88 param.scalePointCount = 0;
89 param.scalePoints = NULL;
91 paramModes[0].label = "Triangle";
92 paramModes[1].label = "Sawtooth";
93 paramModes[2].label = "Sawtooth (inverted)";
94 paramModes[3].label = "Sine (TODO)";
95 paramModes[4].label = "Square";
97 paramModes[0].value = 1.0f;
98 paramModes[1].value = 2.0f;
99 paramModes[2].value = 3.0f;
100 paramModes[3].value = 4.0f;
101 paramModes[4].value = 5.0f;
103 switch (index)
105 case PARAM_MODE:
106 param.name = "Mode";
107 param.unit = NULL;
108 param.hints |= NATIVE_PARAMETER_IS_INTEGER|NATIVE_PARAMETER_USES_SCALEPOINTS;
109 param.ranges.def = 1.0f;
110 param.ranges.min = 1.0f;
111 param.ranges.max = 5.0f;
112 param.ranges.step = 1.0f;
113 param.ranges.stepSmall = 1.0f;
114 param.ranges.stepLarge = 1.0f;
115 param.scalePointCount = 5;
116 param.scalePoints = paramModes;
117 break;
118 case PARAM_SPEED:
119 param.name = "Speed";
120 param.unit = "(coef)";
121 param.ranges.def = 1.0f;
122 param.ranges.min = 0.01f;
123 param.ranges.max = 2048.0f;
124 param.ranges.step = 0.25f;
125 param.ranges.stepSmall = 0.1f;
126 param.ranges.stepLarge = 0.5f;
127 break;
128 case PARAM_MULTIPLIER:
129 param.name = "Multiplier";
130 param.unit = "(coef)";
131 param.ranges.def = 1.0f;
132 param.ranges.min = 0.01f;
133 param.ranges.max = 2.0f;
134 param.ranges.step = 0.01f;
135 param.ranges.stepSmall = 0.0001f;
136 param.ranges.stepLarge = 0.1f;
137 break;
138 case PARAM_BASE_START:
139 param.name = "Start value";
140 param.unit = NULL;
141 param.ranges.def = 0.0f;
142 param.ranges.min = -1.0f;
143 param.ranges.max = 1.0f;
144 param.ranges.step = 0.01f;
145 param.ranges.stepSmall = 0.0001f;
146 param.ranges.stepLarge = 0.1f;
147 break;
148 case PARAM_LFO_OUT:
149 param.name = "LFO Out";
150 param.unit = NULL;
151 param.hints |= NATIVE_PARAMETER_IS_OUTPUT;
152 param.ranges.def = 0.0f;
153 param.ranges.min = 0.0f;
154 param.ranges.max = 1.0f;
155 param.ranges.step = 0.01f;
156 param.ranges.stepSmall = 0.0001f;
157 param.ranges.stepLarge = 0.1f;
158 break;
161 return &param;
163 // unused
164 (void)handle;
167 static float lfo_get_parameter_value(NativePluginHandle handle, uint32_t index)
169 switch (index)
171 case PARAM_MODE:
172 return (float)handlePtr->mode;
173 case PARAM_SPEED:
174 return (float)handlePtr->speed;
175 case PARAM_MULTIPLIER:
176 return handlePtr->multiplier;
177 case PARAM_BASE_START:
178 return handlePtr->baseStart;
179 case PARAM_LFO_OUT:
180 return handlePtr->value;
181 default:
182 return 0.0f;
186 static void lfo_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
188 switch (index)
190 case PARAM_MODE:
191 handlePtr->mode = (int)value;
192 break;
193 case PARAM_SPEED:
194 handlePtr->speed = value;
195 break;
196 case PARAM_MULTIPLIER:
197 handlePtr->multiplier = value;
198 break;
199 case PARAM_BASE_START:
200 handlePtr->baseStart = value;
201 break;
202 case PARAM_LFO_OUT:
203 handlePtr->value = value;
204 break;
208 // FIXME for v3.0, use const for the input buffer
209 static void lfo_process(NativePluginHandle handle,
210 float** inBuffer, float** outBuffer, uint32_t frames,
211 const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
213 const NativeHostDescriptor* const host = handlePtr->host;
214 const NativeTimeInfo* const timeInfo = host->get_time_info(host->handle);
216 if (! timeInfo->playing)
217 return;
219 const double bpm = timeInfo->bbt.valid ? timeInfo->bbt.beatsPerMinute : 120.0;
220 const double sampleRate = host->get_sample_rate(host->handle);
222 const double speedRate = handlePtr->speed/(bpm/60.0/sampleRate);
223 const uint speedRatei = (uint)speedRate;
225 double value = 0.0;
227 switch (handlePtr->mode)
229 case 1: // Triangle
230 value = fabs(1.0-(double)(timeInfo->frame % speedRatei)/(speedRate/2.0));
231 break;
232 case 2: // Sawtooth
233 value = (double)(timeInfo->frame % speedRatei)/speedRate;
234 break;
235 case 3: // Sawtooth (inverted)
236 value = 1.0 - (double)(timeInfo->frame % speedRatei)/speedRate;
237 break;
238 case 4: // Sine -- TODO!
239 value = 0.0;
240 break;
241 case 5: // Square
242 value = (timeInfo->frame % speedRatei <= speedRatei/2) ? 1.0 : 0.0;
243 break;
246 value *= (double)handlePtr->multiplier;
247 value += (double)handlePtr->baseStart;
249 if (value <= 0.0)
250 handlePtr->value = 0.0f;
251 else if (value >= 1.0)
252 handlePtr->value = 1.0f;
253 else
254 handlePtr->value = (float)value;
256 return;
258 // unused
259 (void)inBuffer;
260 (void)outBuffer;
261 (void)frames;
262 (void)midiEvents;
263 (void)midiEventCount;
266 #undef handlePtr
268 // -----------------------------------------------------------------------
270 static const NativePluginDescriptor lfoDesc = {
271 .category = NATIVE_PLUGIN_CATEGORY_UTILITY,
272 .hints = NATIVE_PLUGIN_IS_RTSAFE,
273 .supports = NATIVE_PLUGIN_SUPPORTS_NOTHING,
274 .audioIns = 0,
275 .audioOuts = 0,
276 .cvIns = 0,
277 .cvOuts = 0,
278 .midiIns = 0,
279 .midiOuts = 0,
280 .paramIns = PARAM_COUNT-1,
281 .paramOuts = 1,
282 .name = "LFO",
283 .label = "lfo",
284 .maker = "falkTX",
285 .copyright = "GNU GPL v2+",
287 .instantiate = lfo_instantiate,
288 .cleanup = lfo_cleanup,
290 .get_parameter_count = lfo_get_parameter_count,
291 .get_parameter_info = lfo_get_parameter_info,
292 .get_parameter_value = lfo_get_parameter_value,
294 .get_midi_program_count = NULL,
295 .get_midi_program_info = NULL,
297 .set_parameter_value = lfo_set_parameter_value,
298 .set_midi_program = NULL,
299 .set_custom_data = NULL,
301 .ui_show = NULL,
302 .ui_idle = NULL,
304 .ui_set_parameter_value = NULL,
305 .ui_set_midi_program = NULL,
306 .ui_set_custom_data = NULL,
308 .activate = NULL,
309 .deactivate = NULL,
310 .process = lfo_process,
312 .get_state = NULL,
313 .set_state = NULL,
315 .dispatcher = NULL
318 // -----------------------------------------------------------------------
320 void carla_register_native_plugin_lfo(void);
322 void carla_register_native_plugin_lfo(void)
324 carla_register_native_plugin(&lfoDesc);
327 // -----------------------------------------------------------------------