3
Copyright (C) 1999 Juhana Sadeharju
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.
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.
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.
30
#include "../ladspa-util.h"
39
ty_damper *inputdamper;
45
ty_fixeddelay **fdndels;
52
ty_fixeddelay *tapdelay;
62
ty_gverb *gverb_new(int, float, float, float, float, float, float, float, float);
63
void gverb_free(ty_gverb *);
64
void gverb_flush(ty_gverb *);
65
static void gverb_do(ty_gverb *, float, float *, float *);
66
static void gverb_set_roomsize(ty_gverb *, float);
67
static void gverb_set_revtime(ty_gverb *, float);
68
static void gverb_set_damping(ty_gverb *, float);
69
static void gverb_set_inputbandwidth(ty_gverb *, float);
70
static void gverb_set_earlylevel(ty_gverb *, float);
71
static void gverb_set_taillevel(ty_gverb *, float);
74
* This FDN reverb can be made smoother by setting matrix elements at the
75
* diagonal and near of it to zero or nearly zero. By setting diagonals to zero
76
* means we remove the effect of the parallel comb structure from the
77
* reverberation. A comb generates uniform impulse stream to the reverberation
78
* impulse response, and thus it is not good. By setting near diagonal elements
79
* to zero means we remove delay sequences having consequtive delays of the
80
* similar lenths, when the delays are in sorted in length with respect to
81
* matrix element index. The matrix described here could be generated by
82
* differencing Rocchesso's circulant matrix at max diffuse value and at low
83
* diffuse value (approaching parallel combs).
86
* Set a(k,k), for all k, equal to 0.
89
* Set a(k,k), a(k,k-1) and a(k,k+1) equal to 0.
91
* Example 3: The transition to zero gains could be smooth as well.
92
* a(k,k-1) and a(k,k+1) could be 0.3, and a(k,k-2) and a(k,k+2) could
96
static inline void gverb_fdnmatrix(float *a, float *b)
98
const float dl0 = a[0], dl1 = a[1], dl2 = a[2], dl3 = a[3];
100
b[0] = 0.5f*(+dl0 + dl1 - dl2 - dl3);
101
b[1] = 0.5f*(+dl0 - dl1 - dl2 + dl3);
102
b[2] = 0.5f*(-dl0 + dl1 - dl2 + dl3);
103
b[3] = 0.5f*(+dl0 + dl1 + dl2 + dl3);
106
static inline void gverb_do(ty_gverb *p, float x, float *yl, float *yr)
110
float lsum,rsum,sum,sign;
112
if (isnan(x) || fabsf(x) > 100000.0f) {
116
z = damper_do(p->inputdamper, x);
118
z = diffuser_do(p->ldifs[0],z);
120
for(i = 0; i < FDNORDER; i++) {
121
p->u[i] = p->tapgains[i]*fixeddelay_read(p->tapdelay,p->taps[i]);
123
fixeddelay_write(p->tapdelay,z);
125
for(i = 0; i < FDNORDER; i++) {
126
p->d[i] = damper_do(p->fdndamps[i],
127
p->fdngains[i]*fixeddelay_read(p->fdndels[i],
133
for(i = 0; i < FDNORDER; i++) {
134
sum += sign*(p->taillevel*p->d[i] + p->earlylevel*p->u[i]);
137
sum += x*p->earlylevel;
141
gverb_fdnmatrix(p->d,p->f);
143
for(i = 0; i < FDNORDER; i++) {
144
fixeddelay_write(p->fdndels[i],p->u[i]+p->f[i]);
147
lsum = diffuser_do(p->ldifs[1],lsum);
148
lsum = diffuser_do(p->ldifs[2],lsum);
149
lsum = diffuser_do(p->ldifs[3],lsum);
150
rsum = diffuser_do(p->rdifs[1],rsum);
151
rsum = diffuser_do(p->rdifs[2],rsum);
152
rsum = diffuser_do(p->rdifs[3],rsum);
158
static inline void gverb_set_roomsize(ty_gverb *p, const float a)
162
if (a <= 1.0 || isnan(a)) {
167
p->largestdelay = p->rate * p->roomsize * 0.00294f;
169
p->fdnlens[0] = f_round(1.000000f*p->largestdelay);
170
p->fdnlens[1] = f_round(0.816490f*p->largestdelay);
171
p->fdnlens[2] = f_round(0.707100f*p->largestdelay);
172
p->fdnlens[3] = f_round(0.632450f*p->largestdelay);
173
for(i = 0; i < FDNORDER; i++) {
174
p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
177
p->taps[0] = 5+f_round(0.410f*p->largestdelay);
178
p->taps[1] = 5+f_round(0.300f*p->largestdelay);
179
p->taps[2] = 5+f_round(0.155f*p->largestdelay);
180
p->taps[3] = 5+f_round(0.000f*p->largestdelay);
182
for(i = 0; i < FDNORDER; i++) {
183
p->tapgains[i] = powf((float)p->alpha, p->taps[i]);
188
static inline void gverb_set_revtime(ty_gverb *p,float a)
198
ga = powf(10.0f,-ga/20.0f);
200
p->alpha = (double)powf(ga,1.0f/n);
202
for(i = 0; i < FDNORDER; i++) {
203
p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
208
static inline void gverb_set_damping(ty_gverb *p,float a)
213
for(i = 0; i < FDNORDER; i++) {
214
damper_set(p->fdndamps[i],p->fdndamping);
218
static inline void gverb_set_inputbandwidth(ty_gverb *p,float a)
220
p->inputbandwidth = a;
221
damper_set(p->inputdamper,1.0 - p->inputbandwidth);
224
static inline void gverb_set_earlylevel(ty_gverb *p,float a)
229
static inline void gverb_set_taillevel(ty_gverb *p,float a)