ref: 3e7c1e463cc93eb7b8f3aae049a20c6dc1ac3e0b
parent: 4c789efcd4c3d37ea7ca2fbc833f54dc28f11d85
author: robs <robs>
date: Fri Sep 12 16:24:39 EDT 2008
riaa effect
--- a/AUTHORS
+++ b/AUTHORS
@@ -14,10 +14,10 @@
FORMATS: M3U, PLS, FLAC, AMR, HTK, WavPack, VOX/IMA/VOC ADPCM
support, 24bit support for popular formats, MP3 tags & duration
support.
- EFFECTS: key, tempo, pad, bass, treble, delay, new reverb, new
+ EFFECTS: tempo, pad, bass, treble, delay, new reverb, new
flanger, soft-knee companding, speed via resampling, filters
makeover inc. gnuplot & octave plotting, splice, remix, norm,
- contrast, new rate, spectrogram;
+ contrast, new rate, spectrogram, new pitch, riaa;
new effects chain with buffering and any # channels.
OTHERS: open input files via URL, file merge, play
multiple files with mixed format types, play with replay-gain,
--- a/ChangeLog
+++ b/ChangeLog
@@ -37,15 +37,19 @@
14.1.1 E key pitch 14.1.1 + 6 months
14.1.1 E pan ~= mixer/remix 14.1.1 + 6 months
-Other new features:
+Effects:
- o New --output option to write to multiple files in one run.
- Only useful with certain effects like trim and silence. (cbagwell)
- o Display SoX build environment information with -V -V. (robs)
+ o New `riaa' effect; RIAA vinyl playback EQ. (robs)
o For `rate' effect, change default phase to intermediate; phase,
band-width and aliasing now configurable. (robs)
o New -b option for the norm effect; can be used to fix stereo
imbalance. (robs)
+
+Other new features:
+
+ o New --output option to write to multiple files in one run.
+ Only useful with certain effects like trim and silence. (cbagwell)
+ o Display SoX build environment information with -V -V. (robs)
Other bug fixes:
--- a/README
+++ b/README
@@ -156,6 +156,7 @@
o earwax Process CD audio to best effect for headphone use
o noisered Filter out noise from the audio
o oops Out Of Phase Stereo (or `Karaoke') effect
+ o riaa RIAA vinyl playback equalisation
o Analysis `effects'
o noiseprof Produce a DFT profile of the audio (use with noisered)
--- a/soxeffect.7
+++ b/soxeffect.7
@@ -1238,6 +1238,9 @@
Reverse the audio completely.
Requires temporary file space to store the audio to be reversed.
.TP
+\fBriaa\fR
+Apply RIAA vinyl playback equalisation.
+.TP
\fBsilence \fR[\fB\-l\fR] \fIabove-periods\fR [\fIduration
threshold\fR[\fBd\fR\^|\^\fB%\fR] [\fIbelow-periods duration
threshold\fR[\fBd\fR\^|\^\fB%\fR]]
--- a/src/biquad.h
+++ b/src/biquad.h
@@ -36,7 +36,8 @@
filter_BPF_SPK_N,
filter_AP1,
filter_AP2,
- filter_deemph
+ filter_deemph,
+ filter_riaa
} filter_t;
typedef enum {
@@ -59,8 +60,8 @@
filter_t filter_type;
- double b2, b1, b0; /* Filter coefficients */
- double a2, a1, a0; /* Filter coefficients */
+ double b0, b1, b2; /* Filter coefficients */
+ double a0, a1, a2; /* Filter coefficients */
sox_sample_t i1, i2; /* Filter memory */
double o1, o2; /* Filter memory */
--- a/src/biquads.c
+++ b/src/biquads.c
@@ -139,6 +139,26 @@
}
+static int riaa_getopts(sox_effect_t * effp, int argc, char **argv) {
+ priv_t * p = (priv_t *)effp->priv;
+ p->filter_type = filter_riaa;
+ (void)argv;
+ return argc? lsx_usage(effp) : SOX_SUCCESS;
+}
+
+
+static void make_poly_from_roots(
+ double const * roots, size_t num_roots, double * poly)
+{
+ size_t i, j;
+ poly[0] = 1;
+ poly[1] = -roots[0];
+ memset(poly + 2, 0, (num_roots + 1 - 2) * sizeof(*poly));
+ for (i = 1; i < num_roots; ++i)
+ for (j = num_roots; j > 0; --j)
+ poly[j] -= poly[j - 1] * roots[i];
+}
+
static int start(sox_effect_t * effp)
{
priv_t * p = (priv_t *)effp->priv;
@@ -309,6 +329,40 @@
p->a1 = -2 * cos(w0);
p->a2 = 1 - sin(w0);
break;
+
+ case filter_riaa: /* http://www.dsprelated.com/showmessage/73300/3.php */
+ if (effp->in_signal.rate == 44100) {
+ static const double zeros[] = {-0.2014898, 0.9233820};
+ static const double poles[] = {0.7083149, 0.9924091};
+ make_poly_from_roots(zeros, 2, &p->b0);
+ make_poly_from_roots(poles, 2, &p->a0);
+ }
+ else if (effp->in_signal.rate == 48000) {
+ static const double zeros[] = {-0.1766069, 0.9321590};
+ static const double poles[] = {0.7396325, 0.9931330};
+ make_poly_from_roots(zeros, 2, &p->b0);
+ make_poly_from_roots(poles, 2, &p->a0);
+ }
+ else if (effp->in_signal.rate == 88200) {
+ static const double zeros[] = {-0.1168735, 0.9648312};
+ static const double poles[] = {0.8590646, 0.9964002};
+ make_poly_from_roots(zeros, 2, &p->b0);
+ make_poly_from_roots(poles, 2, &p->a0);
+ }
+ else if (effp->in_signal.rate == 96000) {
+ static const double zeros[] = {-0.1141486, 0.9676817};
+ static const double poles[] = {0.8699137, 0.9966946};
+ make_poly_from_roots(zeros, 2, &p->b0);
+ make_poly_from_roots(poles, 2, &p->a0);
+ }
+ else {
+ sox_fail("Sample rate must be 44.1k, 48k, 88.2k, or 96k");
+ return SOX_EOF;
+ }
+ {double g = dB_to_linear(19.9 - linear_to_dB(
+ (p->b0 + p->b1 + p->b2) / (p->a0 + p->a1 + p->a2)));
+ p->b0 *= g; p->b1 *= g; p->b2 *= g;}
+ break;
}
return sox_biquad_start(effp);
}
@@ -333,3 +387,4 @@
BIQUAD_EFFECT(equalizer, equalizer,"frequency width[q|o|h|k] gain", 0)
BIQUAD_EFFECT(band, band, "[-n] center [width[h|k|q|o]]", 0)
BIQUAD_EFFECT(deemph, deemph, NULL, 0)
+BIQUAD_EFFECT(riaa, riaa, NULL, 0)
--- a/src/effects.h
+++ b/src/effects.h
@@ -63,6 +63,7 @@
EFFECT(resample)
EFFECT(reverb)
EFFECT(reverse)
+ EFFECT(riaa)
EFFECT(silence)
#ifdef HAVE_PNG
EFFECT(spectrogram)