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.

275 lines
7.8KB

  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. switch(index)
  105. {
  106. case 0:
  107. programName = "Default";
  108. break;
  109. }
  110. }
  111. // -----------------------------------------------------------------------
  112. // Internal data
  113. float DistrhoPluginAmplitudeImposer::getParameterValue(uint32_t index) const
  114. {
  115. switch(index)
  116. {
  117. case kParameterDepth:
  118. return fDepth;
  119. case kParameterThreshold:
  120. return fThreshold;
  121. default:
  122. return 0.0f;
  123. }
  124. }
  125. void DistrhoPluginAmplitudeImposer::setParameterValue(uint32_t index, float value)
  126. {
  127. switch(index)
  128. {
  129. case kParameterDepth:
  130. fDepth = value;
  131. break;
  132. case kParameterThreshold:
  133. fThreshold = value;
  134. break;
  135. }
  136. }
  137. void DistrhoPluginAmplitudeImposer::loadProgram(uint32_t index)
  138. {
  139. switch(index)
  140. {
  141. case 0:
  142. fDepth = 1.0f;
  143. fThreshold = 0.5f;
  144. break;
  145. }
  146. }
  147. // -----------------------------------------------------------------------
  148. // Process
  149. void DistrhoPluginAmplitudeImposer::activate()
  150. {
  151. ampEnvelope_l = 0.0f;
  152. ampEnvelope_r = 0.0f;
  153. audioEnvelope_l = 0.0f;
  154. audioEnvelope_r = 0.0f;
  155. envDecay = 0.0001f;
  156. }
  157. void DistrhoPluginAmplitudeImposer::run(const float** inputs, float** outputs, uint32_t frames)
  158. {
  159. const float* const in1 = inputs[0];
  160. const float* const in2 = inputs[1];
  161. const float* const in3 = inputs[2];
  162. const float* const in4 = inputs[3];
  163. /* */ float* const out1 = outputs[0];
  164. /* */ float* const out2 = outputs[1];
  165. float tmp;
  166. twofloats tempf;
  167. twofloats tempin;
  168. for (uint32_t i=0; i<frames; ++i)
  169. {
  170. // calculate envelope from 1st two inputs
  171. tmp = std::abs(in1[i]);
  172. /**/ if (tmp > ampEnvelope_l)
  173. ampEnvelope_l = tmp;
  174. else if (tmp < ampEnvelope_l)
  175. ampEnvelope_l -= envDecay;
  176. tmp = std::abs(in2[i]);
  177. /**/ if (tmp > ampEnvelope_r)
  178. ampEnvelope_r = tmp;
  179. else if (tmp < ampEnvelope_r)
  180. ampEnvelope_r -= envDecay;
  181. // calculate envelope from 2nd two inputs
  182. tmp = std::abs(in3[i]);
  183. /**/ if (tmp > audioEnvelope_l)
  184. audioEnvelope_l = tmp;
  185. else if (tmp < audioEnvelope_l)
  186. audioEnvelope_l -= envDecay;
  187. tmp = std::abs(in4[i]);
  188. /**/ if (tmp > audioEnvelope_r)
  189. audioEnvelope_r = tmp;
  190. else if (tmp < audioEnvelope_r)
  191. audioEnvelope_r -= envDecay;
  192. // make sure we're not multiplying by a negative number
  193. if (ampEnvelope_l < 0.0f)
  194. ampEnvelope_l = 0.0f;
  195. if (ampEnvelope_r < 0.0f)
  196. ampEnvelope_r = 0.0f;
  197. if (audioEnvelope_l < 0.0f)
  198. audioEnvelope_l = 0.0f;
  199. if (audioEnvelope_r < 0.0f)
  200. audioEnvelope_r = 0.0f;
  201. // work out whether we need to multiply audio input
  202. if (audioEnvelope_l > fThreshold)
  203. {
  204. tempin.left = in3[i];
  205. }
  206. else
  207. {
  208. if (audioEnvelope_l > 0.001f)
  209. tempin.left = in3[i] * (fThreshold/audioEnvelope_l);
  210. else
  211. tempin.left = in3[i] * (fThreshold/0.001f); //so it'll decay away smoothly
  212. }
  213. if (audioEnvelope_r > fThreshold)
  214. {
  215. tempin.right = in4[i];
  216. }
  217. else
  218. {
  219. if (audioEnvelope_r > 0.001f)
  220. tempin.right = in4[i] * (fThreshold/audioEnvelope_r);
  221. else
  222. tempin.right = in4[i] * (fThreshold/0.001f);
  223. }
  224. // calculate output
  225. tempf.left = tempin.left * ampEnvelope_l;
  226. tempf.left *= fDepth;
  227. tempf.left = tempf.left + ((1.0f-fDepth)*tempin.left);
  228. tempf.right = tempin.right * ampEnvelope_r;
  229. tempf.right *= fDepth;
  230. tempf.right = tempf.right + ((1.0f-fDepth)*tempin.right);
  231. out1[i] = tempf.left;
  232. out2[i] = tempf.right;
  233. }
  234. }
  235. // -----------------------------------------------------------------------
  236. Plugin* createPlugin()
  237. {
  238. return new DistrhoPluginAmplitudeImposer();
  239. }
  240. // -----------------------------------------------------------------------
  241. END_NAMESPACE_DISTRHO