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"
24 // -----------------------------------------------------------------------
29 PARAM_APPLY_AFTERTOUCH
,
35 const NativeHostDescriptor
* host
;
42 // -----------------------------------------------------------------------
44 static NativePluginHandle
midigain_instantiate(const NativeHostDescriptor
* host
)
46 MidiGainHandle
* const handle
= (MidiGainHandle
*)malloc(sizeof(MidiGainHandle
));
53 handle
->applyNotes
= true;
54 handle
->applyAftertouch
= true;
55 handle
->applyCC
= false;
59 #define handlePtr ((MidiGainHandle*)handle)
61 static void midigain_cleanup(NativePluginHandle handle
)
66 static uint32_t midigain_get_parameter_count(NativePluginHandle handle
)
74 static const NativeParameter
* midigain_get_parameter_info(NativePluginHandle handle
, uint32_t index
)
76 if (index
> PARAM_COUNT
)
79 static NativeParameter param
;
81 param
.hints
= NATIVE_PARAMETER_IS_ENABLED
|NATIVE_PARAMETER_IS_AUTOMATABLE
;
83 param
.scalePointCount
= 0;
84 param
.scalePoints
= NULL
;
90 param
.ranges
.def
= 1.0f
;
91 param
.ranges
.min
= 0.001f
;
92 param
.ranges
.max
= 4.0f
;
93 param
.ranges
.step
= PARAMETER_RANGES_DEFAULT_STEP
;
94 param
.ranges
.stepSmall
= PARAMETER_RANGES_DEFAULT_STEP_SMALL
;
95 param
.ranges
.stepLarge
= PARAMETER_RANGES_DEFAULT_STEP_LARGE
;
97 case PARAM_APPLY_NOTES
:
98 param
.name
= "Apply Notes";
99 param
.hints
|= NATIVE_PARAMETER_IS_BOOLEAN
;
100 param
.ranges
.def
= 1.0f
;
101 param
.ranges
.min
= 0.0f
;
102 param
.ranges
.max
= 1.0f
;
103 param
.ranges
.step
= 1.0f
;
104 param
.ranges
.stepSmall
= 1.0f
;
105 param
.ranges
.stepLarge
= 1.0f
;
107 case PARAM_APPLY_AFTERTOUCH
:
108 param
.name
= "Apply Aftertouch";
109 param
.hints
|= NATIVE_PARAMETER_IS_BOOLEAN
;
110 param
.ranges
.def
= 1.0f
;
111 param
.ranges
.min
= 0.0f
;
112 param
.ranges
.max
= 1.0f
;
113 param
.ranges
.step
= 1.0f
;
114 param
.ranges
.stepSmall
= 1.0f
;
115 param
.ranges
.stepLarge
= 1.0f
;
118 param
.name
= "Apply CC";
119 param
.hints
|= NATIVE_PARAMETER_IS_BOOLEAN
;
120 param
.ranges
.def
= 0.0f
;
121 param
.ranges
.min
= 0.0f
;
122 param
.ranges
.max
= 1.0f
;
123 param
.ranges
.step
= 1.0f
;
124 param
.ranges
.stepSmall
= 1.0f
;
125 param
.ranges
.stepLarge
= 1.0f
;
135 static float midigain_get_parameter_value(NativePluginHandle handle
, uint32_t index
)
140 return handlePtr
->gain
;
141 case PARAM_APPLY_NOTES
:
142 return handlePtr
->applyNotes
? 1.0f
: 0.0f
;
143 case PARAM_APPLY_AFTERTOUCH
:
144 return handlePtr
->applyAftertouch
? 1.0f
: 0.0f
;
146 return handlePtr
->applyCC
? 1.0f
: 0.0f
;
152 static void midigain_set_parameter_value(NativePluginHandle handle
, uint32_t index
, float value
)
157 handlePtr
->gain
= value
;
159 case PARAM_APPLY_NOTES
:
160 handlePtr
->applyNotes
= (value
>= 0.5f
);
162 case PARAM_APPLY_AFTERTOUCH
:
163 handlePtr
->applyAftertouch
= (value
>= 0.5f
);
166 handlePtr
->applyCC
= (value
>= 0.5f
);
171 // FIXME for v3.0, use const for the input buffer
172 static void midigain_process(NativePluginHandle handle
,
173 float** inBuffer
, float** outBuffer
, uint32_t frames
,
174 const NativeMidiEvent
* midiEvents
, uint32_t midiEventCount
)
176 const NativeHostDescriptor
* const host
= handlePtr
->host
;
177 const float gain
= handlePtr
->gain
;
178 const bool applyNotes
= handlePtr
->applyNotes
;
179 const bool applyAftertouch
= handlePtr
->applyAftertouch
;
180 const bool applyCC
= handlePtr
->applyCC
;
181 NativeMidiEvent tmpEvent
;
183 for (uint32_t i
=0; i
< midiEventCount
; ++i
)
185 const NativeMidiEvent
* const midiEvent
= &midiEvents
[i
];
187 const uint8_t status
= (uint8_t)MIDI_GET_STATUS_FROM_DATA(midiEvent
->data
);
189 if (midiEvent
->size
== 3 && ((applyNotes
&& (status
== MIDI_STATUS_NOTE_OFF
|| status
== MIDI_STATUS_NOTE_ON
)) ||
190 (applyAftertouch
&& status
== MIDI_STATUS_POLYPHONIC_AFTERTOUCH
) ||
191 (applyCC
&& status
== MIDI_STATUS_CONTROL_CHANGE
)))
193 memcpy(&tmpEvent
, midiEvent
, sizeof(NativeMidiEvent
));
195 float value
= (float)midiEvent
->data
[2] * gain
;
198 tmpEvent
.data
[2] = 0;
199 else if (value
>= 127.0f
)
200 tmpEvent
.data
[2] = 127;
202 tmpEvent
.data
[2] = (uint8_t)value
;
204 host
->write_midi_event(host
->handle
, &tmpEvent
);
207 host
->write_midi_event(host
->handle
, midiEvent
);
218 // -----------------------------------------------------------------------
220 static const NativePluginDescriptor midigainDesc
= {
221 .category
= NATIVE_PLUGIN_CATEGORY_UTILITY
,
222 .hints
= NATIVE_PLUGIN_IS_RTSAFE
,
223 .supports
= NATIVE_PLUGIN_SUPPORTS_EVERYTHING
,
235 .copyright
= "GNU GPL v2+",
237 .instantiate
= midigain_instantiate
,
238 .cleanup
= midigain_cleanup
,
240 .get_parameter_count
= midigain_get_parameter_count
,
241 .get_parameter_info
= midigain_get_parameter_info
,
242 .get_parameter_value
= midigain_get_parameter_value
,
244 .get_midi_program_count
= NULL
,
245 .get_midi_program_info
= NULL
,
247 .set_parameter_value
= midigain_set_parameter_value
,
248 .set_midi_program
= NULL
,
249 .set_custom_data
= NULL
,
254 .ui_set_parameter_value
= NULL
,
255 .ui_set_midi_program
= NULL
,
256 .ui_set_custom_data
= NULL
,
260 .process
= midigain_process
,
268 // -----------------------------------------------------------------------
270 void carla_register_native_plugin_midigain(void);
272 void carla_register_native_plugin_midigain(void)
274 carla_register_native_plugin(&midigainDesc
);
277 // -----------------------------------------------------------------------