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.

234 lines
5.4KB

  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. // adapted for use in VCV Rack by Martin Lueders
  7. #include "revmodel.hpp"
  8. revmodel::revmodel()
  9. {
  10. };
  11. void revmodel::init(const float sampleRate)
  12. {
  13. conversion = sampleRate/44100.0;
  14. int ccombtuningL1 = round(conversion * combtuningL1);
  15. int ccombtuningR1 = round(conversion * combtuningR1);
  16. int ccombtuningL2 = round(conversion * combtuningL2);
  17. int ccombtuningR2 = round(conversion * combtuningR2);
  18. int ccombtuningL3 = round(conversion * combtuningL3);
  19. int ccombtuningR3 = round(conversion * combtuningR3);
  20. int ccombtuningL4 = round(conversion * combtuningL4);
  21. int ccombtuningR4 = round(conversion * combtuningR4);
  22. int ccombtuningL5 = round(conversion * combtuningL5);
  23. int ccombtuningR5 = round(conversion * combtuningR5);
  24. int ccombtuningL6 = round(conversion * combtuningL6);
  25. int ccombtuningR6 = round(conversion * combtuningR6);
  26. int ccombtuningL7 = round(conversion * combtuningL7);
  27. int ccombtuningR7 = round(conversion * combtuningR7);
  28. int ccombtuningL8 = round(conversion * combtuningL8);
  29. int ccombtuningR8 = round(conversion * combtuningR8);
  30. int callpasstuningL1 = round(conversion * allpasstuningL1);
  31. int callpasstuningR1 = round(conversion * allpasstuningR1);
  32. int callpasstuningL2 = round(conversion * allpasstuningL2);
  33. int callpasstuningR2 = round(conversion * allpasstuningR2);
  34. int callpasstuningL3 = round(conversion * allpasstuningL3);
  35. int callpasstuningR3 = round(conversion * allpasstuningR3);
  36. int callpasstuningL4 = round(conversion * allpasstuningL4);
  37. int callpasstuningR4 = round(conversion * allpasstuningR4);
  38. // Tie the components to their buffers
  39. combL[0].makebuffer(bufcombL1,ccombtuningL1);
  40. combR[0].makebuffer(bufcombR1,ccombtuningR1);
  41. combL[1].makebuffer(bufcombL2,ccombtuningL2);
  42. combR[1].makebuffer(bufcombR2,ccombtuningR2);
  43. combL[2].makebuffer(bufcombL3,ccombtuningL3);
  44. combR[2].makebuffer(bufcombR3,ccombtuningR3);
  45. combL[3].makebuffer(bufcombL4,ccombtuningL4);
  46. combR[3].makebuffer(bufcombR4,ccombtuningR4);
  47. combL[4].makebuffer(bufcombL5,ccombtuningL5);
  48. combR[4].makebuffer(bufcombR5,ccombtuningR5);
  49. combL[5].makebuffer(bufcombL6,ccombtuningL6);
  50. combR[5].makebuffer(bufcombR6,ccombtuningR6);
  51. combL[6].makebuffer(bufcombL7,ccombtuningL7);
  52. combR[6].makebuffer(bufcombR7,ccombtuningR7);
  53. combL[7].makebuffer(bufcombL8,ccombtuningL8);
  54. combR[7].makebuffer(bufcombR8,ccombtuningR8);
  55. allpassL[0].makebuffer(bufallpassL1,callpasstuningL1);
  56. allpassR[0].makebuffer(bufallpassR1,callpasstuningR1);
  57. allpassL[1].makebuffer(bufallpassL2,callpasstuningL2);
  58. allpassR[1].makebuffer(bufallpassR2,callpasstuningR2);
  59. allpassL[2].makebuffer(bufallpassL3,callpasstuningL3);
  60. allpassR[2].makebuffer(bufallpassR3,callpasstuningR3);
  61. allpassL[3].makebuffer(bufallpassL4,callpasstuningL4);
  62. allpassR[3].makebuffer(bufallpassR4,callpasstuningR4);
  63. feedback_allpass = 0.5;
  64. setwet(initialwet);
  65. setroomsize(initialroom);
  66. setdry(initialdry);
  67. setdamp(initialdamp);
  68. setwidth(initialwidth);
  69. setmode(initialmode);
  70. // Buffer will be full of rubbish - so we MUST mute them
  71. mute();
  72. }
  73. void revmodel::mute()
  74. {
  75. if (getmode() >= freezemode)
  76. return;
  77. for (int i=0;i<numcombs;i++)
  78. {
  79. combL[i].mute();
  80. combR[i].mute();
  81. }
  82. for (int i=0;i<numallpasses;i++)
  83. {
  84. allpassL[i].mute();
  85. allpassR[i].mute();
  86. }
  87. }
  88. void revmodel::process(const float in, float &outputL, float &outputR)
  89. {
  90. float outL,outR,input;
  91. {
  92. outL = outR = 0;
  93. input = in*gain*conversion;
  94. // Accumulate comb filters in parallel
  95. for(int i=0; i<numcombs; i++)
  96. {
  97. outL += combL[i].process(input, damp1, damp2, roomsize1);
  98. outR += combR[i].process(input, damp1, damp2, roomsize1);
  99. }
  100. // Feed through allpasses in series
  101. for(int i=0; i<numallpasses; i++)
  102. {
  103. outL = allpassL[i].process(outL, feedback_allpass);
  104. outR = allpassR[i].process(outR, feedback_allpass);
  105. }
  106. // Calculate output REPLACING anything already there
  107. outputL = outL; //*wet1 + outR*wet2;
  108. outputR = outR; //*wet1 + outL*wet2;
  109. }
  110. }
  111. void revmodel::update()
  112. {
  113. // Recalculate internal values after parameter change
  114. if (mode >= freezemode)
  115. {
  116. roomsize1 = 1;
  117. damp1 = 0;
  118. gain = muted;
  119. }
  120. else
  121. {
  122. roomsize1 = roomsize;
  123. damp1 = damp;
  124. gain = fixedgain;
  125. }
  126. damp2 = 1.0 - damp1;
  127. }
  128. // The following get/set functions are not inlined, because
  129. // speed is never an issue when calling them, and also
  130. // because as you develop the reverb model, you may
  131. // wish to take dynamic action when they are called.
  132. void revmodel::setroomsize(float value)
  133. {
  134. roomsize = ((value*scaleroom) + offsetroom); // * conversion;
  135. update();
  136. }
  137. float revmodel::getroomsize()
  138. {
  139. // return (roomsize/conversion-offsetroom)/scaleroom;
  140. return (roomsize-offsetroom)/scaleroom;
  141. }
  142. void revmodel::setdamp(float value)
  143. {
  144. damp = value*scaledamp/conversion;
  145. damp = value*scaledamp * sqrt(conversion) ;
  146. update();
  147. }
  148. float revmodel::getdamp()
  149. {
  150. // return conversion * damp/scaledamp;
  151. return damp/scaledamp;
  152. }
  153. void revmodel::setwet(float value)
  154. {
  155. wet = value*scalewet;
  156. update();
  157. }
  158. float revmodel::getwet()
  159. {
  160. return wet/scalewet;
  161. }
  162. void revmodel::setdry(float value)
  163. {
  164. dry = value*scaledry;
  165. }
  166. float revmodel::getdry()
  167. {
  168. return dry/scaledry;
  169. }
  170. void revmodel::setwidth(float value)
  171. {
  172. width = value;
  173. update();
  174. }
  175. float revmodel::getwidth()
  176. {
  177. return width;
  178. }
  179. void revmodel::setmode(float value)
  180. {
  181. mode = value;
  182. update();
  183. }
  184. float revmodel::getmode()
  185. {
  186. if (mode >= freezemode)
  187. return 1;
  188. else
  189. return 0;
  190. }
  191. //ends