Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

midi-gain.c 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2012-2013 Filipe Coelho <falktx@falktx.com>
  4. *
  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.
  9. *
  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.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #include "CarlaNative.h"
  18. #include "CarlaMIDI.h"
  19. #include <stdlib.h>
  20. #include <string.h>
  21. // -----------------------------------------------------------------------
  22. typedef enum {
  23. PARAM_GAIN = 0,
  24. PARAM_APPLY_NOTES,
  25. PARAM_APPLY_AFTERTOUCH,
  26. PARAM_APPLY_CC,
  27. PARAM_COUNT
  28. } MidiGainParams;
  29. typedef struct {
  30. const NativeHostDescriptor* host;
  31. float gain;
  32. bool applyNotes;
  33. bool applyAftertouch;
  34. bool applyCC;
  35. } MidiGainHandle;
  36. // -----------------------------------------------------------------------
  37. static NativePluginHandle midiGain_instantiate(const NativeHostDescriptor* host)
  38. {
  39. MidiGainHandle* const handle = (MidiGainHandle*)malloc(sizeof(MidiGainHandle));
  40. if (handle == NULL)
  41. return NULL;
  42. handle->host = host;
  43. handle->gain = 1.0f;
  44. handle->applyNotes = true;
  45. handle->applyAftertouch = true;
  46. handle->applyCC = false;
  47. return handle;
  48. }
  49. #define handlePtr ((MidiGainHandle*)handle)
  50. static void midiGain_cleanup(NativePluginHandle handle)
  51. {
  52. free(handlePtr);
  53. }
  54. static uint32_t midiGain_get_parameter_count(NativePluginHandle handle)
  55. {
  56. return PARAM_COUNT;
  57. // unused
  58. (void)handle;
  59. }
  60. const NativeParameter* midiGain_get_parameter_info(NativePluginHandle handle, uint32_t index)
  61. {
  62. if (index > PARAM_COUNT)
  63. return NULL;
  64. static NativeParameter param;
  65. param.hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  66. param.unit = NULL;
  67. param.scalePointCount = 0;
  68. param.scalePoints = NULL;
  69. switch (index)
  70. {
  71. case PARAM_GAIN:
  72. param.name = "Gain";
  73. param.ranges.def = 1.0f;
  74. param.ranges.min = 0.001f;
  75. param.ranges.max = 4.0f;
  76. param.ranges.step = PARAMETER_RANGES_DEFAULT_STEP;
  77. param.ranges.stepSmall = PARAMETER_RANGES_DEFAULT_STEP_SMALL;
  78. param.ranges.stepLarge = PARAMETER_RANGES_DEFAULT_STEP_LARGE;
  79. break;
  80. case PARAM_APPLY_NOTES:
  81. param.name = "Apply Notes";
  82. param.hints |= PARAMETER_IS_BOOLEAN;
  83. param.ranges.def = 1.0f;
  84. param.ranges.min = 0.0f;
  85. param.ranges.max = 1.0f;
  86. param.ranges.step = 1.0f;
  87. param.ranges.stepSmall = 1.0f;
  88. param.ranges.stepLarge = 1.0f;
  89. break;
  90. case PARAM_APPLY_AFTERTOUCH:
  91. param.name = "Apply Aftertouch";
  92. param.hints |= PARAMETER_IS_BOOLEAN;
  93. param.ranges.def = 1.0f;
  94. param.ranges.min = 0.0f;
  95. param.ranges.max = 1.0f;
  96. param.ranges.step = 1.0f;
  97. param.ranges.stepSmall = 1.0f;
  98. param.ranges.stepLarge = 1.0f;
  99. break;
  100. case PARAM_APPLY_CC:
  101. param.name = "Apply CC";
  102. param.hints |= PARAMETER_IS_BOOLEAN;
  103. param.ranges.def = 0.0f;
  104. param.ranges.min = 0.0f;
  105. param.ranges.max = 1.0f;
  106. param.ranges.step = 1.0f;
  107. param.ranges.stepSmall = 1.0f;
  108. param.ranges.stepLarge = 1.0f;
  109. break;
  110. }
  111. return &param;
  112. // unused
  113. (void)handle;
  114. }
  115. static float midiGain_get_parameter_value(NativePluginHandle handle, uint32_t index)
  116. {
  117. switch (index)
  118. {
  119. case PARAM_GAIN:
  120. return handlePtr->gain;
  121. case PARAM_APPLY_NOTES:
  122. return handlePtr->applyNotes ? 1.0f : 0.0f;
  123. case PARAM_APPLY_AFTERTOUCH:
  124. return handlePtr->applyAftertouch ? 1.0f : 0.0f;
  125. case PARAM_APPLY_CC:
  126. return handlePtr->applyCC ? 1.0f : 0.0f;
  127. default:
  128. return 0.0f;
  129. }
  130. }
  131. static void midiGain_set_parameter_value(NativePluginHandle handle, uint32_t index, float value)
  132. {
  133. switch (index)
  134. {
  135. case PARAM_GAIN:
  136. handlePtr->gain = value;
  137. break;
  138. case PARAM_APPLY_NOTES:
  139. handlePtr->applyNotes = (value >= 0.5f);
  140. break;
  141. case PARAM_APPLY_AFTERTOUCH:
  142. handlePtr->applyAftertouch = (value >= 0.5f);
  143. break;
  144. case PARAM_APPLY_CC:
  145. handlePtr->applyCC = (value >= 0.5f);
  146. break;
  147. }
  148. }
  149. static void midiGain_process(NativePluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
  150. {
  151. const NativeHostDescriptor* const host = handlePtr->host;
  152. const float gain = handlePtr->gain;
  153. const bool applyNotes = handlePtr->applyNotes;
  154. const bool applyAftertouch = handlePtr->applyAftertouch;
  155. const bool applyCC = handlePtr->applyCC;
  156. NativeMidiEvent tmpEvent;
  157. for (uint32_t i=0; i < midiEventCount; ++i)
  158. {
  159. const NativeMidiEvent* const midiEvent = &midiEvents[i];
  160. const uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent->data);
  161. if (midiEvent->size == 3 && ((applyNotes && (status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON)) ||
  162. (applyAftertouch && status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH) ||
  163. (applyCC && status == MIDI_STATUS_CONTROL_CHANGE)))
  164. {
  165. memcpy(&tmpEvent, midiEvent, sizeof(NativeMidiEvent));
  166. float value = (float)midiEvent->data[2] * gain;
  167. if (value <= 0.0f)
  168. tmpEvent.data[2] = 0;
  169. else if (value >= 1.27f)
  170. tmpEvent.data[2] = 127;
  171. else
  172. tmpEvent.data[2] = (uint8_t)value;
  173. host->write_midi_event(host->handle, &tmpEvent);
  174. }
  175. else
  176. host->write_midi_event(host->handle, midiEvent);
  177. }
  178. return;
  179. // unused
  180. (void)inBuffer;
  181. (void)outBuffer;
  182. (void)frames;
  183. }
  184. // -----------------------------------------------------------------------
  185. static const NativePluginDescriptor midiGainDesc = {
  186. .category = PLUGIN_CATEGORY_UTILITY,
  187. .hints = PLUGIN_IS_RTSAFE,
  188. .supports = PLUGIN_SUPPORTS_EVERYTHING,
  189. .audioIns = 0,
  190. .audioOuts = 0,
  191. .midiIns = 1,
  192. .midiOuts = 1,
  193. .paramIns = 0,
  194. .paramOuts = 0,
  195. .name = "MIDI Gain",
  196. .label = "midiGain",
  197. .maker = "falkTX",
  198. .copyright = "GNU GPL v2+",
  199. .instantiate = midiGain_instantiate,
  200. .cleanup = midiGain_cleanup,
  201. .get_parameter_count = midiGain_get_parameter_count,
  202. .get_parameter_info = midiGain_get_parameter_info,
  203. .get_parameter_value = midiGain_get_parameter_value,
  204. .get_parameter_text = NULL,
  205. .get_midi_program_count = NULL,
  206. .get_midi_program_info = NULL,
  207. .set_parameter_value = midiGain_set_parameter_value,
  208. .set_midi_program = NULL,
  209. .set_custom_data = NULL,
  210. .ui_show = NULL,
  211. .ui_idle = NULL,
  212. .ui_set_parameter_value = NULL,
  213. .ui_set_midi_program = NULL,
  214. .ui_set_custom_data = NULL,
  215. .activate = NULL,
  216. .deactivate = NULL,
  217. .process = midiGain_process,
  218. .get_state = NULL,
  219. .set_state = NULL,
  220. .dispatcher = NULL
  221. };
  222. // -----------------------------------------------------------------------
  223. void carla_register_native_plugin_midiGain()
  224. {
  225. carla_register_native_plugin(&midiGainDesc);
  226. }
  227. // -----------------------------------------------------------------------