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.

312 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 GPL.txt file
  16. */
  17. #include "CarlaNative.h"
  18. #include "CarlaMIDI.h"
  19. #include <math.h>
  20. #include <stdlib.h>
  21. typedef enum _LfoParams {
  22. PARAM_MODE = 0,
  23. PARAM_SPEED = 1,
  24. PARAM_MULTIPLIER = 2,
  25. PARAM_BASE_START = 3,
  26. PARAM_LFO_OUT = 4,
  27. PARAM_COUNT
  28. } LfoParams;
  29. typedef struct _LfoHandle {
  30. HostDescriptor* host;
  31. int mode;
  32. float speed;
  33. float multiplier;
  34. float baseStart;
  35. float value;
  36. } LfoHandle;
  37. static PluginHandle lfo_instantiate(const PluginDescriptor* _this_, HostDescriptor* host)
  38. {
  39. LfoHandle* const handle = (LfoHandle*)malloc(sizeof(LfoHandle));
  40. if (handle != NULL)
  41. {
  42. handle->host = host;
  43. handle->mode = 1;
  44. handle->speed = 1.0f;
  45. handle->multiplier = 1.0f;
  46. handle->baseStart = 0.0f;
  47. handle->value = 0.0f;
  48. return handle;
  49. }
  50. return NULL;
  51. // unused
  52. (void)_this_;
  53. }
  54. #define handlePtr ((LfoHandle*)handle)
  55. static void lfo_cleanup(PluginHandle handle)
  56. {
  57. free(handlePtr);
  58. }
  59. static uint32_t lfo_get_parameter_count(PluginHandle handle)
  60. {
  61. return PARAM_COUNT;
  62. // unused
  63. (void)handle;
  64. }
  65. const Parameter* lfo_get_parameter_info(PluginHandle handle, uint32_t index)
  66. {
  67. static Parameter param;
  68. static ParameterScalePoint paramModes[3];
  69. param.hints = PARAMETER_IS_ENABLED|PARAMETER_IS_AUTOMABLE;
  70. param.scalePointCount = 0;
  71. param.scalePoints = NULL;
  72. paramModes[0].label = "Type 1";
  73. paramModes[1].label = "Type 2";
  74. paramModes[2].label = "Type 3";
  75. paramModes[0].value = 1.0f;
  76. paramModes[1].value = 2.0f;
  77. paramModes[2].value = 3.0f;
  78. switch (index)
  79. {
  80. case PARAM_MODE:
  81. param.name = "Mode";
  82. param.unit = NULL;
  83. param.hints |= PARAMETER_IS_INTEGER|PARAMETER_USES_SCALEPOINTS;
  84. param.ranges.def = 1.0f;
  85. param.ranges.min = 1.0f;
  86. param.ranges.max = 3.0f;
  87. param.ranges.step = 1.0f;
  88. param.ranges.stepSmall = 1.0f;
  89. param.ranges.stepLarge = 1.0f;
  90. param.scalePointCount = 3;
  91. param.scalePoints = paramModes;
  92. break;
  93. case PARAM_SPEED:
  94. param.name = "Speed";
  95. param.unit = "(coef)";
  96. param.ranges.def = 1.0f;
  97. param.ranges.min = 0.1f;
  98. param.ranges.max = 2.0f;
  99. param.ranges.step = 0.25f;
  100. param.ranges.stepSmall = 0.1f;
  101. param.ranges.stepLarge = 0.5f;
  102. break;
  103. case PARAM_MULTIPLIER:
  104. param.name = "Multiplier";
  105. param.unit = "(coef)";
  106. param.ranges.def = 1.0f;
  107. param.ranges.min = 0.0f;
  108. param.ranges.max = 2.0f;
  109. param.ranges.step = 0.01f;
  110. param.ranges.stepSmall = 0.0001f;
  111. param.ranges.stepLarge = 0.1f;
  112. break;
  113. case PARAM_BASE_START:
  114. param.name = "Start value";
  115. param.unit = NULL;
  116. param.ranges.def = -1.0f;
  117. param.ranges.min = 0.0f;
  118. param.ranges.max = 1.0f;
  119. param.ranges.step = 0.01f;
  120. param.ranges.stepSmall = 0.0001f;
  121. param.ranges.stepLarge = 0.1f;
  122. break;
  123. case PARAM_LFO_OUT:
  124. param.name = "LFO Out";
  125. param.unit = NULL;
  126. param.hints |= PARAMETER_IS_OUTPUT;
  127. param.ranges.def = 0.0f;
  128. param.ranges.min = 0.0f;
  129. param.ranges.max = 1.0f;
  130. param.ranges.step = 0.01f;
  131. param.ranges.stepSmall = 0.0001f;
  132. param.ranges.stepLarge = 0.1f;
  133. break;
  134. }
  135. return &param;
  136. // unused
  137. (void)handle;
  138. }
  139. static float lfo_get_parameter_value(PluginHandle handle, uint32_t index)
  140. {
  141. switch (index)
  142. {
  143. case PARAM_MODE:
  144. return (float)handlePtr->mode;
  145. case PARAM_SPEED:
  146. return handlePtr->speed;
  147. case PARAM_MULTIPLIER:
  148. return handlePtr->multiplier;
  149. case PARAM_BASE_START:
  150. return handlePtr->baseStart;
  151. case PARAM_LFO_OUT:
  152. return handlePtr->value;
  153. default:
  154. return 0.0f;
  155. }
  156. }
  157. static void lfo_set_parameter_value(PluginHandle handle, uint32_t index, float value)
  158. {
  159. switch (index)
  160. {
  161. case PARAM_MODE:
  162. handlePtr->mode = (int)value;
  163. break;
  164. case PARAM_SPEED:
  165. handlePtr->speed = value;
  166. break;
  167. case PARAM_MULTIPLIER:
  168. handlePtr->multiplier = value;
  169. break;
  170. case PARAM_BASE_START:
  171. handlePtr->baseStart = value;
  172. break;
  173. case PARAM_LFO_OUT:
  174. handlePtr->value = value;
  175. break;
  176. }
  177. }
  178. static void lfo_process(PluginHandle handle, float** inBuffer, float** outBuffer, uint32_t frames, uint32_t midiEventCount, const MidiEvent* midiEvents)
  179. {
  180. HostDescriptor* const host = handlePtr->host;
  181. const TimeInfo* const timeInfo = host->get_time_info(host->handle);
  182. if (! timeInfo->playing)
  183. return;
  184. const float bpm = timeInfo->bbt.valid ? timeInfo->bbt.beatsPerMinute : 120.0;
  185. const float SR = host->get_sample_rate(host->handle);
  186. const float rate = handlePtr->speed/(bpm/60.0f/SR);
  187. const int rateI = rate;
  188. float value = 0.0f;
  189. switch (handlePtr->mode)
  190. {
  191. case 1:
  192. /* wave: /\/\ */
  193. value = fabs(1.0f-(float)(timeInfo->frame % rateI)/(rate/2.0f));
  194. break;
  195. case 2:
  196. /* wave: /|/|/ */
  197. value = (float)(timeInfo->frame % rateI)/rate;
  198. break;
  199. case 3:
  200. // wave: square
  201. if (timeInfo->frame % rateI <= rateI/2)
  202. value = 1.0f;
  203. else
  204. value = 0.0f;
  205. break;
  206. }
  207. value *= handlePtr->multiplier;
  208. value += handlePtr->baseStart;
  209. if (value < 0.0f)
  210. handlePtr->value = 0.0f;
  211. else if (value > 1.0f)
  212. handlePtr->value = 1.0f;
  213. else
  214. handlePtr->value = value;
  215. return;
  216. // unused
  217. (void)inBuffer;
  218. (void)outBuffer;
  219. (void)frames;
  220. (void)midiEventCount;
  221. (void)midiEvents;
  222. }
  223. #undef handlePtr
  224. // -----------------------------------------------------------------------
  225. static const PluginDescriptor lfoDesc = {
  226. .category = PLUGIN_CATEGORY_NONE,
  227. .hints = PLUGIN_IS_RTSAFE,
  228. .audioIns = 0,
  229. .audioOuts = 0,
  230. .midiIns = 0,
  231. .midiOuts = 0,
  232. .parameterIns = PARAM_COUNT-1,
  233. .parameterOuts = 1,
  234. .name = "LFO",
  235. .label = "lfo",
  236. .maker = "falkTX",
  237. .copyright = "GNU GPL v2+",
  238. .instantiate = lfo_instantiate,
  239. .cleanup = lfo_cleanup,
  240. .get_parameter_count = lfo_get_parameter_count,
  241. .get_parameter_info = lfo_get_parameter_info,
  242. .get_parameter_value = lfo_get_parameter_value,
  243. .get_parameter_text = NULL,
  244. .get_midi_program_count = NULL,
  245. .get_midi_program_info = NULL,
  246. .set_parameter_value = lfo_set_parameter_value,
  247. .set_midi_program = NULL,
  248. .set_custom_data = NULL,
  249. .ui_show = NULL,
  250. .ui_idle = NULL,
  251. .ui_set_parameter_value = NULL,
  252. .ui_set_midi_program = NULL,
  253. .ui_set_custom_data = NULL,
  254. .activate = NULL,
  255. .deactivate = NULL,
  256. .process = lfo_process,
  257. .get_state = NULL,
  258. .set_state = NULL,
  259. .dispatcher = NULL
  260. };
  261. // -----------------------------------------------------------------------
  262. void carla_register_native_plugin_lfo()
  263. {
  264. carla_register_native_plugin(&lfoDesc);
  265. }
  266. // -----------------------------------------------------------------------