1 /*
2
3 Copyright (C) 1999 Juhana Sadeharju
4 kouhia at nic.funet.fi
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 */
21
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <math.h>
26 #include <string.h>
27 #include "gverbdsp.h"
28 #include "gverb.h"
29 #include "../include/ladspa-util.h"
30
gverb_new(int srate,float maxroomsize,float roomsize,float revtime,float damping,float spread,float inputbandwidth,float earlylevel,float taillevel)31 ty_gverb *gverb_new(int srate, float maxroomsize, float roomsize,
32 float revtime,
33 float damping, float spread,
34 float inputbandwidth, float earlylevel,
35 float taillevel)
36 {
37 ty_gverb *p;
38 float ga,gb,gt;
39 int i,n;
40 float r;
41 float diffscale;
42 int a,b,c,cc,d,dd,e;
43 float spread1,spread2;
44
45 p = (ty_gverb *)malloc(sizeof(ty_gverb));
46 p->rate = srate;
47 p->fdndamping = damping;
48 p->maxroomsize = maxroomsize;
49 p->roomsize = roomsize;
50 p->revtime = revtime;
51 p->earlylevel = earlylevel;
52 p->taillevel = taillevel;
53
54 p->maxdelay = p->rate*p->maxroomsize/340.0;
55 p->largestdelay = p->rate*p->roomsize/340.0;
56
57
58 /* Input damper */
59
60 p->inputbandwidth = inputbandwidth;
61 p->inputdamper = damper_make(1.0 - p->inputbandwidth);
62
63
64 /* FDN section */
65
66
67 p->fdndels = (ty_fixeddelay **)calloc(FDNORDER, sizeof(ty_fixeddelay *));
68 for(i = 0; i < FDNORDER; i++) {
69 p->fdndels[i] = fixeddelay_make((int)p->maxdelay+1000);
70 }
71 p->fdngains = (float *)calloc(FDNORDER, sizeof(float));
72 p->fdnlens = (int *)calloc(FDNORDER, sizeof(int));
73
74 p->fdndamps = (ty_damper **)calloc(FDNORDER, sizeof(ty_damper *));
75 for(i = 0; i < FDNORDER; i++) {
76 p->fdndamps[i] = damper_make(p->fdndamping);
77 }
78
79 ga = 60.0;
80 gt = p->revtime;
81 ga = powf(10.0f,-ga/20.0f);
82 n = p->rate*gt;
83 p->alpha = pow((double)ga, 1.0/(double)n);
84
85 gb = 0.0;
86 for(i = 0; i < FDNORDER; i++) {
87 if (i == 0) gb = 1.000000*p->largestdelay;
88 if (i == 1) gb = 0.816490*p->largestdelay;
89 if (i == 2) gb = 0.707100*p->largestdelay;
90 if (i == 3) gb = 0.632450*p->largestdelay;
91
92 #if 0
93 p->fdnlens[i] = nearest_prime((int)gb, 0.5);
94 #else
95 p->fdnlens[i] = f_round(gb);
96 #endif
97 p->fdngains[i] = -powf((float)p->alpha,p->fdnlens[i]);
98 }
99
100 p->d = (float *)calloc(FDNORDER, sizeof(float));
101 p->u = (float *)calloc(FDNORDER, sizeof(float));
102 p->f = (float *)calloc(FDNORDER, sizeof(float));
103
104 /* Diffuser section */
105
106 diffscale = (float)p->fdnlens[3]/(210+159+562+410);
107 spread1 = spread;
108 spread2 = 3.0*spread;
109
110 b = 210;
111 r = 0.125541;
112 a = spread1*r;
113 c = 210+159+a;
114 cc = c-b;
115 r = 0.854046;
116 a = spread2*r;
117 d = 210+159+562+a;
118 dd = d-c;
119 e = 1341-d;
120
121 p->ldifs = (ty_diffuser **)calloc(4, sizeof(ty_diffuser *));
122 p->ldifs[0] = diffuser_make((int)(diffscale*b),0.75);
123 p->ldifs[1] = diffuser_make((int)(diffscale*cc),0.75);
124 p->ldifs[2] = diffuser_make((int)(diffscale*dd),0.625);
125 p->ldifs[3] = diffuser_make((int)(diffscale*e),0.625);
126
127 b = 210;
128 r = -0.568366;
129 a = spread1*r;
130 c = 210+159+a;
131 cc = c-b;
132 r = -0.126815;
133 a = spread2*r;
134 d = 210+159+562+a;
135 dd = d-c;
136 e = 1341-d;
137
138 p->rdifs = (ty_diffuser **)calloc(4, sizeof(ty_diffuser *));
139 p->rdifs[0] = diffuser_make((int)(diffscale*b),0.75);
140 p->rdifs[1] = diffuser_make((int)(diffscale*cc),0.75);
141 p->rdifs[2] = diffuser_make((int)(diffscale*dd),0.625);
142 p->rdifs[3] = diffuser_make((int)(diffscale*e),0.625);
143
144
145
146 /* Tapped delay section */
147
148 p->tapdelay = fixeddelay_make(44000);
149 p->taps = (int *)calloc(FDNORDER, sizeof(int));
150 p->tapgains = (float *)calloc(FDNORDER, sizeof(float));
151
152 p->taps[0] = 5+0.410*p->largestdelay;
153 p->taps[1] = 5+0.300*p->largestdelay;
154 p->taps[2] = 5+0.155*p->largestdelay;
155 p->taps[3] = 5+0.000*p->largestdelay;
156
157 for(i = 0; i < FDNORDER; i++) {
158 p->tapgains[i] = pow(p->alpha,(double)p->taps[i]);
159 }
160
161 return(p);
162 }
163
gverb_free(ty_gverb * p)164 void gverb_free(ty_gverb *p)
165 {
166 int i;
167
168 damper_free(p->inputdamper);
169 for(i = 0; i < FDNORDER; i++) {
170 fixeddelay_free(p->fdndels[i]);
171 damper_free(p->fdndamps[i]);
172 diffuser_free(p->ldifs[i]);
173 diffuser_free(p->rdifs[i]);
174 }
175 free(p->fdndels);
176 free(p->fdngains);
177 free(p->fdnlens);
178 free(p->fdndamps);
179 free(p->d);
180 free(p->u);
181 free(p->f);
182 free(p->ldifs);
183 free(p->rdifs);
184 free(p->taps);
185 free(p->tapgains);
186 fixeddelay_free(p->tapdelay);
187 free(p);
188 }
189
gverb_flush(ty_gverb * p)190 void gverb_flush(ty_gverb *p)
191 {
192 int i;
193
194 damper_flush(p->inputdamper);
195 for(i = 0; i < FDNORDER; i++) {
196 fixeddelay_flush(p->fdndels[i]);
197 damper_flush(p->fdndamps[i]);
198 diffuser_flush(p->ldifs[i]);
199 diffuser_flush(p->rdifs[i]);
200 }
201 memset(p->d, 0, FDNORDER * sizeof(float));
202 memset(p->u, 0, FDNORDER * sizeof(float));
203 memset(p->f, 0, FDNORDER * sizeof(float));
204 fixeddelay_flush(p->tapdelay);
205 }
206
207 /* swh: other functions are now in the .h file for inlining */
208