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.

278 lines
7.8KB

  1. /*
  2. * Carla Native Plugins
  3. * Copyright (C) 2012-2019 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. static 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 = NATIVE_PARAMETER_IS_ENABLED|NATIVE_PARAMETER_IS_AUTOMATABLE;
  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 |= NATIVE_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 |= NATIVE_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 |= NATIVE_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. // FIXME for v3.0, use const for the input buffer
  150. static void midigain_process(NativePluginHandle handle,
  151. float** inBuffer, float** outBuffer, uint32_t frames,
  152. const NativeMidiEvent* midiEvents, uint32_t midiEventCount)
  153. {
  154. const NativeHostDescriptor* const host = handlePtr->host;
  155. const float gain = handlePtr->gain;
  156. const bool applyNotes = handlePtr->applyNotes;
  157. const bool applyAftertouch = handlePtr->applyAftertouch;
  158. const bool applyCC = handlePtr->applyCC;
  159. NativeMidiEvent tmpEvent;
  160. for (uint32_t i=0; i < midiEventCount; ++i)
  161. {
  162. const NativeMidiEvent* const midiEvent = &midiEvents[i];
  163. const uint8_t status = (uint8_t)MIDI_GET_STATUS_FROM_DATA(midiEvent->data);
  164. if (midiEvent->size == 3 && ((applyNotes && (status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON)) ||
  165. (applyAftertouch && status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH) ||
  166. (applyCC && status == MIDI_STATUS_CONTROL_CHANGE)))
  167. {
  168. memcpy(&tmpEvent, midiEvent, sizeof(NativeMidiEvent));
  169. float value = (float)midiEvent->data[2] * gain;
  170. if (value <= 0.0f)
  171. tmpEvent.data[2] = 0;
  172. else if (value >= 127.0f)
  173. tmpEvent.data[2] = 127;
  174. else
  175. tmpEvent.data[2] = (uint8_t)value;
  176. host->write_midi_event(host->handle, &tmpEvent);
  177. }
  178. else
  179. host->write_midi_event(host->handle, midiEvent);
  180. }
  181. return;
  182. // unused
  183. (void)inBuffer;
  184. (void)outBuffer;
  185. (void)frames;
  186. }
  187. // -----------------------------------------------------------------------
  188. static const NativePluginDescriptor midigainDesc = {
  189. .category = NATIVE_PLUGIN_CATEGORY_UTILITY,
  190. .hints = NATIVE_PLUGIN_IS_RTSAFE,
  191. .supports = NATIVE_PLUGIN_SUPPORTS_EVERYTHING,
  192. .audioIns = 0,
  193. .audioOuts = 0,
  194. .cvIns = 0,
  195. .cvOuts = 0,
  196. .midiIns = 1,
  197. .midiOuts = 1,
  198. .paramIns = 0,
  199. .paramOuts = 0,
  200. .name = "MIDI Gain",
  201. .label = "midigain",
  202. .maker = "falkTX",
  203. .copyright = "GNU GPL v2+",
  204. .instantiate = midigain_instantiate,
  205. .cleanup = midigain_cleanup,
  206. .get_parameter_count = midigain_get_parameter_count,
  207. .get_parameter_info = midigain_get_parameter_info,
  208. .get_parameter_value = midigain_get_parameter_value,
  209. .get_midi_program_count = NULL,
  210. .get_midi_program_info = NULL,
  211. .set_parameter_value = midigain_set_parameter_value,
  212. .set_midi_program = NULL,
  213. .set_custom_data = NULL,
  214. .ui_show = NULL,
  215. .ui_idle = NULL,
  216. .ui_set_parameter_value = NULL,
  217. .ui_set_midi_program = NULL,
  218. .ui_set_custom_data = NULL,
  219. .activate = NULL,
  220. .deactivate = NULL,
  221. .process = midigain_process,
  222. .get_state = NULL,
  223. .set_state = NULL,
  224. .dispatcher = NULL
  225. };
  226. // -----------------------------------------------------------------------
  227. void carla_register_native_plugin_midigain(void);
  228. void carla_register_native_plugin_midigain(void)
  229. {
  230. carla_register_native_plugin(&midigainDesc);
  231. }
  232. // -----------------------------------------------------------------------