DISTRHO ndc Plugs
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.

271 lines
7.7KB

  1. /*
  2. * DISTRHO AmplitudeImposer, a DPF'ied AmplitudeImposer.
  3. * Copyright (C) 2004 Niall Moody
  4. * Copyright (C) 2015 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a
  7. * copy of this software and associated documentation files (the "Software"),
  8. * to deal in the Software without restriction, including without limitation
  9. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10. * and/or sell copies of the Software, and to permit persons to whom the
  11. * Software is furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  21. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. * DEALINGS IN THE SOFTWARE.
  23. */
  24. #include "DistrhoPluginAmplitudeImposer.hpp"
  25. START_NAMESPACE_DISTRHO
  26. // -----------------------------------------------------------------------
  27. struct twofloats {
  28. float left;
  29. float right;
  30. };
  31. // -----------------------------------------------------------------------
  32. DistrhoPluginAmplitudeImposer::DistrhoPluginAmplitudeImposer()
  33. : Plugin(kParameterCount, 1, 0), // 1 program, 0 states
  34. fDepth(1.0f),
  35. fThreshold(0.5f),
  36. ampEnvelope_l(0.0f),
  37. ampEnvelope_r(0.0f),
  38. audioEnvelope_l(0.0f),
  39. audioEnvelope_r(0.0f),
  40. envDecay(0.0001f) {}
  41. // -----------------------------------------------------------------------
  42. // Init
  43. void DistrhoPluginAmplitudeImposer::initAudioPort(bool input, uint32_t index, AudioPort& port)
  44. {
  45. port.hints = 0x0;
  46. if (input)
  47. {
  48. switch (index)
  49. {
  50. case 0:
  51. port.name = "Input Left (Amp Env)";
  52. port.symbol = "in_left_amp";
  53. break;
  54. case 1:
  55. port.name = "Input Right (Amp Env)";
  56. port.symbol = "in_left_amp";
  57. break;
  58. case 2:
  59. port.name = "Input Left (Audio)";
  60. port.symbol = "in_left_audio";
  61. break;
  62. case 3:
  63. port.name = "Input Right (Audio)";
  64. port.symbol = "in_right_audio";
  65. break;
  66. }
  67. }
  68. else
  69. {
  70. switch (index)
  71. {
  72. case 0:
  73. port.name = "Output Left";
  74. port.symbol = "out_left";
  75. break;
  76. case 1:
  77. port.name = "Output Right";
  78. port.symbol = "out_left";
  79. break;
  80. }
  81. }
  82. }
  83. void DistrhoPluginAmplitudeImposer::initParameter(uint32_t index, Parameter& parameter)
  84. {
  85. parameter.hints = kParameterIsAutomable;
  86. parameter.ranges.min = 0.0f;
  87. parameter.ranges.max = 1.0f;
  88. switch (index)
  89. {
  90. case kParameterDepth:
  91. parameter.name = "Depth";
  92. parameter.symbol = "depth";
  93. parameter.ranges.def = 1.0f;
  94. break;
  95. case kParameterThreshold:
  96. parameter.name = "Thres";
  97. parameter.symbol = "thres";
  98. parameter.ranges.def = 0.5f;
  99. break;
  100. }
  101. }
  102. void DistrhoPluginAmplitudeImposer::initProgramName(uint32_t index, String& programName)
  103. {
  104. if (index != 0)
  105. return
  106. programName = "Default";
  107. }
  108. // -----------------------------------------------------------------------
  109. // Internal data
  110. float DistrhoPluginAmplitudeImposer::getParameterValue(uint32_t index) const
  111. {
  112. switch(index)
  113. {
  114. case kParameterDepth:
  115. return fDepth;
  116. case kParameterThreshold:
  117. return fThreshold;
  118. default:
  119. return 0.0f;
  120. }
  121. }
  122. void DistrhoPluginAmplitudeImposer::setParameterValue(uint32_t index, float value)
  123. {
  124. switch(index)
  125. {
  126. case kParameterDepth:
  127. fDepth = value;
  128. break;
  129. case kParameterThreshold:
  130. fThreshold = value;
  131. break;
  132. }
  133. }
  134. void DistrhoPluginAmplitudeImposer::loadProgram(uint32_t index)
  135. {
  136. if (index != 0)
  137. return
  138. fDepth = 1.0f;
  139. fThreshold = 0.5f;
  140. }
  141. // -----------------------------------------------------------------------
  142. // Process
  143. void DistrhoPluginAmplitudeImposer::activate()
  144. {
  145. ampEnvelope_l = 0.0f;
  146. ampEnvelope_r = 0.0f;
  147. audioEnvelope_l = 0.0f;
  148. audioEnvelope_r = 0.0f;
  149. envDecay = 0.0001f;
  150. }
  151. void DistrhoPluginAmplitudeImposer::run(const float** inputs, float** outputs, uint32_t frames)
  152. {
  153. const float* const in1 = inputs[0];
  154. const float* const in2 = inputs[1];
  155. const float* const in3 = inputs[2];
  156. const float* const in4 = inputs[3];
  157. /* */ float* const out1 = outputs[0];
  158. /* */ float* const out2 = outputs[1];
  159. float tmp;
  160. twofloats tempf;
  161. twofloats tempin;
  162. for (uint32_t i=0; i<frames; ++i)
  163. {
  164. // calculate envelope from 1st two inputs
  165. tmp = std::abs(in1[i]);
  166. /**/ if (tmp > ampEnvelope_l)
  167. ampEnvelope_l = tmp;
  168. else if (tmp < ampEnvelope_l)
  169. ampEnvelope_l -= envDecay;
  170. tmp = std::abs(in2[i]);
  171. /**/ if (tmp > ampEnvelope_r)
  172. ampEnvelope_r = tmp;
  173. else if (tmp < ampEnvelope_r)
  174. ampEnvelope_r -= envDecay;
  175. // calculate envelope from 2nd two inputs
  176. tmp = std::abs(in3[i]);
  177. /**/ if (tmp > audioEnvelope_l)
  178. audioEnvelope_l = tmp;
  179. else if (tmp < audioEnvelope_l)
  180. audioEnvelope_l -= envDecay;
  181. tmp = std::abs(in4[i]);
  182. /**/ if (tmp > audioEnvelope_r)
  183. audioEnvelope_r = tmp;
  184. else if (tmp < audioEnvelope_r)
  185. audioEnvelope_r -= envDecay;
  186. // make sure we're not multiplying by a negative number
  187. if (ampEnvelope_l < 0.0f)
  188. ampEnvelope_l = 0.0f;
  189. if (ampEnvelope_r < 0.0f)
  190. ampEnvelope_r = 0.0f;
  191. if (audioEnvelope_l < 0.0f)
  192. audioEnvelope_l = 0.0f;
  193. if (audioEnvelope_r < 0.0f)
  194. audioEnvelope_r = 0.0f;
  195. // work out whether we need to multiply audio input
  196. if (audioEnvelope_l > fThreshold)
  197. {
  198. tempin.left = in3[i];
  199. }
  200. else
  201. {
  202. if (audioEnvelope_l > 0.001f)
  203. tempin.left = in3[i] * (fThreshold/audioEnvelope_l);
  204. else
  205. tempin.left = in3[i] * (fThreshold/0.001f); //so it'll decay away smoothly
  206. }
  207. if (audioEnvelope_r > fThreshold)
  208. {
  209. tempin.right = in4[i];
  210. }
  211. else
  212. {
  213. if (audioEnvelope_r > 0.001f)
  214. tempin.right = in4[i] * (fThreshold/audioEnvelope_r);
  215. else
  216. tempin.right = in4[i] * (fThreshold/0.001f);
  217. }
  218. // calculate output
  219. tempf.left = tempin.left * ampEnvelope_l;
  220. tempf.left *= fDepth;
  221. tempf.left = tempf.left + ((1.0f-fDepth)*tempin.left);
  222. tempf.right = tempin.right * ampEnvelope_r;
  223. tempf.right *= fDepth;
  224. tempf.right = tempf.right + ((1.0f-fDepth)*tempin.right);
  225. out1[i] = tempf.left;
  226. out2[i] = tempf.right;
  227. }
  228. }
  229. // -----------------------------------------------------------------------
  230. Plugin* createPlugin()
  231. {
  232. return new DistrhoPluginAmplitudeImposer();
  233. }
  234. // -----------------------------------------------------------------------
  235. END_NAMESPACE_DISTRHO