~ubuntu-branches/ubuntu/raring/lmms/raring-proposed

« back to all changes in this revision

Viewing changes to plugins/ladspa_effect/swh/gverb/gverb.h

  • Committer: Charlie Smotherman
  • Date: 2012-12-05 22:08:38 UTC
  • mfrom: (33.1.7 lmms_0.4.13)
  • Revision ID: cjsmo@cableone.net-20121205220838-09pjfzew9m5023hr
* New  Upstream release.
  - Minor tweaking to ZynAddSubFX, CALF, SWH plugins  and Stefan Fendt's RC
    filters.
  - Added UI fixes: Magnentic effect of knobs and Piano-roll fixes
  - Updated German localization and copyright year
* debian/lmms-common.install:
  - added /usr/share/applications so the lmms.desktop file will correctly
    install (LP: #863366)
  - This should also fix the Software Center not displaying lmms in sound
    and video (LP: #824231)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#ifndef GVERB_H
 
23
#define GVERB_H
 
24
 
 
25
#include <stdlib.h>
 
26
#include <math.h>
 
27
#include <string.h>
 
28
#include "gverbdsp.h"
 
29
#include "gverb.h"
 
30
#include "../ladspa-util.h"
 
31
 
 
32
#define FDNORDER 4
 
33
 
 
34
typedef struct {
 
35
  int rate;
 
36
  float inputbandwidth;
 
37
  float taillevel;
 
38
  float earlylevel;
 
39
  ty_damper *inputdamper;
 
40
  float maxroomsize;
 
41
  float roomsize;
 
42
  float revtime;
 
43
  float maxdelay;
 
44
  float largestdelay;
 
45
  ty_fixeddelay **fdndels;
 
46
  float *fdngains;
 
47
  int *fdnlens;
 
48
  ty_damper **fdndamps; 
 
49
  float fdndamping;
 
50
  ty_diffuser **ldifs;
 
51
  ty_diffuser **rdifs;
 
52
  ty_fixeddelay *tapdelay;
 
53
  int *taps;
 
54
  float *tapgains;
 
55
  float *d;
 
56
  float *u;
 
57
  float *f;
 
58
  double alpha;
 
59
} ty_gverb;
 
60
 
 
61
 
 
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);
 
72
 
 
73
/*
 
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).
 
84
 *
 
85
 * Example 1:
 
86
 * Set a(k,k), for all k, equal to 0.
 
87
 *
 
88
 * Example 2:
 
89
 * Set a(k,k), a(k,k-1) and a(k,k+1) equal to 0.
 
90
 *
 
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
 
93
 * be 0.5, say.
 
94
 */
 
95
 
 
96
static inline void gverb_fdnmatrix(float *a, float *b)
 
97
{
 
98
  const float dl0 = a[0], dl1 = a[1], dl2 = a[2], dl3 = a[3];
 
99
 
 
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);
 
104
}
 
105
 
 
106
static inline void gverb_do(ty_gverb *p, float x, float *yl, float *yr)
 
107
{
 
108
  float z;
 
109
  unsigned int i;
 
110
  float lsum,rsum,sum,sign;
 
111
 
 
112
  if (isnan(x) || fabsf(x) > 100000.0f) {
 
113
    x = 0.0f;
 
114
  }
 
115
 
 
116
  z = damper_do(p->inputdamper, x);
 
117
 
 
118
  z = diffuser_do(p->ldifs[0],z);
 
119
 
 
120
  for(i = 0; i < FDNORDER; i++) {
 
121
    p->u[i] = p->tapgains[i]*fixeddelay_read(p->tapdelay,p->taps[i]);
 
122
  }
 
123
  fixeddelay_write(p->tapdelay,z);
 
124
 
 
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],
 
128
                                                       p->fdnlens[i]));
 
129
  }
 
130
 
 
131
  sum = 0.0f;
 
132
  sign = 1.0f;
 
133
  for(i = 0; i < FDNORDER; i++) {
 
134
    sum += sign*(p->taillevel*p->d[i] + p->earlylevel*p->u[i]);
 
135
    sign = -sign;
 
136
  }
 
137
  sum += x*p->earlylevel;
 
138
  lsum = sum;
 
139
  rsum = sum;
 
140
 
 
141
  gverb_fdnmatrix(p->d,p->f);
 
142
 
 
143
  for(i = 0; i < FDNORDER; i++) {
 
144
    fixeddelay_write(p->fdndels[i],p->u[i]+p->f[i]);
 
145
  }
 
146
 
 
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);
 
153
 
 
154
  *yl = lsum;
 
155
  *yr = rsum;
 
156
}
 
157
 
 
158
static inline void gverb_set_roomsize(ty_gverb *p, const float a)
 
159
{
 
160
  unsigned int i;
 
161
 
 
162
  if (a <= 1.0 || isnan(a)) {
 
163
    p->roomsize = 1.0;
 
164
  } else {
 
165
    p->roomsize = a;
 
166
  }
 
167
  p->largestdelay = p->rate * p->roomsize * 0.00294f;
 
168
 
 
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]);
 
175
  }
 
176
 
 
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);
 
181
 
 
182
  for(i = 0; i < FDNORDER; i++) {
 
183
    p->tapgains[i] = powf((float)p->alpha, p->taps[i]);
 
184
  }
 
185
 
 
186
}
 
187
 
 
188
static inline void gverb_set_revtime(ty_gverb *p,float a)
 
189
{
 
190
  float ga,gt;
 
191
  double n;
 
192
  unsigned int i;
 
193
 
 
194
  p->revtime = a;
 
195
 
 
196
  ga = 60.0;
 
197
  gt = p->revtime;
 
198
  ga = powf(10.0f,-ga/20.0f);
 
199
  n = p->rate*gt;
 
200
  p->alpha = (double)powf(ga,1.0f/n);
 
201
 
 
202
  for(i = 0; i < FDNORDER; i++) {
 
203
    p->fdngains[i] = -powf((float)p->alpha, p->fdnlens[i]);
 
204
  }
 
205
 
 
206
}
 
207
 
 
208
static inline void gverb_set_damping(ty_gverb *p,float a)
 
209
{
 
210
  unsigned int i;
 
211
 
 
212
  p->fdndamping = a;
 
213
  for(i = 0; i < FDNORDER; i++) {
 
214
    damper_set(p->fdndamps[i],p->fdndamping);
 
215
  }
 
216
}
 
217
 
 
218
static inline void gverb_set_inputbandwidth(ty_gverb *p,float a)
 
219
{
 
220
  p->inputbandwidth = a;
 
221
  damper_set(p->inputdamper,1.0 - p->inputbandwidth);
 
222
}
 
223
 
 
224
static inline void gverb_set_earlylevel(ty_gverb *p,float a)
 
225
{
 
226
  p->earlylevel = a;
 
227
}
 
228
 
 
229
static inline void gverb_set_taillevel(ty_gverb *p,float a)
 
230
{
 
231
  p->taillevel = a;
 
232
}
 
233
 
 
234
#endif