DISTRHO Mini-Series
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.

344 lines
9.5KB

  1. /*
  2. * DISTRHO 3BandSplitter Plugin, based on 3BandSplitter by Michael Gruhn
  3. * Copyright (C) 2007 Michael Gruhn <michael-gruhn@web.de>
  4. * Copyright (C) 2012-2015 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation.
  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 Lesser General Public License for more details.
  14. *
  15. * For a full copy of the license see the LICENSE file.
  16. */
  17. #include "DistrhoPlugin3BandSplitter.hpp"
  18. #include <cmath>
  19. static const float kAMP_DB = 8.656170245f;
  20. static const float kDC_ADD = 1e-30f;
  21. static const float kPI = 3.141592654f;
  22. START_NAMESPACE_DISTRHO
  23. // -----------------------------------------------------------------------
  24. DistrhoPlugin3BandSplitter::DistrhoPlugin3BandSplitter()
  25. : Plugin(paramCount, 1, 0) // 1 program, 0 states
  26. {
  27. // set default values
  28. loadProgram(0);
  29. // reset
  30. deactivate();
  31. }
  32. // -----------------------------------------------------------------------
  33. // Init
  34. void DistrhoPlugin3BandSplitter::initAudioPort(bool input, uint32_t index, AudioPort& port)
  35. {
  36. port.hints = 0x0;
  37. if (input)
  38. {
  39. switch (index)
  40. {
  41. case 0:
  42. port.name = "Input Left";
  43. port.symbol = "in_left";
  44. break;
  45. case 1:
  46. port.name = "Input Right";
  47. port.symbol = "in_right";
  48. break;
  49. }
  50. port.groupId = kPortGroupStereo;
  51. }
  52. else
  53. {
  54. switch (index)
  55. {
  56. case 0:
  57. port.name = "Output Left (Low)";
  58. port.symbol = "in_left_low";
  59. port.groupId = kPortGroupLow;
  60. break;
  61. case 1:
  62. port.name = "Output Right (Low)";
  63. port.symbol = "in_right_low";
  64. port.groupId = kPortGroupLow;
  65. break;
  66. case 2:
  67. port.name = "Output Left (Mid)";
  68. port.symbol = "in_left_mid";
  69. port.groupId = kPortGroupMid;
  70. break;
  71. case 3:
  72. port.name = "Output Right (Mid)";
  73. port.symbol = "in_right_mid";
  74. port.groupId = kPortGroupMid;
  75. break;
  76. case 4:
  77. port.name = "Output Left (High)";
  78. port.symbol = "in_left_high";
  79. port.groupId = kPortGroupHigh;
  80. break;
  81. case 5:
  82. port.name = "Output Right (High)";
  83. port.symbol = "in_right_high";
  84. port.groupId = kPortGroupHigh;
  85. break;
  86. }
  87. }
  88. }
  89. void DistrhoPlugin3BandSplitter::initParameter(uint32_t index, Parameter& parameter)
  90. {
  91. switch (index)
  92. {
  93. case paramLow:
  94. parameter.hints = kParameterIsAutomatable;
  95. parameter.name = "Low";
  96. parameter.symbol = "low";
  97. parameter.unit = "dB";
  98. parameter.ranges.def = 0.0f;
  99. parameter.ranges.min = -24.0f;
  100. parameter.ranges.max = 24.0f;
  101. break;
  102. case paramMid:
  103. parameter.hints = kParameterIsAutomatable;
  104. parameter.name = "Mid";
  105. parameter.symbol = "mid";
  106. parameter.unit = "dB";
  107. parameter.ranges.def = 0.0f;
  108. parameter.ranges.min = -24.0f;
  109. parameter.ranges.max = 24.0f;
  110. break;
  111. case paramHigh:
  112. parameter.hints = kParameterIsAutomatable;
  113. parameter.name = "High";
  114. parameter.symbol = "high";
  115. parameter.unit = "dB";
  116. parameter.ranges.def = 0.0f;
  117. parameter.ranges.min = -24.0f;
  118. parameter.ranges.max = 24.0f;
  119. break;
  120. case paramMaster:
  121. parameter.hints = kParameterIsAutomatable;
  122. parameter.name = "Master";
  123. parameter.symbol = "master";
  124. parameter.unit = "dB";
  125. parameter.ranges.def = 0.0f;
  126. parameter.ranges.min = -24.0f;
  127. parameter.ranges.max = 24.0f;
  128. break;
  129. case paramLowMidFreq:
  130. parameter.hints = kParameterIsAutomatable;
  131. parameter.name = "Low-Mid Freq";
  132. parameter.symbol = "low_mid";
  133. parameter.unit = "Hz";
  134. parameter.ranges.def = 440.0f;
  135. parameter.ranges.min = 0.0f;
  136. parameter.ranges.max = 1000.0f;
  137. break;
  138. case paramMidHighFreq:
  139. parameter.hints = kParameterIsAutomatable;
  140. parameter.name = "Mid-High Freq";
  141. parameter.symbol = "mid_high";
  142. parameter.unit = "Hz";
  143. parameter.ranges.def = 1000.0f;
  144. parameter.ranges.min = 1000.0f;
  145. parameter.ranges.max = 20000.0f;
  146. break;
  147. }
  148. }
  149. void DistrhoPlugin3BandSplitter::initPortGroup(uint32_t groupId, PortGroup& portGroup)
  150. {
  151. switch (groupId)
  152. {
  153. case kPortGroupLow:
  154. portGroup.name = "Low";
  155. portGroup.symbol = "low";
  156. break;
  157. case kPortGroupMid:
  158. portGroup.name = "Mid";
  159. portGroup.symbol = "mid";
  160. break;
  161. case kPortGroupHigh:
  162. portGroup.name = "High";
  163. portGroup.symbol = "high";
  164. break;
  165. }
  166. }
  167. void DistrhoPlugin3BandSplitter::initProgramName(uint32_t index, String& programName)
  168. {
  169. if (index != 0)
  170. return;
  171. programName = "Default";
  172. }
  173. // -----------------------------------------------------------------------
  174. // Internal data
  175. float DistrhoPlugin3BandSplitter::getParameterValue(uint32_t index) const
  176. {
  177. switch (index)
  178. {
  179. case paramLow:
  180. return fLow;
  181. case paramMid:
  182. return fMid;
  183. case paramHigh:
  184. return fHigh;
  185. case paramMaster:
  186. return fMaster;
  187. case paramLowMidFreq:
  188. return fLowMidFreq;
  189. case paramMidHighFreq:
  190. return fMidHighFreq;
  191. default:
  192. return 0.0f;
  193. }
  194. }
  195. void DistrhoPlugin3BandSplitter::setParameterValue(uint32_t index, float value)
  196. {
  197. if (getSampleRate() <= 0.0)
  198. return;
  199. switch (index)
  200. {
  201. case paramLow:
  202. fLow = value;
  203. lowVol = std::exp( (fLow/48.0f) * 48.0f / kAMP_DB);
  204. break;
  205. case paramMid:
  206. fMid = value;
  207. midVol = std::exp( (fMid/48.0f) * 48.0f / kAMP_DB);
  208. break;
  209. case paramHigh:
  210. fHigh = value;
  211. highVol = std::exp( (fHigh/48.0f) * 48.0f / kAMP_DB);
  212. break;
  213. case paramMaster:
  214. fMaster = value;
  215. outVol = std::exp( (fMaster/48.0f) * 48.0f / kAMP_DB);
  216. break;
  217. case paramLowMidFreq:
  218. fLowMidFreq = std::fmin(value, fMidHighFreq);
  219. freqLP = fLowMidFreq;
  220. xLP = std::exp(-2.0f * kPI * freqLP / (float)getSampleRate());
  221. a0LP = 1.0f - xLP;
  222. b1LP = -xLP;
  223. break;
  224. case paramMidHighFreq:
  225. fMidHighFreq = std::fmax(value, fLowMidFreq);
  226. freqHP = fMidHighFreq;
  227. xHP = std::exp(-2.0f * kPI * freqHP / (float)getSampleRate());
  228. a0HP = 1.0f - xHP;
  229. b1HP = -xHP;
  230. break;
  231. }
  232. }
  233. void DistrhoPlugin3BandSplitter::loadProgram(uint32_t index)
  234. {
  235. if (index != 0)
  236. return;
  237. // Default values
  238. fLow = 0.0f;
  239. fMid = 0.0f;
  240. fHigh = 0.0f;
  241. fMaster = 0.0f;
  242. fLowMidFreq = 220.0f;
  243. fMidHighFreq = 2000.0f;
  244. // Internal stuff
  245. lowVol = midVol = highVol = outVol = 1.0f;
  246. freqLP = 200.0f;
  247. freqHP = 2000.0f;
  248. // reset filter values
  249. activate();
  250. }
  251. // -----------------------------------------------------------------------
  252. // Process
  253. void DistrhoPlugin3BandSplitter::activate()
  254. {
  255. const float sr = (float)getSampleRate();
  256. xLP = std::exp(-2.0f * kPI * freqLP / sr);
  257. a0LP = 1.0f - xLP;
  258. b1LP = -xLP;
  259. xHP = std::exp(-2.0f * kPI * freqHP / sr);
  260. a0HP = 1.0f - xHP;
  261. b1HP = -xHP;
  262. }
  263. void DistrhoPlugin3BandSplitter::deactivate()
  264. {
  265. out1LP = out2LP = out1HP = out2HP = 0.0f;
  266. tmp1LP = tmp2LP = tmp1HP = tmp2HP = 0.0f;
  267. }
  268. void DistrhoPlugin3BandSplitter::run(const float** inputs, float** outputs, uint32_t frames)
  269. {
  270. const float* in1 = inputs[0];
  271. const float* in2 = inputs[1];
  272. float* out1 = outputs[0];
  273. float* out2 = outputs[1];
  274. float* out3 = outputs[2];
  275. float* out4 = outputs[3];
  276. float* out5 = outputs[4];
  277. float* out6 = outputs[5];
  278. for (uint32_t i=0; i < frames; ++i)
  279. {
  280. tmp1LP = a0LP * in1[i] - b1LP * tmp1LP + kDC_ADD;
  281. tmp2LP = a0LP * in2[i] - b1LP * tmp2LP + kDC_ADD;
  282. out1LP = tmp1LP - kDC_ADD;
  283. out2LP = tmp2LP - kDC_ADD;
  284. tmp1HP = a0HP * in1[i] - b1HP * tmp1HP + kDC_ADD;
  285. tmp2HP = a0HP * in2[i] - b1HP * tmp2HP + kDC_ADD;
  286. out1HP = in1[i] - tmp1HP - kDC_ADD;
  287. out2HP = in2[i] - tmp2HP - kDC_ADD;
  288. out6[i] = out2HP*highVol * outVol;
  289. out5[i] = out1HP*highVol * outVol;
  290. out4[i] = (in2[i] - out2LP - out2HP)*midVol * outVol;
  291. out3[i] = (in1[i] - out1LP - out1HP)*midVol * outVol;
  292. out2[i] = out2LP*lowVol * outVol;
  293. out1[i] = out1LP*lowVol * outVol;
  294. }
  295. }
  296. // -----------------------------------------------------------------------
  297. Plugin* createPlugin()
  298. {
  299. return new DistrhoPlugin3BandSplitter();
  300. }
  301. // -----------------------------------------------------------------------
  302. END_NAMESPACE_DISTRHO