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.

291 lines
7.6KB

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