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.

266 lines
5.7KB

  1. // Reverb model implementation
  2. //
  3. // Written by Jezar at Dreampoint, June 2000
  4. // http://www.dreampoint.co.uk
  5. // This code is public domain
  6. #include "revmodel.hpp"
  7. revmodel::revmodel()
  8. {
  9. gain = 0.0f;
  10. roomsize = 0.0f;
  11. roomsize1 = 0.0f;
  12. damp = 0.0f;
  13. damp1 = 0.0f;
  14. wet = 0.0f;
  15. wet1 = 0.0f;
  16. wet2 = 0.0f;
  17. dry = 0.0f;
  18. width = 0.0f;
  19. mode = 0.0f;
  20. // Tie the components to their buffers
  21. combL[0].setbuffer(bufcombL1,combtuningL1);
  22. combR[0].setbuffer(bufcombR1,combtuningR1);
  23. combL[1].setbuffer(bufcombL2,combtuningL2);
  24. combR[1].setbuffer(bufcombR2,combtuningR2);
  25. combL[2].setbuffer(bufcombL3,combtuningL3);
  26. combR[2].setbuffer(bufcombR3,combtuningR3);
  27. combL[3].setbuffer(bufcombL4,combtuningL4);
  28. combR[3].setbuffer(bufcombR4,combtuningR4);
  29. combL[4].setbuffer(bufcombL5,combtuningL5);
  30. combR[4].setbuffer(bufcombR5,combtuningR5);
  31. combL[5].setbuffer(bufcombL6,combtuningL6);
  32. combR[5].setbuffer(bufcombR6,combtuningR6);
  33. combL[6].setbuffer(bufcombL7,combtuningL7);
  34. combR[6].setbuffer(bufcombR7,combtuningR7);
  35. combL[7].setbuffer(bufcombL8,combtuningL8);
  36. combR[7].setbuffer(bufcombR8,combtuningR8);
  37. allpassL[0].setbuffer(bufallpassL1,allpasstuningL1);
  38. allpassR[0].setbuffer(bufallpassR1,allpasstuningR1);
  39. allpassL[1].setbuffer(bufallpassL2,allpasstuningL2);
  40. allpassR[1].setbuffer(bufallpassR2,allpasstuningR2);
  41. allpassL[2].setbuffer(bufallpassL3,allpasstuningL3);
  42. allpassR[2].setbuffer(bufallpassR3,allpasstuningR3);
  43. allpassL[3].setbuffer(bufallpassL4,allpasstuningL4);
  44. allpassR[3].setbuffer(bufallpassR4,allpasstuningR4);
  45. // Set default values
  46. allpassL[0].setfeedback(0.5f);
  47. allpassR[0].setfeedback(0.5f);
  48. allpassL[1].setfeedback(0.5f);
  49. allpassR[1].setfeedback(0.5f);
  50. allpassL[2].setfeedback(0.5f);
  51. allpassR[2].setfeedback(0.5f);
  52. allpassL[3].setfeedback(0.5f);
  53. allpassR[3].setfeedback(0.5f);
  54. setwet(initialwet);
  55. setroomsize(initialroom);
  56. setdry(initialdry);
  57. setdamp(initialdamp);
  58. setwidth(initialwidth);
  59. setmode(initialmode);
  60. // Buffer will be full of rubbish - so we MUST mute them
  61. mute();
  62. }
  63. void revmodel::mute()
  64. {
  65. if (getmode() >= freezemode)
  66. return;
  67. for (int i=0;i<numcombs;i++)
  68. {
  69. combL[i].mute();
  70. combR[i].mute();
  71. }
  72. for (int i=0;i<numallpasses;i++)
  73. {
  74. allpassL[i].mute();
  75. allpassR[i].mute();
  76. }
  77. }
  78. void revmodel::processreplace(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
  79. {
  80. float outL,outR,input;
  81. while(numsamples-- > 0)
  82. {
  83. outL = outR = 0;
  84. input = (*inputL + *inputR) * gain;
  85. // Accumulate comb filters in parallel
  86. for(int i=0; i<numcombs; i++)
  87. {
  88. outL += combL[i].process(input);
  89. outR += combR[i].process(input);
  90. }
  91. // Feed through allpasses in series
  92. for(int i=0; i<numallpasses; i++)
  93. {
  94. outL = allpassL[i].process(outL);
  95. outR = allpassR[i].process(outR);
  96. }
  97. // Calculate output REPLACING anything already there
  98. *outputL = outL*wet1 + outR*wet2 + *inputL*dry;
  99. *outputR = outR*wet1 + outL*wet2 + *inputR*dry;
  100. // Increment sample pointers, allowing for interleave (if any)
  101. inputL += skip;
  102. inputR += skip;
  103. outputL += skip;
  104. outputR += skip;
  105. }
  106. }
  107. void revmodel::processmix(float *inputL, float *inputR, float *outputL, float *outputR, long numsamples, int skip)
  108. {
  109. float outL,outR,input;
  110. while(numsamples-- > 0)
  111. {
  112. outL = outR = 0;
  113. input = (*inputL + *inputR) * gain;
  114. // Accumulate comb filters in parallel
  115. for(int i=0; i<numcombs; i++)
  116. {
  117. outL += combL[i].process(input);
  118. outR += combR[i].process(input);
  119. }
  120. // Feed through allpasses in series
  121. for(int i=0; i<numallpasses; i++)
  122. {
  123. outL = allpassL[i].process(outL);
  124. outR = allpassR[i].process(outR);
  125. }
  126. // Calculate output MIXING with anything already there
  127. *outputL += outL*wet1 + outR*wet2 + *inputL*dry;
  128. *outputR += outR*wet1 + outL*wet2 + *inputR*dry;
  129. // Increment sample pointers, allowing for interleave (if any)
  130. inputL += skip;
  131. inputR += skip;
  132. outputL += skip;
  133. outputR += skip;
  134. }
  135. }
  136. void revmodel::update()
  137. {
  138. // Recalculate internal values after parameter change
  139. int i;
  140. wet1 = wet*(width/2 + 0.5f);
  141. wet2 = wet*((1-width)/2);
  142. if (mode >= freezemode)
  143. {
  144. roomsize1 = 1;
  145. damp1 = 0;
  146. gain = muted;
  147. }
  148. else
  149. {
  150. roomsize1 = roomsize;
  151. damp1 = damp;
  152. gain = fixedgain;
  153. }
  154. for(i=0; i<numcombs; i++)
  155. {
  156. combL[i].setfeedback(roomsize1);
  157. combR[i].setfeedback(roomsize1);
  158. }
  159. for(i=0; i<numcombs; i++)
  160. {
  161. combL[i].setdamp(damp1);
  162. combR[i].setdamp(damp1);
  163. }
  164. }
  165. // The following get/set functions are not inlined, because
  166. // speed is never an issue when calling them, and also
  167. // because as you develop the reverb model, you may
  168. // wish to take dynamic action when they are called.
  169. void revmodel::setroomsize(float value)
  170. {
  171. roomsize = (value*scaleroom) + offsetroom;
  172. update();
  173. }
  174. float revmodel::getroomsize()
  175. {
  176. return (roomsize-offsetroom)/scaleroom;
  177. }
  178. void revmodel::setdamp(float value)
  179. {
  180. damp = value*scaledamp;
  181. update();
  182. }
  183. float revmodel::getdamp()
  184. {
  185. return damp/scaledamp;
  186. }
  187. void revmodel::setwet(float value)
  188. {
  189. wet = value*scalewet;
  190. update();
  191. }
  192. float revmodel::getwet()
  193. {
  194. return wet/scalewet;
  195. }
  196. void revmodel::setdry(float value)
  197. {
  198. dry = value*scaledry;
  199. }
  200. float revmodel::getdry()
  201. {
  202. return dry/scaledry;
  203. }
  204. void revmodel::setwidth(float value)
  205. {
  206. width = value;
  207. update();
  208. }
  209. float revmodel::getwidth()
  210. {
  211. return width;
  212. }
  213. void revmodel::setmode(float value)
  214. {
  215. mode = value;
  216. update();
  217. }
  218. float revmodel::getmode()
  219. {
  220. if (mode >= freezemode)
  221. return 1;
  222. else
  223. return 0;
  224. }
  225. //ends