Add initial bits for Qt6 support
[carla.git] / source / native-plugins / audio-gain.c
blobd69a6f277edeb7bdc02569adaa2eb3794e103f87
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"
19 #include "CarlaMIDI.h"
21 #include <math.h>
22 #include <stdbool.h>
23 #include <stdlib.h>
24 #include <string.h>
26 #define MAX_CHANNELS 2
28 // -----------------------------------------------------------------------
30 typedef struct {
31 float a0, b1, z1;
32 } Filter;
34 static inline
35 void set_filter_sample_rate(Filter* const filter, const float sampleRate)
37 static const float M_PIf = (float)M_PI;
38 const float frequency = 30.0f / sampleRate;
40 filter->b1 = expf(-2.0f * M_PIf * frequency);
41 filter->a0 = 1.0f - filter->b1;
42 filter->z1 = 0.0f;
45 // -----------------------------------------------------------------------
47 typedef enum {
48 // all versions
49 PARAM_GAIN = 0,
50 PARAM_COUNT_MONO,
52 // stereo version
53 PARAM_APPLY_LEFT = PARAM_COUNT_MONO,
54 PARAM_APPLY_RIGHT,
55 PARAM_COUNT_STEREO
56 } AudioGainParams;
58 typedef struct {
59 Filter lowpass[MAX_CHANNELS];
60 float gain;
61 bool isMono;
62 bool applyLeft;
63 bool applyRight;
64 } AudioGainHandle;
66 // -----------------------------------------------------------------------
68 static NativePluginHandle audiogain_instantiate(const NativeHostDescriptor* host, const bool isMono)
70 AudioGainHandle* const handle = (AudioGainHandle*)malloc(sizeof(AudioGainHandle));
72 if (handle == NULL)
73 return NULL;
75 handle->gain = 1.0f;
76 handle->isMono = isMono;
77 handle->applyLeft = true;
78 handle->applyRight = true;
80 const float sampleRate = (float)host->get_sample_rate(host->handle);
82 for (unsigned i = 0; i < MAX_CHANNELS; ++i)
83 set_filter_sample_rate(&handle->lowpass[i], sampleRate);
85 return handle;
88 static NativePluginHandle audiogain_instantiate_mono(const NativeHostDescriptor* host)
90 return audiogain_instantiate(host, true);
93 static NativePluginHandle audiogain_instantiate_stereo(const NativeHostDescriptor* host)
95 return audiogain_instantiate(host, false);
98 #define handlePtr ((AudioGainHandle*)handle)
100 static void audiogain_cleanup(NativePluginHandle handle)
102 free(handlePtr);
105 static uint32_t audiogain_get_parameter_count(NativePluginHandle handle)
107 return handlePtr->isMono ? PARAM_COUNT_MONO : PARAM_COUNT_STEREO;
110 static const NativeParameter* audiogain_get_parameter_info(NativePluginHandle handle, uint32_t index)
112 if (index > (uint32_t)(handlePtr->isMono ? PARAM_COUNT_MONO : PARAM_COUNT_STEREO))
113 return NULL;
115 static NativeParameter param;
117 param.hints = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMATABLE;
118 param.unit = NULL;
119 param.scalePointCount = 0;
120 param.scalePoints = NULL;
122 switch (index)
124 case PARAM_GAIN:
125 param.name = "Gain";
126 param.ranges.def = 1.0f;
127 param.ranges.min = 0.0f;
128 param.ranges.max = 4.0f;
129 param.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
130 param.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
131 param.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
132 break;
133 case PARAM_APPLY_LEFT:
134 param.name = "Apply Left";
135 param.hints |= NATIVE_PARAMETER_IS_BOOLEAN;
136 param.ranges.def = 1.0f;
137 param.ranges.min = 0.0f;
138 param.ranges.max = 1.0f;
139 param.ranges.step = 1.0f;
140 param.ranges.stepSmall = 1.0f;
141 param.ranges.stepLarge = 1.0f;
142 break;
143 case PARAM_APPLY_RIGHT:
144 param.name = "Apply Right";
145 param.hints |= NATIVE_PARAMETER_IS_BOOLEAN;
146 param.ranges.def = 1.0f;
147 param.ranges.min = 0.0f;
148 param.ranges.max = 1.0f;
149 param.ranges.step = 1.0f;
150 param.ranges.stepSmall = 1.0f;
151 param.ranges.stepLarge = 1.0f;
152 break;
155 return &param;
158 static float audiogain_get_parameter_value(NativePluginHandle handle, uint32_t index)
160 switch (index)
162 case PARAM_GAIN:
163 return handlePtr->gain;
164 case PARAM_APPLY_LEFT:
165 return handlePtr->applyLeft ? 1.0f : 0.0f;
166 case PARAM_APPLY_RIGHT:
167 return handlePtr->applyRight ? 1.0f : 0.0f;
168 default:
169 return 0.0f;
173 static void audiogain_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
175 switch (index)
177 case PARAM_GAIN:
178 handlePtr->gain = value;
179 break;
180 case PARAM_APPLY_LEFT:
181 handlePtr->applyLeft = (value >= 0.5f);
182 break;
183 case PARAM_APPLY_RIGHT:
184 handlePtr->applyRight = (value >= 0.5f);
185 break;
189 static inline
190 void handle_audio_buffers(const float* inBuffer, float* outBuffer, Filter* const filter, const float gain, const uint32_t frames)
192 const float a0 = filter->a0;
193 const float b1 = filter->b1;
194 float z1 = filter->z1;
196 for (uint32_t i=0; i < frames; ++i) {
197 z1 = gain * a0 + z1 * b1;
198 *outBuffer++ = *inBuffer++ * z1;
201 filter->z1 = z1;
204 // FIXME for v3.0, use const for the input buffer
205 static void audiogain_process(NativePluginHandle handle,
206 float** inBuffer, float** outBuffer, uint32_t frames,
207 const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
209 const float gain = handlePtr->gain;
210 const bool applyLeft = handlePtr->applyLeft;
211 const bool applyRight = handlePtr->applyRight;
212 const bool isMono = handlePtr->isMono;
214 handle_audio_buffers(inBuffer[0], outBuffer[0], &handlePtr->lowpass[0], (isMono || applyLeft) ? gain : 1.0f, frames);
216 if (! isMono)
217 handle_audio_buffers(inBuffer[1], outBuffer[1], &handlePtr->lowpass[1], applyRight ? gain : 1.0f, frames);
219 return;
221 // unused
222 (void)midiEvents;
223 (void)midiEventCount;
226 static intptr_t audiogain_dispatcher(NativePluginHandle handle, NativePluginDispatcherOpcode opcode, int32_t index, intptr_t value, void* ptr, float opt)
228 switch (opcode)
230 case NATIVE_PLUGIN_OPCODE_SAMPLE_RATE_CHANGED:
231 for (unsigned i = 0; i < MAX_CHANNELS; ++i)
232 set_filter_sample_rate(&handlePtr->lowpass[i], opt);
233 break;
234 default:
235 break;
238 return 0;
240 // unused
241 (void)index;
242 (void)value;
243 (void)ptr;
246 // -----------------------------------------------------------------------
248 static const NativePluginDescriptor audiogainMonoDesc = {
249 .category = NATIVE_PLUGIN_CATEGORY_UTILITY,
250 .hints = NATIVE_PLUGIN_IS_RTSAFE,
251 .supports = NATIVE_PLUGIN_SUPPORTS_NOTHING,
252 .audioIns = 1,
253 .audioOuts = 1,
254 .midiIns = 0,
255 .midiOuts = 0,
256 .paramIns = PARAM_COUNT_MONO,
257 .paramOuts = 0,
258 .name = "Audio Gain (Mono)",
259 .label = "audiogain",
260 .maker = "falkTX",
261 .copyright = "GNU GPL v2+",
263 .instantiate = audiogain_instantiate_mono,
264 .cleanup = audiogain_cleanup,
266 .get_parameter_count = audiogain_get_parameter_count,
267 .get_parameter_info = audiogain_get_parameter_info,
268 .get_parameter_value = audiogain_get_parameter_value,
270 .get_midi_program_count = NULL,
271 .get_midi_program_info = NULL,
273 .set_parameter_value = audiogain_set_parameter_value,
274 .set_midi_program = NULL,
275 .set_custom_data = NULL,
277 .ui_show = NULL,
278 .ui_idle = NULL,
280 .ui_set_parameter_value = NULL,
281 .ui_set_midi_program = NULL,
282 .ui_set_custom_data = NULL,
284 .activate = NULL,
285 .deactivate = NULL,
286 .process = audiogain_process,
288 .get_state = NULL,
289 .set_state = NULL,
291 .dispatcher = audiogain_dispatcher,
293 .render_inline_display = NULL
296 static const NativePluginDescriptor audiogainStereoDesc = {
297 .category = NATIVE_PLUGIN_CATEGORY_UTILITY,
298 .hints = NATIVE_PLUGIN_IS_RTSAFE,
299 .supports = NATIVE_PLUGIN_SUPPORTS_NOTHING,
300 .audioIns = 2,
301 .audioOuts = 2,
302 .cvIns = 0,
303 .cvOuts = 0,
304 .midiIns = 0,
305 .midiOuts = 0,
306 .paramIns = PARAM_COUNT_STEREO,
307 .paramOuts = 0,
308 .name = "Audio Gain (Stereo)",
309 .label = "audiogain_s",
310 .maker = "falkTX",
311 .copyright = "GNU GPL v2+",
313 .instantiate = audiogain_instantiate_stereo,
314 .cleanup = audiogain_cleanup,
316 .get_parameter_count = audiogain_get_parameter_count,
317 .get_parameter_info = audiogain_get_parameter_info,
318 .get_parameter_value = audiogain_get_parameter_value,
320 .get_midi_program_count = NULL,
321 .get_midi_program_info = NULL,
323 .set_parameter_value = audiogain_set_parameter_value,
324 .set_midi_program = NULL,
325 .set_custom_data = NULL,
327 .ui_show = NULL,
328 .ui_idle = NULL,
330 .ui_set_parameter_value = NULL,
331 .ui_set_midi_program = NULL,
332 .ui_set_custom_data = NULL,
334 .activate = NULL,
335 .deactivate = NULL,
336 .process = audiogain_process,
338 .get_state = NULL,
339 .set_state = NULL,
341 .dispatcher = audiogain_dispatcher
344 // -----------------------------------------------------------------------
346 void carla_register_native_plugin_audiogain(void);
348 void carla_register_native_plugin_audiogain(void)
350 carla_register_native_plugin(&audiogainMonoDesc);
351 carla_register_native_plugin(&audiogainStereoDesc);
354 // -----------------------------------------------------------------------