shithub: sox

Download patch

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},