Reverb.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*
  2. Reverb.h
  3. Copyright 2002-5 Tim Goetze <tim@quitte.de>
  4. http://quitte.de/dsp/
  5. two reverb units: JVRev and Plate.
  6. the former is a rewrite of STK's JVRev, a traditional design.
  7. original comment:
  8. This is based on some of the famous
  9. Stanford CCRMA reverbs (NRev, KipRev)
  10. all based on the Chowning/Moorer/
  11. Schroeder reverberators, which use
  12. networks of simple allpass and comb
  13. delay filters.
  14. (STK is an effort of Gary Scavone).
  15. the algorithm is mostly unchanged in this implementation; the delay
  16. line lengths have been fiddled with to make the stereo field more
  17. evenly weighted, and denormal protection has been added.
  18. the Plate reverb is based on the circuit discussed in Jon Dattorro's
  19. september 1997 JAES paper on effect design (part 1: reverb & filters).
  20. */
  21. /*
  22. This program is free software; you can redistribute it and/or
  23. modify it under the terms of the GNU General Public License
  24. as published by the Free Software Foundation; either version 2
  25. of the License, or (at your option) any later version.
  26. This program is distributed in the hope that it will be useful,
  27. but WITHOUT ANY WARRANTY; without even the implied warranty of
  28. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. GNU General Public License for more details.
  30. You should have received a copy of the GNU General Public License
  31. along with this program; if not, write to the Free Software
  32. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  33. 02111-1307, USA or point your web browser to http://www.gnu.org.
  34. */
  35. #ifndef _REVERB_H_
  36. #define _REVERB_H_
  37. #include <stdio.h>
  38. #include "dsp/Delay.h"
  39. #include "dsp/OnePole.h"
  40. #include "dsp/Sine.h"
  41. #include "dsp/util.h"
  42. /* both reverbs use this */
  43. class Lattice
  44. : public DSP::Delay
  45. {
  46. public:
  47. inline sample_t
  48. process (sample_t x, double d)
  49. {
  50. sample_t y = get();
  51. x -= d * y;
  52. put (x);
  53. return d * x + y;
  54. }
  55. };
  56. /* helper for JVRev */
  57. class JVComb
  58. : public DSP::Delay
  59. {
  60. public:
  61. float c;
  62. inline sample_t
  63. process (sample_t x)
  64. {
  65. x += c * get();
  66. put (x);
  67. return x;
  68. }
  69. };
  70. class JVRev
  71. : public Plugin
  72. {
  73. public:
  74. static int default_length[9];
  75. sample_t t60;
  76. Lattice allpass [3];
  77. JVComb comb[4];
  78. DSP::Delay left, right;
  79. double apc;
  80. template <sample_func_t F>
  81. void one_cycle (int frames);
  82. int length [9];
  83. void set_t60 (sample_t t);
  84. public:
  85. static PortInfo port_info [];
  86. void init();
  87. void activate();
  88. void run (int n)
  89. {
  90. one_cycle<store_func> (n);
  91. }
  92. void run_adding (int n)
  93. {
  94. one_cycle<adding_func> (n);
  95. }
  96. };
  97. /* /////////////////////////////////////////////////////////////////////// */
  98. class ModLattice
  99. {
  100. public:
  101. float n0, width;
  102. DSP::Delay delay;
  103. DSP::Sine lfo;
  104. DSP::DelayTapA tap;
  105. void init (int n, int w)
  106. {
  107. n0 = n;
  108. width = w;
  109. delay.init (n + w);
  110. }
  111. void reset()
  112. {
  113. delay.reset();
  114. tap.reset();
  115. }
  116. inline sample_t
  117. process (sample_t x, double d)
  118. {
  119. /* TODO: try all-pass interpolation */
  120. sample_t y = delay.get_at (n0 + width * lfo.get());
  121. x += d * y;
  122. delay.put (x);
  123. return y - d * x; /* note sign */
  124. }
  125. };
  126. class PlateStub
  127. : public Plugin
  128. {
  129. public:
  130. sample_t f_lfo;
  131. sample_t indiff1, indiff2, dediff1, dediff2;
  132. struct {
  133. DSP::OnePoleLP bandwidth;
  134. Lattice lattice[4];
  135. } input;
  136. struct {
  137. ModLattice mlattice[2];
  138. Lattice lattice[2];
  139. DSP::Delay delay[4];
  140. DSP::OnePoleLP damping[2];
  141. int taps[12];
  142. } tank;
  143. public:
  144. void init();
  145. void activate()
  146. {
  147. input.bandwidth.reset();
  148. for (int i = 0; i < 4; ++i)
  149. {
  150. input.lattice[i].reset();
  151. tank.delay[i].reset();
  152. }
  153. for (int i = 0; i < 2; ++i)
  154. {
  155. tank.mlattice[i].reset();
  156. tank.lattice[i].reset();
  157. tank.damping[i].reset();
  158. }
  159. tank.mlattice[0].lfo.set_f (1.2, fs, 0);
  160. tank.mlattice[1].lfo.set_f (1.2, fs, .5 * M_PI);
  161. }
  162. inline void process (sample_t x, sample_t decay,
  163. sample_t * xl, sample_t * xr);
  164. };
  165. /* /////////////////////////////////////////////////////////////////////// */
  166. class Plate
  167. : public PlateStub
  168. {
  169. public:
  170. template <sample_func_t F>
  171. void one_cycle (int frames);
  172. public:
  173. static PortInfo port_info [];
  174. void run (int n)
  175. {
  176. one_cycle<store_func> (n);
  177. }
  178. void run_adding (int n)
  179. {
  180. one_cycle<adding_func> (n);
  181. }
  182. };
  183. /* /////////////////////////////////////////////////////////////////////// */
  184. class Plate2x2
  185. : public PlateStub
  186. {
  187. public:
  188. template <sample_func_t F>
  189. void one_cycle (int frames);
  190. public:
  191. static PortInfo port_info [];
  192. void run (int n)
  193. {
  194. one_cycle<store_func> (n);
  195. }
  196. void run_adding (int n)
  197. {
  198. one_cycle<adding_func> (n);
  199. }
  200. };
  201. #endif /* _REVERB_H_ */