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.

278 lines
7.5KB

  1. /*
  2. * ZamComp mono compressor
  3. * Copyright (C) 2014 Damien Zammit <damien@zamaudio.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 "ZamCompPlugin.hpp"
  18. START_NAMESPACE_DISTRHO
  19. // -----------------------------------------------------------------------
  20. ZamCompPlugin::ZamCompPlugin()
  21. : Plugin(paramCount, 1, 0) // 1 program, 0 states
  22. {
  23. // set default values
  24. d_setProgram(0);
  25. }
  26. // -----------------------------------------------------------------------
  27. // Init
  28. void ZamCompPlugin::d_initParameter(uint32_t index, Parameter& parameter)
  29. {
  30. switch (index)
  31. {
  32. case paramAttack:
  33. parameter.hints = PARAMETER_IS_AUTOMABLE;
  34. parameter.name = "Attack";
  35. parameter.symbol = "att";
  36. parameter.unit = "ms";
  37. parameter.ranges.def = 10.0f;
  38. parameter.ranges.min = 0.1f;
  39. parameter.ranges.max = 200.0f;
  40. break;
  41. case paramRelease:
  42. parameter.hints = PARAMETER_IS_AUTOMABLE;
  43. parameter.name = "Release";
  44. parameter.symbol = "rel";
  45. parameter.unit = "ms";
  46. parameter.ranges.def = 80.0f;
  47. parameter.ranges.min = 50.0f;
  48. parameter.ranges.max = 500.0f;
  49. break;
  50. case paramKnee:
  51. parameter.hints = PARAMETER_IS_AUTOMABLE;
  52. parameter.name = "Knee";
  53. parameter.symbol = "kn";
  54. parameter.unit = "dB";
  55. parameter.ranges.def = 0.0f;
  56. parameter.ranges.min = 0.0f;
  57. parameter.ranges.max = 8.0f;
  58. break;
  59. case paramRatio:
  60. parameter.hints = PARAMETER_IS_AUTOMABLE;
  61. parameter.name = "Ratio";
  62. parameter.symbol = "rat";
  63. parameter.unit = " ";
  64. parameter.ranges.def = 4.0f;
  65. parameter.ranges.min = 1.0f;
  66. parameter.ranges.max = 20.0f;
  67. break;
  68. case paramThresh:
  69. parameter.hints = PARAMETER_IS_AUTOMABLE;
  70. parameter.name = "Threshold";
  71. parameter.symbol = "thr";
  72. parameter.unit = "dB";
  73. parameter.ranges.def = 0.0f;
  74. parameter.ranges.min = -60.0f;
  75. parameter.ranges.max = 0.0f;
  76. break;
  77. case paramMakeup:
  78. parameter.hints = PARAMETER_IS_AUTOMABLE;
  79. parameter.name = "Makeup";
  80. parameter.symbol = "mak";
  81. parameter.unit = "dB";
  82. parameter.ranges.def = 0.0f;
  83. parameter.ranges.min = -30.0f;
  84. parameter.ranges.max = 30.0f;
  85. break;
  86. case paramGainR:
  87. parameter.hints = PARAMETER_IS_OUTPUT;
  88. parameter.name = "Gain Reduction";
  89. parameter.symbol = "gr";
  90. parameter.unit = "dB";
  91. parameter.ranges.def = 0.0f;
  92. parameter.ranges.min = 0.0f;
  93. parameter.ranges.max = 40.0f;
  94. break;
  95. case paramOutputLevel:
  96. parameter.hints = PARAMETER_IS_OUTPUT;
  97. parameter.name = "Output Level";
  98. parameter.symbol = "outlevel";
  99. parameter.unit = "dB";
  100. parameter.ranges.def = -45.0f;
  101. parameter.ranges.min = -45.0f;
  102. parameter.ranges.max = 20.0f;
  103. break;
  104. }
  105. }
  106. void ZamCompPlugin::d_initProgramName(uint32_t index, d_string& programName)
  107. {
  108. if (index != 0)
  109. return;
  110. programName = "Default";
  111. }
  112. // -----------------------------------------------------------------------
  113. // Internal data
  114. float ZamCompPlugin::d_getParameterValue(uint32_t index) const
  115. {
  116. switch (index)
  117. {
  118. case paramAttack:
  119. return attack;
  120. break;
  121. case paramRelease:
  122. return release;
  123. break;
  124. case paramKnee:
  125. return knee;
  126. break;
  127. case paramRatio:
  128. return ratio;
  129. break;
  130. case paramThresh:
  131. return thresdb;
  132. break;
  133. case paramMakeup:
  134. return makeup;
  135. break;
  136. case paramGainR:
  137. return gainr;
  138. break;
  139. case paramOutputLevel:
  140. return outlevel;
  141. break;
  142. default:
  143. return 0.0f;
  144. }
  145. }
  146. void ZamCompPlugin::d_setParameterValue(uint32_t index, float value)
  147. {
  148. switch (index)
  149. {
  150. case paramAttack:
  151. attack = value;
  152. break;
  153. case paramRelease:
  154. release = value;
  155. break;
  156. case paramKnee:
  157. knee = value;
  158. break;
  159. case paramRatio:
  160. ratio = value;
  161. break;
  162. case paramThresh:
  163. thresdb = value;
  164. break;
  165. case paramMakeup:
  166. makeup = value;
  167. break;
  168. case paramGainR:
  169. gainr = value;
  170. break;
  171. case paramOutputLevel:
  172. outlevel = value;
  173. break;
  174. }
  175. }
  176. void ZamCompPlugin::d_setProgram(uint32_t index)
  177. {
  178. if (index != 0)
  179. return;
  180. /* Default parameter values */
  181. attack = 10.0f;
  182. release = 80.0f;
  183. knee = 0.0f;
  184. ratio = 4.0f;
  185. thresdb = 0.0f;
  186. makeup = 0.0f;
  187. /* reset filter values */
  188. d_activate();
  189. }
  190. // -----------------------------------------------------------------------
  191. // Process
  192. void ZamCompPlugin::d_activate()
  193. {
  194. gainr = 0.0f;
  195. outlevel = -45.f;
  196. old_yl = old_y1 = 0.0f;
  197. }
  198. void ZamCompPlugin::d_run(const float** inputs, float** outputs, uint32_t frames)
  199. {
  200. float srate = d_getSampleRate();
  201. float width=(knee-0.99f)*6.f;
  202. float cdb=0.f;
  203. float attack_coeff = exp(-1000.f/(attack * srate));
  204. float release_coeff = exp(-1000.f/(release * srate));
  205. float gain = 1.f;
  206. float xg, xl, yg, yl, y1;
  207. uint32_t i;
  208. float max = 0.f;
  209. for (i = 0; i < frames; i++) {
  210. yg=0.f;
  211. xg = (inputs[0][i]==0.f) ? -160.f : to_dB(fabs(inputs[0][i]));
  212. xg = sanitize_denormal(xg);
  213. if (2.f*(xg-thresdb)<-width) {
  214. yg = xg;
  215. } else if (2.f*fabs(xg-thresdb)<=width) {
  216. yg = xg + (1.f/ratio-1.f)*(xg-thresdb+width/2.f)*(xg-thresdb+width/2.f)/(2.f*width);
  217. } else if (2.f*(xg-thresdb)>width) {
  218. yg = thresdb + (xg-thresdb)/ratio;
  219. }
  220. yg = sanitize_denormal(yg);
  221. xl = xg - yg;
  222. old_y1 = sanitize_denormal(old_y1);
  223. old_yl = sanitize_denormal(old_yl);
  224. y1 = fmaxf(xl, release_coeff * old_y1+(1.f-release_coeff)*xl);
  225. yl = attack_coeff * old_yl+(1.f-attack_coeff)*y1;
  226. y1 = sanitize_denormal(y1);
  227. yl = sanitize_denormal(yl);
  228. cdb = -yl;
  229. gain = from_dB(cdb);
  230. gainr = yl;
  231. outputs[0][i] = inputs[0][i];
  232. outputs[0][i] *= gain * from_dB(makeup);
  233. max = (fabsf(outputs[0][i]) > max) ? fabsf(outputs[0][i]) : sanitize_denormal(max);
  234. old_yl = yl;
  235. old_y1 = y1;
  236. }
  237. outlevel = (max == 0.f) ? -45.f : to_dB(max);
  238. }
  239. // -----------------------------------------------------------------------
  240. Plugin* createPlugin()
  241. {
  242. return new ZamCompPlugin();
  243. }
  244. // -----------------------------------------------------------------------
  245. END_NAMESPACE_DISTRHO