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 "../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