ref: 18a98c11353eb5f5613ced866ec1f6cf1efdfee5
parent: e8e76b1a07d1925c34debc75c6cba86910cab44e
author: cbagwell <cbagwell>
date: Fri Nov 10 12:07:49 EST 2000
Added new "earwax" effect.
--- a/Changelog
+++ b/Changelog
@@ -28,6 +28,9 @@
versions. This should allow people to work with raw CD audio data
on Mac OSX and also gives a basis for adding future support for
things like ADPCM processing.
+ o Added new "earwax" effect from Edward Beingessner. It is meant to
+ be used for CD audio played through headphones. It will move the
+ sound stage from left/right to in front of you.
sox-12.17
---------
--- a/Makefile.dos
+++ b/Makefile.dos
@@ -17,7 +17,7 @@
wav.obj wve.obj
EOBJ = avg.obj band.obj bandpass.obj breject.obj btrworth.obj chorus.obj \
- compand.obj copy.obj cut.obj deemphas.obj echo.obj \
+ compand.obj copy.obj cut.obj deemphas.obj earwax.o echo.obj \
echos.obj fade.obj filter.obj flanger.obj highp.obj highpass.obj \
lowp.obj lowpass.obj map.obj mask.obj phaser.obj pick.obj \
pitch.obj pan.obj polyphase.obj rate.obj resample.obj reverb.obj \
--- a/Makefile.gcc
+++ b/Makefile.gcc
@@ -34,8 +34,8 @@
voc.o wav.o wve.o
EOBJ = avg.o band.o bandpass.o breject.o btrworth.o chorus.o compand.o \
- copy.o cut.o deemphas.o echo.o echos.o fade.o filter.o flanger.o \
- highp.o highpass.o lowp.o lowpass.o map.o mask.o pan.o \
+ copy.o cut.o deemphas.o earwax.o echo.o echos.o fade.o filter.o \
+ flanger.o highp.o highpass.o lowp.o lowpass.o map.o mask.o pan.o \
phaser.o pick.o pitch.o polyphas.o rate.o resample.o reverb.o \
reverse.o speed.o split.o stat.o stretch.o swap.o \
trimo vibro.o vol.o
--- a/README
+++ b/README
@@ -45,6 +45,7 @@
o Band-reject filter
o Chorus effect
o Cut out loop samples
+ o Move sound stage of CD audio to in front of you (for headphone use)
o Add an echo
o Add a sequence of echos
o Fade in and out
--- a/sox.1
+++ b/sox.1
@@ -62,6 +62,8 @@
.br
\fBdeemph\fR
.br
+ \fBearwax\fR
+.br
\fBecho\fR \fIgain-in gain-out delay decay\fR [ \fIdelay decay ...\fR ]
.br
\fBechos\fR \fIgain-in gain-out delay decay\fR [ \fIdelay decay ...\fR ]
@@ -641,6 +643,17 @@
audio cd format. The frequency response of pre-emphasized
recordings is rectified. The filtering is defined in the
standard document ISO 908.
+.TP 10
+earwax
+Makes sound easier to listen to on headphones.
+Adds audio-cues to samples in audio cd format so that
+when listened to on headphones the stereo image is
+moved from inside
+your head (standard for headphones) to outside and in front of the
+listener (standard for speakers). See
+.br
+www.geocities.com/beinges
+for a full explanation.
.TP 10
echo \fIgain-in gain-out delay decay \fR[ \fIdelay decay ... \fR]
Add echoing to a sound sample.
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -46,8 +46,8 @@
sf.o smp.o sndrtool.o sphere.o tx16w.o voc.o wav.o wve.o
EOBJ = avg.o band.o bandpass.o breject.o btrworth.o chorus.o compand.o \
- copy.o cut.o deemphas.o echo.o echos.o fade.o filter.o flanger.o \
- highp.o highpass.o lowp.o lowpass.o map.o mask.o pan.o \
+ copy.o cut.o deemphas.o earwax.o echo.o echos.o fade.o filter.o \
+ flanger.o highp.o highpass.o lowp.o lowpass.o map.o mask.o pan.o \
phaser.o pick.o pitch.o polyphas.o rate.o resample.o reverb.o \
reverse.o speed.o split.o stat.o stretch.o swap.o trim.o \
vibro.o vol.o
--- /dev/null
+++ b/src/earwax.c
@@ -1,0 +1,195 @@
+/*
+ * November 9, 2000
+ * Copyright (C) 2000 Edward Beingessner And Sundry Contributors
+ * This source code is freely redistributable and may be used for
+ * any purpose. This copyright notice must be maintained.
+ * Edward Beingessner And Sundry Contributors are not responsible for
+ * the consequences of using this software.
+ */
+
+/*
+ * earwax - makes listening to headphones easier
+ *
+ * This effect takes a stereo sound that is meant to be listened to
+ * on headphones, and adds audio cues to move the soundstage from inside
+ * your head (standard for headphones) to outside and in front of the
+ * listener (standard for speakers). This makes the sound much easier to
+ * listen to on headphones. See www.geocities.com/beinges for a full
+ * explanation.
+ *
+ * Usage:
+ * earwax
+ *
+ * Note:
+ * This filter only works for 44.1 kHz stereo signals (cd format)
+ *
+*/
+
+#include "st.h"
+
+#define EARWAX_SCALE 64
+
+/* A stereo fir filter. One side filters as if the signal was from
+ 30 degrees from the ear, the other as if 330 degrees. */
+/* 30 330 */
+static const LONG filt[] ={4, -6,
+ 4, -11,
+ -1, -5,
+ 3, 3,
+ -2, 5,
+ -5, 0,
+ 9, 1,
+ 6, 3,
+ -4, -1,
+ -5, -3,
+ -2, -5,
+ -7, 1,
+ 6, -7,
+ 30, -29,
+ 12, -3,
+ -11, 4,
+ -3, 7,
+ -20, 23,
+ 2, 0,
+ 1, -6,
+ -14, -5,
+ 15, -18,
+ 6, 7,
+ 15, -10,
+ -14, 22,
+ -7, -2,
+ -4, 9,
+ 6, -12,
+ 6, -6,
+ 0, -11,
+ 0, -5,
+ 4, 0};
+
+/* 32 tap stereo FIR filter needs 64 taps */
+#define EARWAX_NUMTAPS 64
+
+typedef struct earwaxstuff {
+ LONG *tap; /* taps are z^-1 delays for the FIR filter */
+} *earwax_t;
+
+/*
+ * Process options
+ */
+int st_earwax_getopts(effp, n, argv)
+eff_t effp;
+int n;
+char **argv;
+{
+ /* no options */
+ if (n){
+ st_fail("The earwax filtering effect takes no options.\n");
+ return (ST_EOF);
+ }
+ return (ST_SUCCESS);
+}
+
+/*
+ * Prepare for processing.
+ */
+int st_earwax_start(effp)
+eff_t effp;
+{
+ earwax_t earwax = (earwax_t) effp->priv;
+ int i;
+
+ /* check the input format */
+ if (effp->ininfo.encoding != ST_ENCODING_SIGN2
+ || effp->ininfo.rate != 44100
+ || effp->ininfo.channels != 2){
+ st_fail("the earwax effect works only with audio cd (44.1 kHz, twos-complement signed linear, stereo) samples.\n");
+ return (ST_EOF);
+ }
+
+ /* allocate tap memory */
+ earwax->tap = (LONG*)malloc( sizeof(LONG) * EARWAX_NUMTAPS );
+ if( !earwax->tap ){
+ st_fail("earwax: Cannot malloc %d bytes!\n",
+ sizeof(LONG) * EARWAX_NUMTAPS );
+ return (ST_EOF);
+ }
+
+ /* zero out the delayed taps */
+ for(i=0; i < EARWAX_NUMTAPS; i++ ){
+ earwax->tap[i] = 0;
+ }
+
+ return (ST_SUCCESS);
+}
+
+/*
+ * Processed signed long samples from ibuf to obuf.
+ * Return number of samples processed.
+ */
+
+int st_earwax_flow(effp, ibuf, obuf, isamp, osamp)
+eff_t effp;
+LONG *ibuf, *obuf;
+LONG *isamp, *osamp;
+{
+ earwax_t earwax = (earwax_t) effp->priv;
+ int len, done;
+ int i;
+ LONG output;
+
+ len = ((*isamp > *osamp) ? *osamp : *isamp);
+
+ for(done = 0; done < len; done++) {
+
+ /* update taps and calculate output */
+ output = 0;
+ for(i = EARWAX_NUMTAPS-1; i > 0; i--) {
+ earwax->tap[i] = earwax->tap[i-1];
+ output += earwax->tap[i] * filt[i];
+ }
+ earwax->tap[0] = *ibuf++ / EARWAX_SCALE;
+ output += earwax->tap[0] * filt[i];
+
+ /* store scaled output */
+ *obuf++ = output;
+ }
+
+ *isamp = *osamp = len;
+ return (ST_SUCCESS);
+}
+
+/*
+ * Drain out taps.
+ */
+int st_earwax_drain(effp, obuf, osamp)
+eff_t effp;
+LONG *obuf;
+LONG *osamp;
+{
+ earwax_t earwax = (earwax_t) effp->priv;
+ int i,j;
+ LONG output;
+
+ for(i = EARWAX_NUMTAPS-1; i >= 0; i--){
+ output = 0;
+ for(j = 0; j < i; j++ ){
+ output += filt[j+(EARWAX_NUMTAPS-i)] * earwax->tap[j];
+ }
+ *obuf++ = output;
+ }
+ *osamp = EARWAX_NUMTAPS-1;
+
+ return (ST_SUCCESS);
+}
+
+/*
+ * Clean up taps.
+ */
+int st_earwax_stop(effp)
+eff_t effp;
+{
+ earwax_t earwax = (earwax_t) effp->priv;
+
+ free((char *)earwax->tap);
+
+ return (ST_SUCCESS);
+}
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -505,6 +505,12 @@
extern int st_echos_drain();
extern int st_echos_stop();
+extern int st_earwax_getopts();
+extern int st_earwax_start();
+extern int st_earwax_flow();
+extern int st_earwax_drain();
+extern int st_earwax_stop();
+
extern int st_fade_getopts();
extern int st_fade_start();
extern int st_fade_flow();
@@ -679,6 +685,9 @@
{"deemph", ST_EFF_MCHAN,
st_deemph_getopts, st_deemph_start, st_deemph_flow,
st_null_drain, st_deemph_stop},
+ {"earwax", ST_EFF_MCHAN,
+ st_earwax_getopts, st_earwax_start, st_earwax_flow,
+ st_earwax_drain, st_earwax_stop},
{"echo", 0,
st_echo_getopts, st_echo_start, st_echo_flow,
st_echo_drain, st_echo_stop},