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"
26 #define MAX_CHANNELS 2
28 // -----------------------------------------------------------------------
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
;
45 // -----------------------------------------------------------------------
53 PARAM_APPLY_LEFT
= PARAM_COUNT_MONO
,
59 Filter lowpass
[MAX_CHANNELS
];
66 // -----------------------------------------------------------------------
68 static NativePluginHandle
audiogain_instantiate(const NativeHostDescriptor
* host
, const bool isMono
)
70 AudioGainHandle
* const handle
= (AudioGainHandle
*)malloc(sizeof(AudioGainHandle
));
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
);
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
)
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
))
115 static NativeParameter param
;
117 param
.hints
= NATIVE_PARAMETER_IS_ENABLED
|NATIVE_PARAMETER_IS_AUTOMATABLE
;
119 param
.scalePointCount
= 0;
120 param
.scalePoints
= NULL
;
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
;
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
;
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
;
158 static float audiogain_get_parameter_value(NativePluginHandle handle
, uint32_t index
)
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
;
173 static void audiogain_set_parameter_value(NativePluginHandle handle
, uint32_t index
, float value
)
178 handlePtr
->gain
= value
;
180 case PARAM_APPLY_LEFT
:
181 handlePtr
->applyLeft
= (value
>= 0.5f
);
183 case PARAM_APPLY_RIGHT
:
184 handlePtr
->applyRight
= (value
>= 0.5f
);
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
;
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
);
217 handle_audio_buffers(inBuffer
[1], outBuffer
[1], &handlePtr
->lowpass
[1], applyRight
? gain
: 1.0f
, frames
);
223 (void)midiEventCount
;
226 static intptr_t audiogain_dispatcher(NativePluginHandle handle
, NativePluginDispatcherOpcode opcode
, int32_t index
, intptr_t value
, void* ptr
, float opt
)
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
);
246 // -----------------------------------------------------------------------
248 static const NativePluginDescriptor audiogainMonoDesc
= {
249 .category
= NATIVE_PLUGIN_CATEGORY_UTILITY
,
250 .hints
= NATIVE_PLUGIN_IS_RTSAFE
,
251 .supports
= NATIVE_PLUGIN_SUPPORTS_NOTHING
,
256 .paramIns
= PARAM_COUNT_MONO
,
258 .name
= "Audio Gain (Mono)",
259 .label
= "audiogain",
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
,
280 .ui_set_parameter_value
= NULL
,
281 .ui_set_midi_program
= NULL
,
282 .ui_set_custom_data
= NULL
,
286 .process
= audiogain_process
,
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
,
306 .paramIns
= PARAM_COUNT_STEREO
,
308 .name
= "Audio Gain (Stereo)",
309 .label
= "audiogain_s",
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
,
330 .ui_set_parameter_value
= NULL
,
331 .ui_set_midi_program
= NULL
,
332 .ui_set_custom_data
= NULL
,
336 .process
= audiogain_process
,
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 // -----------------------------------------------------------------------