[SCM] calf/master: + Loudness: started working on A-weighting class; Biquad: added 'inline' keyword here and there
js at users.alioth.debian.org
js at users.alioth.debian.org
Tue May 7 15:38:17 UTC 2013
The following commit has been merged in the master branch:
commit 98d613e320597073ec5447b538890ae52dc57924
Author: Krzysztof Foltman <wdev at foltman.com>
Date: Mon Nov 3 22:42:10 2008 +0000
+ Loudness: started working on A-weighting class; Biquad: added 'inline' keyword here and there
diff --git a/src/benchmark.cpp b/src/benchmark.cpp
index 79a558a..a852836 100644
--- a/src/benchmark.cpp
+++ b/src/benchmark.cpp
@@ -24,6 +24,7 @@
#include <calf/giface.h>
#include <calf/modules.h>
#include <calf/modules_dev.h>
+#include <calf/loudness.h>
#include <calf/benchmark.h>
// #define TEST_OSC
@@ -339,6 +340,16 @@ void eq_calc()
}
}
+void aweighting_calc()
+{
+ aweighter aw;
+ aw.set(48000);
+ for (int i = 10; i < 20000; i += 10)
+ {
+ printf("%d %f\n", i, 20*log10(aw.freq_gain(i * 1.0, 48000)));
+ }
+}
+
#ifdef TEST_OSC
struct my_sink: public osc_message_sink<osc_strstream>
@@ -445,5 +456,8 @@ int main(int argc, char *argv[])
if (unit && !strcmp(unit, "eq"))
eq_calc();
+ if (unit && !strcmp(unit, "aweighting"))
+ aweighting_calc();
+
return 0;
}
diff --git a/src/calf/biquad.h b/src/calf/biquad.h
index 10119a7..d90027a 100644
--- a/src/calf/biquad.h
+++ b/src/calf/biquad.h
@@ -107,7 +107,7 @@ public:
* @param sr sample rate
* @param gain amplification (gain at sr/2)
*/
- void set_hp_rbj(float fc, float q, float esr, float gain=1.0)
+ inline void set_hp_rbj(float fc, float q, float esr, float gain=1.0)
{
Coeff omega=(float)(2*M_PI*fc/esr);
Coeff sn=sin(omega);
@@ -124,7 +124,7 @@ public:
}
// this replaces sin/cos with polynomial approximation
- void set_hp_rbj_optimized(float fc, float q, float esr, float gain=1.0)
+ inline void set_hp_rbj_optimized(float fc, float q, float esr, float gain=1.0)
{
Coeff omega=(float)(2*M_PI*fc/esr);
Coeff sn=omega+omega*omega*omega*(1.0/6.0)+omega*omega*omega*omega*omega*(1.0/120);
@@ -146,7 +146,7 @@ public:
* @param sr sample rate
* @param gain amplification (gain at sr/2)
*/
- void set_bp_rbj(double fc, double q, double esr, double gain=1.0)
+ inline void set_bp_rbj(double fc, double q, double esr, double gain=1.0)
{
float omega=(float)(2*M_PI*fc/esr);
float sn=sin(omega);
@@ -163,7 +163,7 @@ public:
}
// rbj's bandreject
- void set_br_rbj(double fc, double q, double esr, double gain=1.0)
+ inline void set_br_rbj(double fc, double q, double esr, double gain=1.0)
{
float omega=(float)(2*M_PI*fc/esr);
float sn=sin(omega);
@@ -181,15 +181,27 @@ public:
// this is mine (and, I guess, it sucks/doesn't work)
void set_allpass(float freq, float pole_r, float sr)
{
- float a=prewarp(freq, sr);
- float q=pole_r;
- set_bilinear(a*a+q*q, -2.0f*a, 1, a*a+q*q, 2.0f*a, 1);
+ float a=prewarp(freq, sr);
+ float q=pole_r;
+ set_bilinear(a*a+q*q, -2.0f*a, 1, a*a+q*q, 2.0f*a, 1);
}
/// prewarping for bilinear transform, maps given digital frequency to analog counterpart for analog filter design
- float prewarp(float freq, float sr)
+ static inline float prewarp(float freq, float sr)
{
- if (freq>sr*0.49) freq=(float)(sr*0.49);
- return (float)(tan(M_PI*freq/sr));
+ if (freq>sr*0.49) freq=(float)(sr*0.49);
+ return (float)(tan(M_PI*freq/sr));
+ }
+ /// convert analog frequency-corresponding pole value to digital
+ static inline float unwarp(float freq, float sr)
+ {
+ float T = 1.0 / sr;
+ return (2 / T) * atan(freq * T / 2);
+ }
+ /// convert analog frequency-corresponding pole value to digital
+ static inline float unwarpf(float coeff, float sr)
+ {
+ float T = 1.0 / sr;
+ return 1.0 / ((2 / T) * atan((1.0 / coeff) * T / 2));
}
/// set digital filter parameters based on given analog filter parameters
void set_bilinear(float aa0, float aa1, float aa2, float ab0, float ab1, float ab2)
@@ -206,7 +218,7 @@ public:
/// @param freq peak frequency
/// @param q q (correlated to freq/bandwidth, @see set_bp_rbj)
/// @param peak peak gain (1.0 means no peak, >1.0 means a peak, less than 1.0 is a dip)
- void set_peakeq_rbj(float freq, float q, float peak, float sr)
+ inline void set_peakeq_rbj(float freq, float q, float peak, float sr)
{
float A = sqrt(peak);
float w0 = freq * 2 * M_PI * (1.0 / sr);
@@ -222,7 +234,7 @@ public:
/// @param freq corner frequency (gain at freq is sqrt(peak))
/// @param q q (relates bandwidth and peak frequency), the higher q, the louder the resonant peak (situated below fc) is
/// @param peak shelf gain (1.0 means no peak, >1.0 means a peak, less than 1.0 is a dip)
- void set_lowshelf_rbj(float freq, float q, float peak, float sr)
+ inline void set_lowshelf_rbj(float freq, float q, float peak, float sr)
{
float A = sqrt(peak);
float w0 = freq * 2 * M_PI * (1.0 / sr);
@@ -250,7 +262,7 @@ public:
/// @param freq corner frequency (gain at freq is sqrt(peak))
/// @param q q (relates bandwidth and peak frequency), the higher q, the louder the resonant peak (situated above fc) is
/// @param peak shelf gain (1.0 means no peak, >1.0 means a peak, less than 1.0 is a dip)
- void set_highshelf_rbj(float freq, float q, float peak, float sr)
+ inline void set_highshelf_rbj(float freq, float q, float peak, float sr)
{
float A = sqrt(peak);
float w0 = freq * 2 * M_PI * (1.0 / sr);
diff --git a/src/calf/loudness.h b/src/calf/loudness.h
new file mode 100644
index 0000000..c9dccf3
--- /dev/null
+++ b/src/calf/loudness.h
@@ -0,0 +1,83 @@
+/* Calf DSP Library
+ * A-weighting filter for
+ * Copyright (C) 2001-2007 Krzysztof Foltman
+ *
+ * Most of code in this file is based on freely
+ * available other work of other people (filter equations).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CALF_LOUDNESS_H
+#define __CALF_LOUDNESS_H
+
+#include "biquad.h"
+
+namespace dsp {
+
+class aweighter {
+public:
+ biquad_d2<float> bq1, bq2, bq3;
+
+ float process(float sample)
+ {
+ return bq1.process(bq2.process(bq3.process(sample)));
+ }
+
+ void set(float sr)
+ {
+ // lowpass : H(s) = 1 / (1 + st) = 1 / (1 + s/w) = 1 / (1 + s/(2piF))
+ // wc = 2pi * fc
+
+ // This is not done yet - I need to finish redoing the coeffs properly
+ float f1 = 129.4f / sr;
+ float f2 = 676.7f / sr;
+ float f3 = 4636.f / sr;
+ float f4 = 76655.f / sr;
+ /*
+ float f1 = biquad_coeffs<float>::unwarpf(129.4f, sr);
+ float f2 = biquad_coeffs<float>::unwarpf(676.7f, sr);
+ float f3 = biquad_coeffs<float>::unwarpf(4636.f, sr);
+ float f4 = biquad_coeffs<float>::unwarpf(76655.f, sr);
+ */
+ bq1.set_bilinear(0, 0, 1, f1*f1, 2 * f1, 1);
+ bq2.set_bilinear(4.0, 0, 0, f2*f3, f2 + f3, 1);
+ bq3.set_bilinear(0, 0, 1, f4*f4, 2 * f4, 1);
+ }
+
+ void sanitize()
+ {
+ bq1.sanitize();
+ bq2.sanitize();
+ bq3.sanitize();
+ }
+
+ void reset()
+ {
+ bq1.reset();
+ bq2.reset();
+ bq3.reset();
+ }
+
+ float freq_gain(float freq, float sr)
+ {
+ return bq1.freq_gain(freq, sr) * bq2.freq_gain(freq, sr) * bq3.freq_gain(freq, sr);
+ }
+
+};
+
+};
+
+#endif
--
calf audio plugins packaging
More information about the pkg-multimedia-commits
mailing list