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.

212 lines
5.3KB

  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. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <math.h>
  19. #include <string.h>
  20. #include "../include/gverbdsp.h"
  21. #include "../include/gverb.h"
  22. #include "../include/ladspa-util.h"
  23. namespace rack_plugin_rcm {
  24. ty_gverb *gverb_new(int srate, float maxroomsize, float roomsize,
  25. float revtime,
  26. float damping, float spread,
  27. float inputbandwidth, float earlylevel,
  28. float taillevel)
  29. {
  30. ty_gverb *p;
  31. float ga,gb,gt;
  32. int i,n;
  33. float r;
  34. float diffscale;
  35. int a,b,c,cc,d,dd,e;
  36. float spread1,spread2;
  37. p = (ty_gverb *)malloc(sizeof(ty_gverb));
  38. p->rate = srate;
  39. p->fdndamping = damping;
  40. p->maxroomsize = maxroomsize;
  41. p->roomsize = roomsize;
  42. p->revtime = revtime;
  43. p->earlylevel = earlylevel;
  44. p->taillevel = taillevel;
  45. p->maxdelay = p->rate*p->maxroomsize/340.0;
  46. p->largestdelay = p->rate*p->roomsize/340.0;
  47. /* Input damper */
  48. p->inputbandwidth = inputbandwidth;
  49. p->inputdamper = damper_make(1.0 - p->inputbandwidth);
  50. /* FDN section */
  51. p->fdndels = (ty_fixeddelay **)calloc(FDNORDER, sizeof(ty_fixeddelay *));
  52. for(i = 0; i < FDNORDER; i++) {
  53. p->fdndels[i] = fixeddelay_make((int)p->maxdelay+1000);
  54. }
  55. p->fdngains = (float *)calloc(FDNORDER, sizeof(float));
  56. p->fdnlens = (int *)calloc(FDNORDER, sizeof(int));
  57. p->fdndamps = (ty_damper **)calloc(FDNORDER, sizeof(ty_damper *));
  58. for(i = 0; i < FDNORDER; i++) {
  59. p->fdndamps[i] = damper_make(p->fdndamping);
  60. }
  61. ga = 60.0;
  62. gt = p->revtime;
  63. ga = powf(10.0f,-ga/20.0f);
  64. n = p->rate*gt;
  65. p->alpha = pow((double)ga, 1.0/(double)n);
  66. gb = 0.0;
  67. for(i = 0; i < FDNORDER; i++) {
  68. if (i == 0) gb = 1.000000*p->largestdelay;
  69. if (i == 1) gb = 0.816490*p->largestdelay;
  70. if (i == 2) gb = 0.707100*p->largestdelay;
  71. if (i == 3) gb = 0.632450*p->largestdelay;
  72. #if 0
  73. p->fdnlens[i] = nearest_prime((int)gb, 0.5);
  74. #else
  75. p->fdnlens[i] = f_round(gb);
  76. #endif
  77. p->fdngains[i] = -powf((float)p->alpha,p->fdnlens[i]);
  78. }
  79. p->d = (float *)calloc(FDNORDER, sizeof(float));
  80. p->u = (float *)calloc(FDNORDER, sizeof(float));
  81. p->f = (float *)calloc(FDNORDER, sizeof(float));
  82. /* Diffuser section */
  83. diffscale = (float)p->fdnlens[3]/(210+159+562+410);
  84. spread1 = spread;
  85. spread2 = 3.0*spread;
  86. b = 210;
  87. r = 0.125541;
  88. a = spread1*r;
  89. c = 210+159+a;
  90. cc = c-b;
  91. r = 0.854046;
  92. a = spread2*r;
  93. d = 210+159+562+a;
  94. dd = d-c;
  95. e = 1341-d;
  96. p->ldifs = (ty_diffuser **)calloc(4, sizeof(ty_diffuser *));
  97. p->ldifs[0] = diffuser_make((int)(diffscale*b),0.75);
  98. p->ldifs[1] = diffuser_make((int)(diffscale*cc),0.75);
  99. p->ldifs[2] = diffuser_make((int)(diffscale*dd),0.625);
  100. p->ldifs[3] = diffuser_make((int)(diffscale*e),0.625);
  101. b = 210;
  102. r = -0.568366;
  103. a = spread1*r;
  104. c = 210+159+a;
  105. cc = c-b;
  106. r = -0.126815;
  107. a = spread2*r;
  108. d = 210+159+562+a;
  109. dd = d-c;
  110. e = 1341-d;
  111. p->rdifs = (ty_diffuser **)calloc(4, sizeof(ty_diffuser *));
  112. p->rdifs[0] = diffuser_make((int)(diffscale*b),0.75);
  113. p->rdifs[1] = diffuser_make((int)(diffscale*cc),0.75);
  114. p->rdifs[2] = diffuser_make((int)(diffscale*dd),0.625);
  115. p->rdifs[3] = diffuser_make((int)(diffscale*e),0.625);
  116. /* Tapped delay section */
  117. p->tapdelay = fixeddelay_make(44000);
  118. p->taps = (int *)calloc(FDNORDER, sizeof(int));
  119. p->tapgains = (float *)calloc(FDNORDER, sizeof(float));
  120. p->taps[0] = 5+0.410*p->largestdelay;
  121. p->taps[1] = 5+0.300*p->largestdelay;
  122. p->taps[2] = 5+0.155*p->largestdelay;
  123. p->taps[3] = 5+0.000*p->largestdelay;
  124. for(i = 0; i < FDNORDER; i++) {
  125. p->tapgains[i] = pow(p->alpha,(double)p->taps[i]);
  126. }
  127. return(p);
  128. }
  129. void gverb_free(ty_gverb *p)
  130. {
  131. int i;
  132. damper_free(p->inputdamper);
  133. for(i = 0; i < FDNORDER; i++) {
  134. fixeddelay_free(p->fdndels[i]);
  135. damper_free(p->fdndamps[i]);
  136. diffuser_free(p->ldifs[i]);
  137. diffuser_free(p->rdifs[i]);
  138. }
  139. free(p->fdndels);
  140. free(p->fdngains);
  141. free(p->fdnlens);
  142. free(p->fdndamps);
  143. free(p->d);
  144. free(p->u);
  145. free(p->f);
  146. free(p->ldifs);
  147. free(p->rdifs);
  148. free(p->taps);
  149. free(p->tapgains);
  150. fixeddelay_free(p->tapdelay);
  151. free(p);
  152. }
  153. void gverb_flush(ty_gverb *p)
  154. {
  155. int i;
  156. damper_flush(p->inputdamper);
  157. for(i = 0; i < FDNORDER; i++) {
  158. fixeddelay_flush(p->fdndels[i]);
  159. damper_flush(p->fdndamps[i]);
  160. diffuser_flush(p->ldifs[i]);
  161. diffuser_flush(p->rdifs[i]);
  162. }
  163. memset(p->d, 0, FDNORDER * sizeof(float));
  164. memset(p->u, 0, FDNORDER * sizeof(float));
  165. memset(p->f, 0, FDNORDER * sizeof(float));
  166. fixeddelay_flush(p->tapdelay);
  167. }
  168. /* swh: other functions are now in the .h file for inlining */
  169. } // namespace rack_plugin_rcm