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.

324 lines
8.2KB

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