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.

240 lines
6.1KB

  1. /*
  2. Copyright (C) 1999 Juhana Sadeharju
  3. kouhia at nic.funet.fi
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #ifndef GVERB_H
  17. #define GVERB_H
  18. #include <stdlib.h>
  19. #include <math.h>
  20. #include <string.h>
  21. #include "gverbdsp.h"
  22. #include "gverb.h"
  23. #include "ladspa-util.h"
  24. namespace rack_plugin_rcm {
  25. #define FDNORDER 4
  26. typedef struct {
  27. int rate;
  28. float inputbandwidth;
  29. float taillevel;
  30. float earlylevel;
  31. ty_damper *inputdamper;
  32. float maxroomsize;
  33. float roomsize;
  34. float revtime;
  35. float maxdelay;
  36. float largestdelay;
  37. ty_fixeddelay **fdndels;
  38. float *fdngains;
  39. int *fdnlens;
  40. ty_damper **fdndamps;
  41. float fdndamping;
  42. ty_diffuser **ldifs;
  43. ty_diffuser **rdifs;
  44. ty_fixeddelay *tapdelay;
  45. int *taps;
  46. float *tapgains;
  47. float *d;
  48. float *u;
  49. float *f;
  50. double alpha;
  51. } ty_gverb;
  52. ty_gverb *gverb_new(int, float, float, float, float, float, float, float, float);
  53. void gverb_free(ty_gverb *);
  54. void gverb_flush(ty_gverb *);
  55. static void gverb_do(ty_gverb *, float, float *, float *);
  56. static void gverb_set_roomsize(ty_gverb *, float);
  57. static void gverb_set_revtime(ty_gverb *, float);
  58. static void gverb_set_damping(ty_gverb *, float);
  59. static void gverb_set_inputbandwidth(ty_gverb *, float);
  60. static void gverb_set_earlylevel(ty_gverb *, float);
  61. static void gverb_set_taillevel(ty_gverb *, float);
  62. /*
  63. * This FDN reverb can be made smoother by setting matrix elements at the
  64. * diagonal and near of it to zero or nearly zero. By setting diagonals to zero
  65. * means we remove the effect of the parallel comb structure from the
  66. * reverberation. A comb generates uniform impulse stream to the reverberation
  67. * impulse response, and thus it is not good. By setting near diagonal elements
  68. * to zero means we remove delay sequences having consequtive delays of the
  69. * similar lenths, when the delays are in sorted in length with respect to
  70. * matrix element index. The matrix described here could be generated by
  71. * differencing Rocchesso's circulant matrix at max diffuse value and at low
  72. * diffuse value (approaching parallel combs).
  73. *
  74. * Example 1:
  75. * Set a(k,k), for all k, equal to 0.
  76. *
  77. * Example 2:
  78. * Set a(k,k), a(k,k-1) and a(k,k+1) equal to 0.
  79. *
  80. * Example 3: The transition to zero gains could be smooth as well.
  81. * a(k,k-1) and a(k,k+1) could be 0.3, and a(k,k-2) and a(k,k+2) could
  82. * be 0.5, say.
  83. */
  84. static __inline void gverb_fdnmatrix(float *a, float *b)
  85. {
  86. const float dl0 = a[0], dl1 = a[1], dl2 = a[2], dl3 = a[3];
  87. b[0] = 0.5f*(+dl0 + dl1 - dl2 - dl3);
  88. b[1] = 0.5f*(+dl0 - dl1 - dl2 + dl3);
  89. b[2] = 0.5f*(-dl0 + dl1 - dl2 + dl3);
  90. b[3] = 0.5f*(+dl0 + dl1 + dl2 + dl3);
  91. }
  92. static __inline void gverb_do(ty_gverb *p, float x, float *yl, float *yr)
  93. {
  94. float z;
  95. unsigned int i;
  96. float lsum,rsum,sum,sign;
  97. if ((x != x) || fabsf(x) > 100000.0f) {
  98. x = 0.0f;
  99. }
  100. z = damper_do(p->inputdamper, x);
  101. z = diffuser_do(p->ldifs[0],z);
  102. for(i = 0; i < FDNORDER; i++) {
  103. p->u[i] = p->tapgains[i]*fixeddelay_read(p->tapdelay,p->taps[i]);
  104. }
  105. fixeddelay_write(p->tapdelay,z);
  106. for(i = 0; i < FDNORDER; i++) {
  107. p->d[i] = damper_do(p->fdndamps[i],
  108. p->fdngains[i]*fixeddelay_read(p->fdndels[i],
  109. p->fdnlens[i]));
  110. }
  111. sum = 0.0f;
  112. sign = 1.0f;
  113. for(i = 0; i < FDNORDER; i++) {
  114. sum += sign*(p->taillevel*p->d[i] + p->earlylevel*p->u[i]);
  115. sign = -sign;
  116. }
  117. sum += x*p->earlylevel;
  118. lsum = sum;
  119. rsum = sum;
  120. gverb_fdnmatrix(p->d,p->f);
  121. for(i = 0; i < FDNORDER; i++) {
  122. fixeddelay_write(p->fdndels[i],p->u[i]+p->f[i]);
  123. }
  124. lsum = diffuser_do(p->ldifs[1],lsum);
  125. lsum = diffuser_do(p->ldifs[2],lsum);
  126. lsum = diffuser_do(p->ldifs[3],lsum);
  127. rsum = diffuser_do(p->rdifs[1],rsum);
  128. rsum = diffuser_do(p->rdifs[2],rsum);
  129. rsum = diffuser_do(p->rdifs[3],rsum);
  130. *yl = lsum;
  131. *yr = rsum;
  132. }
  133. static __inline void gverb_set_roomsize(ty_gverb *p, const float a)
  134. {
  135. unsigned int i;
  136. if (a <= 1.0 || (a != a)) {
  137. p->roomsize = 1.0;
  138. } else {
  139. p->roomsize = a;
  140. }
  141. p->largestdelay = p->rate * p->roomsize * 0.00294f;
  142. p->fdnlens[0] = f_round(1.000000f*p->largestdelay);
  143. p->fdnlens[1] = f_round(0.816490f*p->largestdelay);
  144. p->fdnlens[2] = f_round(0.707100f*p->largestdelay);
  145. p->fdnlens[3] = f_round(0.632450f*p->largestdelay);
  146. for(i = 0; i < FDNORDER; i++) {
  147. p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
  148. }
  149. p->taps[0] = 5+f_round(0.410f*p->largestdelay);
  150. p->taps[1] = 5+f_round(0.300f*p->largestdelay);
  151. p->taps[2] = 5+f_round(0.155f*p->largestdelay);
  152. p->taps[3] = 5+f_round(0.000f*p->largestdelay);
  153. for(i = 0; i < FDNORDER; i++) {
  154. p->tapgains[i] = powf((float)p->alpha, p->taps[i]);
  155. }
  156. }
  157. static __inline void gverb_set_revtime(ty_gverb *p,float a)
  158. {
  159. float ga,gt;
  160. double n;
  161. unsigned int i;
  162. p->revtime = a;
  163. ga = 60.0;
  164. gt = p->revtime;
  165. ga = powf(10.0f,-ga/20.0f);
  166. n = p->rate*gt;
  167. p->alpha = (double)powf(ga,1.0f/n);
  168. for(i = 0; i < FDNORDER; i++) {
  169. p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
  170. }
  171. }
  172. static __inline void gverb_set_damping(ty_gverb *p,float a)
  173. {
  174. unsigned int i;
  175. p->fdndamping = a;
  176. for(i = 0; i < FDNORDER; i++) {
  177. damper_set(p->fdndamps[i],p->fdndamping);
  178. }
  179. }
  180. static __inline void gverb_set_inputbandwidth(ty_gverb *p,float a)
  181. {
  182. p->inputbandwidth = a;
  183. damper_set(p->inputdamper,1.0 - p->inputbandwidth);
  184. }
  185. static __inline void gverb_set_earlylevel(ty_gverb *p,float a)
  186. {
  187. p->earlylevel = a;
  188. }
  189. static __inline void gverb_set_taillevel(ty_gverb *p,float a)
  190. {
  191. p->taillevel = a;
  192. }
  193. } // namespace rack_plugin_rcm
  194. #endif