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.

275 lines
7.8KB

  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 PluginHostDescriptor* host;
  31. MappedValue map_midi;
  32. float gain;
  33. bool applyNotes;
  34. bool applyAftertouch;
  35. bool applyCC;
  36. } MidiGainHandle;
  37. // -----------------------------------------------------------------------
  38. static PluginHandle midiGain_instantiate(const PluginHostDescriptor* host)
  39. {
  40. MidiGainHandle* const handle = (MidiGainHandle*)malloc(sizeof(MidiGainHandle));
  41. if (handle == NULL)
  42. return NULL;
  43. handle->host = host;
  44. handle->map_midi = host->map_value(host->handle, EVENT_TYPE_MIDI);
  45. handle->gain = 1.0f;
  46. handle->applyNotes = true;
  47. handle->applyAftertouch = true;
  48. handle->applyCC = false;
  49. return handle;
  50. }
  51. #define handlePtr ((MidiGainHandle*)handle)
  52. static void midiGain_cleanup(PluginHandle handle)
  53. {
  54. free(handlePtr);
  55. }
  56. static uint32_t midiGain_get_parameter_count(PluginHandle handle)
  57. {
  58. return PARAM_COUNT;
  59. // unused
  60. (void)handle;
  61. }
  62. const Parameter* midiGain_get_parameter_info(PluginHandle handle, uint32_t index)
  63. {
  64. if (index > PARAM_COUNT)
  65. return NULL;
  66. static Parameter param;
  67. param.hints = PARAMETER_IS_ENABLED ":" PARAMETER_IS_AUTOMABLE;
  68. param.unit = NULL;
  69. param.scalePointCount = 0;
  70. param.scalePoints = NULL;
  71. switch (index)
  72. {
  73. case PARAM_GAIN:
  74. param.name = "Gain";
  75. param.ranges.def = 1.0f;
  76. param.ranges.min = 0.001f;
  77. param.ranges.max = 4.0f;
  78. param.ranges.step = PARAMETER_RANGE_DEFAULT_STEP;
  79. param.ranges.stepSmall = PARAMETER_RANGE_DEFAULT_STEP_SMALL;
  80. param.ranges.stepLarge = PARAMETER_RANGE_DEFAULT_STEP_LARGE;
  81. break;
  82. case PARAM_APPLY_NOTES:
  83. param.name = "Apply Notes";
  84. param.hints = PARAMETER_IS_ENABLED ":" PARAMETER_IS_AUTOMABLE ":" PARAMETER_IS_BOOLEAN;
  85. param.ranges.def = 1.0f;
  86. param.ranges.min = 0.0f;
  87. param.ranges.max = 1.0f;
  88. param.ranges.step = 1.0f;
  89. param.ranges.stepSmall = 1.0f;
  90. param.ranges.stepLarge = 1.0f;
  91. break;
  92. case PARAM_APPLY_AFTERTOUCH:
  93. param.name = "Apply Aftertouch";
  94. param.hints = PARAMETER_IS_ENABLED ":" PARAMETER_IS_AUTOMABLE ":" PARAMETER_IS_BOOLEAN;
  95. param.ranges.def = 1.0f;
  96. param.ranges.min = 0.0f;
  97. param.ranges.max = 1.0f;
  98. param.ranges.step = 1.0f;
  99. param.ranges.stepSmall = 1.0f;
  100. param.ranges.stepLarge = 1.0f;
  101. break;
  102. case PARAM_APPLY_CC:
  103. param.name = "Apply CC";
  104. param.hints = PARAMETER_IS_ENABLED ":" PARAMETER_IS_AUTOMABLE ":" PARAMETER_IS_BOOLEAN;
  105. param.ranges.def = 0.0f;
  106. param.ranges.min = 0.0f;
  107. param.ranges.max = 1.0f;
  108. param.ranges.step = 1.0f;
  109. param.ranges.stepSmall = 1.0f;
  110. param.ranges.stepLarge = 1.0f;
  111. break;
  112. }
  113. return &param;
  114. // unused
  115. (void)handle;
  116. }
  117. static float midiGain_get_parameter_value(PluginHandle handle, uint32_t index)
  118. {
  119. switch (index)
  120. {
  121. case PARAM_GAIN:
  122. return handlePtr->gain;
  123. case PARAM_APPLY_NOTES:
  124. return handlePtr->applyNotes ? 1.0f : 0.0f;
  125. case PARAM_APPLY_AFTERTOUCH:
  126. return handlePtr->applyAftertouch ? 1.0f : 0.0f;
  127. case PARAM_APPLY_CC:
  128. return handlePtr->applyCC ? 1.0f : 0.0f;
  129. default:
  130. return 0.0f;
  131. }
  132. }
  133. static void midiGain_set_parameter_value(PluginHandle handle, uint32_t index, float value)
  134. {
  135. switch (index)
  136. {
  137. case PARAM_GAIN:
  138. handlePtr->gain = value;
  139. break;
  140. case PARAM_APPLY_NOTES:
  141. handlePtr->applyNotes = (value >= 0.5f);
  142. break;
  143. case PARAM_APPLY_AFTERTOUCH:
  144. handlePtr->applyAftertouch = (value >= 0.5f);
  145. break;
  146. case PARAM_APPLY_CC:
  147. handlePtr->applyCC = (value >= 0.5f);
  148. break;
  149. }
  150. }
  151. static void midiGain_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, const Event* events, uint32_t eventCount)
  152. {
  153. const PluginHostDescriptor* const host = handlePtr->host;
  154. const MappedValue map_midi = handlePtr->map_midi;
  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. MidiEvent tmpEvent;
  160. tmpEvent.e.type = map_midi;
  161. for (uint32_t i=0; i < eventCount; ++i)
  162. {
  163. if (events[i].type != map_midi)
  164. continue;
  165. const MidiEvent* const midiEvent = (const MidiEvent*)&events[i];
  166. const uint8_t status = MIDI_GET_STATUS_FROM_DATA(midiEvent->data);
  167. if (midiEvent->size == 3 && ((applyNotes && (status == MIDI_STATUS_NOTE_OFF || status == MIDI_STATUS_NOTE_ON)) ||
  168. (applyAftertouch && status == MIDI_STATUS_POLYPHONIC_AFTERTOUCH) ||
  169. (applyCC && status == MIDI_STATUS_CONTROL_CHANGE)))
  170. {
  171. memcpy(&tmpEvent, midiEvent, sizeof(MidiEvent));
  172. float value = (float)midiEvent->data[2] * gain;
  173. if (value <= 0.0f)
  174. tmpEvent.data[2] = 0;
  175. else if (value >= 127.0f)
  176. tmpEvent.data[2] = 127;
  177. else
  178. tmpEvent.data[2] = (uint8_t)value;
  179. host->write_event(host->handle, (const Event*)&tmpEvent);
  180. }
  181. else
  182. host->write_event(host->handle, &events[i]);
  183. }
  184. return;
  185. // unused
  186. (void)inBuffer;
  187. (void)outBuffer;
  188. (void)frames;
  189. }
  190. // -----------------------------------------------------------------------
  191. static const PluginDescriptor midiGainDesc = {
  192. .api = CARLA_NATIVE_API_VERSION,
  193. .categories = PLUGIN_CATEGORY_UTILITY ":midi",
  194. .features = "rtsafe",
  195. .supports = PLUGIN_SUPPORTS_EVERYTHING,
  196. .metadata = NULL,
  197. .audioIns = 0,
  198. .audioOuts = 0,
  199. .midiIns = 1,
  200. .midiOuts = 1,
  201. .paramIns = 0,
  202. .paramOuts = 0,
  203. .author = "falkTX",
  204. .name = "MIDI Gain",
  205. .label = "midiGain",
  206. .copyright = "GNU GPL v2+",
  207. .instantiate = midiGain_instantiate,
  208. .cleanup = midiGain_cleanup,
  209. .get_parameter_count = midiGain_get_parameter_count,
  210. .get_parameter_info = midiGain_get_parameter_info,
  211. .get_parameter_value = midiGain_get_parameter_value,
  212. .get_parameter_text = NULL,
  213. .set_parameter_value = midiGain_set_parameter_value,
  214. .get_midi_program_count = NULL,
  215. .get_midi_program_info = NULL,
  216. .set_midi_program = NULL,
  217. .idle = NULL,
  218. .get_state = NULL,
  219. .set_state = NULL,
  220. .activate = NULL,
  221. .deactivate = NULL,
  222. .process = midiGain_process,
  223. .dispatcher = NULL
  224. };
  225. // -----------------------------------------------------------------------
  226. void carla_register_native_plugin_midiGain()
  227. {
  228. carla_register_native_plugin(&midiGainDesc);
  229. }
  230. // -----------------------------------------------------------------------