LMMS
Loading...
Searching...
No Matches
loudness.h
Go to the documentation of this file.
1/* Calf DSP Library
2 * A-weighting filter for
3 * Copyright (C) 2001-2007 Krzysztof Foltman
4 *
5 * Most of code in this file is based on freely
6 * available other work of other people (filter equations).
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General
19 * Public License along with this program; if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02111-1307, USA.
22 */
23#ifndef __CALF_LOUDNESS_H
24#define __CALF_LOUDNESS_H
25
26#include "biquad.h"
27
28#ifndef M_PI
29#define M_PI 3.14159265358979323846264338327
30#endif
31
32
33namespace dsp {
34
35class aweighter {
36public:
38
40 float process(float sample)
41 {
42 return bq1.process(bq2.process(bq3.process(sample)));
43 }
44
46 void set(float sr)
47 {
48 // analog coeffs taken from: http://www.diracdelta.co.uk/science/source/a/w/aweighting/source.html
49 // first we need to adjust them by doing some obscene sort of reverse pre-warping (a broken one, too!)
50 float f1 = biquad_coeffs::unwarpf(20.6f, sr);
51 float f2 = biquad_coeffs::unwarpf(107.7f, sr);
52 float f3 = biquad_coeffs::unwarpf(738.f, sr);
53 float f4 = biquad_coeffs::unwarpf(12200.f, sr);
54 // then map s domain to z domain using bilinear transform
55 // note: f1 and f4 are double poles
56 bq1.set_bilinear(0, 0, 1, f1*f1, 2 * f1, 1);
57 bq2.set_bilinear(1, 0, 0, f2*f3, f2 + f3, 1);
58 bq3.set_bilinear(0, 0, 1, f4*f4, 2 * f4, 1);
59 // the coeffs above give non-normalized value, so it should be normalized to produce 0dB at 1 kHz
60 // find actual gain
61 float gain1kHz = freq_gain(1000.0, sr);
62 // divide one filter's x[n-m] coefficients by that value
63 float gc = 1.0 / gain1kHz;
64 bq1.a0 *= gc;
65 bq1.a1 *= gc;
66 bq1.a2 *= gc;
67 }
68
70 void sanitize()
71 {
72 bq1.sanitize();
73 bq2.sanitize();
74 bq3.sanitize();
75 }
76
78 void reset()
79 {
80 bq1.reset();
81 bq2.reset();
82 bq3.reset();
83 }
84
86 float freq_gain(float freq, float sr)
87 {
88 return bq1.freq_gain(freq, sr) * bq2.freq_gain(freq, sr) * bq3.freq_gain(freq, sr);
89 }
90
91};
92
93class riaacurve {
94public:
98
100 {
101 use_brickw = true;
102 }
103
105 float process(float sample)
106 {
107 return r1.process(use_brickw ? brickw.process(sample) : sample);
108 }
109
111 void set(float sr, int mode, int type)
112 {
113 float i,j,k,g,a0,a1,a2,b1,b2,tau1,tau2,tau3;
114 switch(type) {
115 case 0: //"Columbia"
116 i = 100.f;
117 j = 500.f;
118 k = 1590.f;
119 break;
120 case 1: //"EMI"
121 i = 70.f;
122 j = 500.f;
123 k = 2500.f;
124 break;
125 case 2: //"BSI(78rpm)"
126 i = 50.f;
127 j = 353.f;
128 k = 3180.f;
129 break;
130 case 3: //"RIAA"
131 default:
132 tau1 = 0.003180f;
133 tau2 = 0.000318f;
134 tau3 = 0.000075f;
135 i = 1.f / (2.f * M_PI * tau1);
136 j = 1.f / (2.f * M_PI * tau2);
137 k = 1.f / (2.f * M_PI * tau3);
138 break;
139 case 4: //"CD Mastering"
140 tau1 = 0.000050f;
141 tau2 = 0.000015f;
142 tau3 = 0.0000001f;// 1.6MHz out of audible range for null impact
143 i = 1.f / (2.f * M_PI * tau1);
144 j = 1.f / (2.f * M_PI * tau2);
145 k = 1.f / (2.f * M_PI * tau3);
146 break;
147 case 5: //"50µs FM (Europe)"
148 tau1 = 0.000050f;
149 tau2 = tau1 / 20;// not used
150 tau3 = tau1 / 50;//
151 i = 1.f / (2.f * M_PI * tau1);
152 j = 1.f / (2.f * M_PI * tau2);
153 k = 1.f / (2.f * M_PI * tau3);
154 break;
155 case 6: //"75µs FM (US)"
156 tau1 = 0.000075f;
157 tau2 = tau1 / 20;// not used
158 tau3 = tau1 / 50;//
159 i = 1.f / (2.f * M_PI * tau1);
160 j = 1.f / (2.f * M_PI * tau2);
161 k = 1.f / (2.f * M_PI * tau3);
162 break;
163 }
164
165 i *= 2.f * M_PI;
166 j *= 2.f * M_PI;
167 k *= 2.f * M_PI;
168
169 float t = 1.f / sr;
170
171 //swap a1 b1, a2 b2
172 biquad_coeffs coeffs;
173 if (type == 7 || type == 8)
174 {
175 use_brickw = false;
176 float tau = (type == 7 ? 0.000050 : 0.000075);
177 float f = 1.0 / (2 * M_PI * tau);
178 float nyq = sr * 0.5f;
179 float gain = sqrt(1.0 + nyq * nyq / (f * f)); // gain at Nyquist
180 float cfreq = sqrt((gain - 1.0) * f * f); // frequency
181 float q = 1.0;
182 if (type == 8)
183 q = pow((sr / 3269.0) + 19.5, -0.25); // somewhat poor curve-fit
184 if (type == 7)
185 q = pow((sr / 4750.0) + 19.5, -0.25);
186 if (mode == 0)
187 r1.set_highshelf_rbj(cfreq, q, 1.f / gain, sr);
188 else
189 r1.set_highshelf_rbj(cfreq, q, gain, sr);
190 }
191 else
192 {
193 use_brickw = true;
194 if (mode == 0) { //Reproduction
195 g = 1.f / (4.f+2.f*i*t+2.f*k*t+i*k*t*t);
196 a0 = (2.f*t+j*t*t)*g;
197 a1 = (2.f*j*t*t)*g;
198 a2 = (-2.f*t+j*t*t)*g;
199 b1 = (-8.f+2.f*i*k*t*t)*g;
200 b2 = (4.f-2.f*i*t-2.f*k*t+i*k*t*t)*g;
201 } else { //Production
202 g = 1.f / (2.f*t+j*t*t);
203 a0 = (4.f+2.f*i*t+2.f*k*t+i*k*t*t)*g;
204 a1 = (-8.f+2.f*i*k*t*t)*g;
205 a2 = (4.f-2.f*i*t-2.f*k*t+i*k*t*t)*g;
206 b1 = (2.f*j*t*t)*g;
207 b2 = (-2.f*t+j*t*t)*g;
208 }
209 coeffs.set_bilinear_direct(a0, a1, a2, b1, b2);
210
211 // the coeffs above give non-normalized value, so it should be normalized to produce 0dB at 1 kHz
212 // find actual gain
213 // Note: for FM emphasis, use 100 Hz for normalization instead
214 float gain1kHz = coeffs.freq_gain(1000.0, sr);
215 // divide one filter's x[n-m] coefficients by that value
216 float gc = 1.0 / gain1kHz;
217 r1.a0 = coeffs.a0 * gc;
218 r1.a1 = coeffs.a1 * gc;
219 r1.a2 = coeffs.a2 * gc;
220 r1.b1 = coeffs.b1;
221 r1.b2 = coeffs.b2;
222 }
223
224 r1.sanitize();
225
226 float cutfreq = std::min(0.45f * sr, 21000.f);
227 brickw.set_lp_rbj(cutfreq, 0.707f, sr, 1.f);
228 brickw.sanitize();
229 }
230
232 void sanitize()
233 {
234 r1.sanitize();
235 brickw.sanitize();
236 }
237
239 void reset()
240 {
241 r1.reset();
242 }
243
245 float freq_gain(float freq, float sr) const
246 {
247 return r1.freq_gain(freq, sr) * (use_brickw ? brickw.freq_gain(freq, sr) : 1.f);
248 }
249
250};
251
252};
253
254#endif
CAdPlugDatabase::CRecord::RecordType type
Definition adplugdb.cpp:93
Definition loudness.h:35
biquad_d2 bq1
Definition loudness.h:37
biquad_d2 bq3
Definition loudness.h:37
void set(float sr)
Set sample rate (updates filter coefficients).
Definition loudness.h:46
void reset()
Reset state to zero.
Definition loudness.h:78
biquad_d2 bq2
Definition loudness.h:37
float process(float sample)
Produce one output sample from one input sample.
Definition loudness.h:40
void sanitize()
Reset to zero if at risk of denormals.
Definition loudness.h:70
float freq_gain(float freq, float sr)
Gain and a given frequency.
Definition loudness.h:86
Definition biquad.h:49
double b2
Definition biquad.h:52
double a0
Definition biquad.h:52
double a2
Definition biquad.h:52
float freq_gain(float freq, float sr) const
Definition biquad.h:321
double b1
Definition biquad.h:52
static double unwarpf(float t, float sr)
convert analog filter time constant to digital counterpart
Definition biquad.h:205
double a1
Definition biquad.h:52
void set_bilinear_direct(double aa0, double aa1, double aa2, double ab1, double ab2)
set digital filter parameters directly
Definition biquad.h:226
void set(float sr, int mode, int type)
Set sample rate (updates filter coefficients).
Definition loudness.h:111
biquad_d2 brickw
Definition loudness.h:96
bool use_brickw
Definition loudness.h:97
float freq_gain(float freq, float sr) const
Gain and a given frequency.
Definition loudness.h:245
void sanitize()
Reset to zero if at risk of denormals.
Definition loudness.h:232
float process(float sample)
Produce one output sample from one input sample.
Definition loudness.h:105
riaacurve()
Definition loudness.h:99
biquad_d2 r1
Definition loudness.h:95
void reset()
Reset state to zero.
Definition loudness.h:239
#define M_PI
Definition compat.h:149
struct huft * t
Definition inflate.c:943
register unsigned k
Definition inflate.c:946
register unsigned j
Definition inflate.c:1576
int g
Definition inflate.c:1573
register unsigned i
Definition inflate.c:1575
unsigned f
Definition inflate.c:1572
JHUFF_TBL long freq[]
Definition jchuff.h:50
Definition audio_fx.h:36
png_structrp int mode
Definition png.h:1139
Definition biquad.h:430
signed int sample
Definition tap_dynamics_m.c:41
register uch * q
Definition fileio.c:817