shithub: sox

Download patch

ref: 25e648fea3d715890452eb9d4b72e9e7b6e44ec8
parent: 02408dc14424421895b1030c41066a33ea4b0758
author: rrt <rrt>
date: Mon Nov 27 20:32:11 EST 2006

Make input buffer const in effects. This means that some effects have
to copy its contents, but has the nice effect of making things
slightly more logical (you read your input and write your output) as
well as making it possible to make input more flexible in future (e.g.
it could come from an mmapped file).

--- a/src/avg.c
+++ b/src/avg.c
@@ -508,7 +508,7 @@
  * Process either isamp or osamp samples, whichever is smaller.
  */
 
-int st_avg_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_avg_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                 st_size_t *isamp, st_size_t *osamp)
 {
     avg_t avg = (avg_t) effp->priv;
--- a/src/band.c
+++ b/src/band.c
@@ -135,7 +135,7 @@
  * Return number of samples processed.
  */
 
-int st_band_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_band_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
         band_t band = (band_t) effp->priv;
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -2,7 +2,7 @@
 
 
 
-int st_biquad_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_biquad_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                         st_size_t *isamp, st_size_t *osamp)
 {
   biquad_t p = (biquad_t) effp->priv;
--- a/src/biquad.h
+++ b/src/biquad.h
@@ -19,7 +19,7 @@
   double o1, o2;           /* Filter memory */
 } * biquad_t;
 
-int st_biquad_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_biquad_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                         st_size_t *isamp, st_size_t *osamp);
 
 assert_static(sizeof(struct biquad) <= ST_MAX_EFFECT_PRIVSIZE, 
--- a/src/btrworth.c
+++ b/src/btrworth.c
@@ -75,7 +75,7 @@
   }
 }
 
-int st_butterworth_flow (eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_butterworth_flow (eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                          st_size_t *isamp, st_size_t *osamp)
 {
   butterworth_t butterworth = (butterworth_t) effp->priv;
--- a/src/btrworth.h
+++ b/src/btrworth.h
@@ -33,7 +33,7 @@
 
 int st_butterworth_start (eff_t effp);
 void st_butterworth_plot (eff_t effp);
-int st_butterworth_flow (eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
+int st_butterworth_flow (eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf,
                          st_size_t *isamp, st_size_t *osamp);
 
 typedef struct butterworth {
--- a/src/chorus.c
+++ b/src/chorus.c
@@ -254,7 +254,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_chorus_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_chorus_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                    st_size_t *isamp, st_size_t *osamp)
 {
         chorus_t chorus = (chorus_t) effp->priv;
--- a/src/compand.c
+++ b/src/compand.c
@@ -264,7 +264,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_compand_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_compand_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
   compand_t l = (compand_t) effp->priv;
--- a/src/copy.c
+++ b/src/copy.c
@@ -45,7 +45,7 @@
  * Place in buf[].
  * Return number of samples read.
  */
-int st_copy_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_copy_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
         int done;
--- a/src/dcshift.c
+++ b/src/dcshift.c
@@ -99,7 +99,7 @@
 /*
  * Process data.
  */
-int st_dcshift_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_dcshift_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
     dcs_t dcs = (dcs_t) effp->priv;
--- a/src/deemphas.c
+++ b/src/deemphas.c
@@ -188,7 +188,7 @@
  * Return number of samples processed.
  */
 
-int st_deemph_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_deemph_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                    st_size_t *isamp, st_size_t *osamp)
 {
      deemph_t deemph = (deemph_t) effp->priv;
--- a/src/earwax.c
+++ b/src/earwax.c
@@ -125,7 +125,7 @@
  * Return number of samples processed.
  */
 
-int st_earwax_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_earwax_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                    st_size_t *isamp, st_size_t *osamp)
 {
   earwax_t earwax = (earwax_t) effp->priv;
--- a/src/echo.c
+++ b/src/echo.c
@@ -185,7 +185,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_echo_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_echo_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
         echo_t echo = (echo_t) effp->priv;
--- a/src/echos.c
+++ b/src/echos.c
@@ -177,7 +177,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_echos_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_echos_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                 st_size_t *isamp, st_size_t *osamp)
 {
         echos_t echos = (echos_t) effp->priv;
--- a/src/equalizer.c
+++ b/src/equalizer.c
@@ -147,7 +147,7 @@
   return (ST_SUCCESS);
 }
 
-int st_equalizer_flow(eff_t effp, st_sample_t *ibuf,
+int st_equalizer_flow(eff_t effp, const st_sample_t *ibuf,
                       st_sample_t *obuf, st_size_t *isamp,
                       st_size_t *osamp)
 {
--- a/src/fade.c
+++ b/src/fade.c
@@ -215,7 +215,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_fade_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_fade_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
     fade_t fade = (fade_t) effp->priv;
--- a/src/filter.c
+++ b/src/filter.c
@@ -182,7 +182,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_filter_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_filter_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                    st_size_t *isamp, st_size_t *osamp)
 {
         filter_t f = (filter_t) effp->priv;
--- a/src/flanger.c
+++ b/src/flanger.c
@@ -207,7 +207,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_flanger_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_flanger_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
         flanger_t flanger = (flanger_t) effp->priv;
--- a/src/highp.c
+++ b/src/highp.c
@@ -100,7 +100,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_highp_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_highp_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                   st_size_t *isamp, st_size_t *osamp)
 {
         highp_t highp = (highp_t) effp->priv;
--- a/src/lowp.c
+++ b/src/lowp.c
@@ -96,7 +96,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_lowp_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_lowp_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
         lowp_t lowp = (lowp_t) effp->priv;
--- a/src/mask.c
+++ b/src/mask.c
@@ -46,7 +46,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_mask_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_mask_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
         int len, done;
--- a/src/mcompand.c
+++ b/src/mcompand.c
@@ -67,7 +67,7 @@
  *   the companders have different prediction intervals (volume
  *   application delays).  Note that the predictive mode of the
  *   limiter needs some TLC - in fact, a rewrite - since what's really
- *   useful is to assure that a waveform won't be clipped, be slewing
+ *   useful is to assure that a waveform won't be clipped, by slewing
  *   the volume in advance so that the peak is at limit (or below, if
  *   there's a higher subsequent peak visible in the lookahead window)
  *   once it's reached.  */
@@ -172,7 +172,6 @@
 
       *lowbufptr = out;
 
-
       out =
         butterworth->a_high[0] * in +
         butterworth->a_high [1] * butterworth->xy_high[chan].x [0] +
@@ -223,7 +222,7 @@
   int nBands;
   st_sample_t *band_buf1, *band_buf2, *band_buf3;
   int band_buf_len;
-  st_ssize_t delay_buf_size;/* Size of delay_buf in samples */
+  st_size_t delay_buf_size;/* Size of delay_buf in samples */
   struct comp_band *bands;
 } *compand_t;
 
@@ -497,7 +496,7 @@
     *v += delta * l->decayRate[chan];
 }
 
-static int st_mcompand_flow_1(compand_t c, comp_band_t l, st_sample_t *ibuf, st_sample_t *obuf, int len, int filechans)
+static int st_mcompand_flow_1(compand_t c, comp_band_t l, const st_sample_t *ibuf, st_sample_t *obuf, int len, int filechans)
 {
   int done, chan;
 
@@ -542,10 +541,10 @@
       if (c->delay_buf_size <= 0)
         obuf[done++] = ibuf[chan]*(outv/v)*l->outgain;
       else {
+        /* FIXME: note that this lookahead algorithm is really lame:
+           the response to a peak is released before the peak
+           arrives. */
 
-
-        /* note that this lookahead algorithm is really lame.  the response to a peak is released before the peak arrives.  fix! */
-
         /* because volume application delays differ band to band, but
            total delay doesn't, the volume is applied in an iteration
            preceding that in which the sample goes to obuf, except in
@@ -574,13 +573,13 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_mcompand_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_mcompand_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                      st_size_t *isamp, st_size_t *osamp) {
   compand_t c = (compand_t) effp->priv;
   comp_band_t l;
-  int len = ((*isamp > *osamp) ? *osamp : *isamp);
+  int len = min(*isamp, *osamp);
   int band, i;
-  st_sample_t *abuf, *bbuf, *cbuf, *oldabuf;
+  st_sample_t *abuf, *bbuf, *cbuf, *oldabuf, *ibuf_copy;
   double out;
 
   if (c->band_buf_len < len) {
@@ -593,10 +592,13 @@
     c->band_buf_len = len;
   }
 
+  ibuf_copy = (st_sample_t *)malloc(*isamp * sizeof(st_sample_t));
+  memcpy(ibuf_copy, ibuf, *isamp * sizeof(st_sample_t));
+
   /* split ibuf into bands using butterworths, pipe each band through st_mcompand_flow_1, then add back together and write to obuf */
 
   memset(obuf,0,len * sizeof *obuf);
-  for (band=0,abuf=ibuf,bbuf=c->band_buf2,cbuf=c->band_buf1;band<c->nBands;++band) {
+  for (band=0,abuf=ibuf_copy,bbuf=c->band_buf2,cbuf=c->band_buf1;band<c->nBands;++band) {
     l = &c->bands[band];
 
     if (l->topfreq)
@@ -605,7 +607,7 @@
       bbuf = abuf;
       abuf = cbuf;
     }
-    if (abuf == ibuf)
+    if (abuf == ibuf_copy)
       abuf = c->band_buf3;
     (void)st_mcompand_flow_1(c,l,bbuf,abuf,len,effp->outinfo.channels);
     for (i=0;i<len;++i)
@@ -620,6 +622,8 @@
   }
 
   *isamp = *osamp = len;
+
+  free(ibuf_copy);
 
   return ST_SUCCESS;
 }
--- a/src/noiseprof.c
+++ b/src/noiseprof.c
@@ -109,7 +109,7 @@
 /*
  * Grab what we can from ibuf, and process if we have a whole window.
  */
-int st_noiseprof_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_noiseprof_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
     profdata_t data = (profdata_t) effp->priv;
--- a/src/noisered.c
+++ b/src/noisered.c
@@ -246,7 +246,7 @@
 /*
  * Read in windows, and call process_window once we get a whole one.
  */
-int st_noisered_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_noisered_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
     reddata_t data = (reddata_t) effp->priv;
--- a/src/pan.c
+++ b/src/pan.c
@@ -17,6 +17,7 @@
  */
 
 #include "st_i.h"
+#include <string.h>
 
 static st_effect_t st_pan_effect;
 
@@ -66,20 +67,24 @@
 
 #define UNEXPECTED_CHANNELS \
     st_fail("unexpected number of channels (in=%d, out=%d)", ich, och); \
+    free(ibuf_copy); \
     return ST_EOF
 
 /*
  * Process either isamp or osamp samples, whichever is smaller.
  */
-int st_pan_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_pan_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                 st_size_t *isamp, st_size_t *osamp)
 {
     pan_t pan = (pan_t) effp->priv;
-    register st_size_t len;
-    st_size_t done;
+    st_size_t len, done;
+    st_sample_t *ibuf_copy;
     char ich, och;
-    register double left, right, dir, hdir;
+    double left, right, dir, hdir;
     
+    ibuf_copy = (st_sample_t *)malloc(*isamp * sizeof(st_sample_t));
+    memcpy(ibuf_copy, ibuf, *isamp * sizeof(st_sample_t));
+
     dir   = pan->dir;    /* -1   <=  dir  <= 1   */
     hdir  = 0.5 * dir;  /* -0.5 <=  hdir <= 0.5 */
     left  = 0.5 - hdir; /*  0   <=  left <= 1   */
@@ -100,16 +105,16 @@
         switch (ich) {
         case 1: /* simple copy */
             for (done=0; done<len; done++)
-                *obuf++ = *ibuf++;
+                *obuf++ = *ibuf_copy++;
             break;
         case 2: /* average 2 */
             for (done=0; done<len; done++)
             {
                 double f;
-                f = 0.5*ibuf[0] + 0.5*ibuf[1];
+                f = 0.5*ibuf_copy[0] + 0.5*ibuf_copy[1];
                 ST_EFF_SAMPLE_CLIP_COUNT(f);
                 *obuf++ = f;
-                ibuf += 2;
+                ibuf_copy += 2;
             }
             break;
         case 4: /* average 4 */
@@ -116,11 +121,11 @@
             for (done=0; done<len; done++)
             {
                 double f;
-                f = 0.25*ibuf[0] + 0.25*ibuf[1] + 
-                        0.25*ibuf[2] + 0.25*ibuf[3];
+                f = 0.25*ibuf_copy[0] + 0.25*ibuf_copy[1] + 
+                        0.25*ibuf_copy[2] + 0.25*ibuf_copy[3];
                 ST_EFF_SAMPLE_CLIP_COUNT(f);
                 *obuf++ = f;
-                ibuf += 4;
+                ibuf_copy += 4;
             }
             break;
         default:
@@ -135,14 +140,14 @@
             {
                 double f;
 
-                f = left * ibuf[0];
+                f = left * ibuf_copy[0];
                 ST_EFF_SAMPLE_CLIP_COUNT(f);
                 obuf[0] = f;
-                f = right * ibuf[0];
+                f = right * ibuf_copy[0];
                 ST_EFF_SAMPLE_CLIP_COUNT(f);
                 obuf[1] = f;
                 obuf += 2;
-                ibuf++;
+                ibuf_copy++;
             }
             break;
         case 2: /* linear panorama. 
@@ -161,14 +166,14 @@
                 {
                     double f;
 
-                    f = cll * ibuf[0] + clr * ibuf[1];
+                    f = cll * ibuf_copy[0] + clr * ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[0] = f;
-                    f = cr * ibuf[1];
+                    f = cr * ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[1] = f;
                     obuf += 2;
-                    ibuf += 2;
+                    ibuf_copy += 2;
                 }
             }
             else /* to the right */
@@ -184,14 +189,14 @@
                 {
                     double f;
 
-                    f = cl * ibuf[0];
+                    f = cl * ibuf_copy[0];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[0] = f;
-                    f = crl * ibuf[0] + crr * ibuf[1];
+                    f = crl * ibuf_copy[0] + crr * ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[1] = f;
                     obuf += 2;
-                    ibuf += 2;
+                    ibuf_copy += 2;
                 }
             }
             break;
@@ -210,8 +215,8 @@
                     register double ibuf0, ibuf1, f;
 
                     /* build stereo signal */
-                    ibuf0 = 0.5*ibuf[0] + 0.5*ibuf[2];
-                    ibuf1 = 0.5*ibuf[1] + 0.5*ibuf[3];
+                    ibuf0 = 0.5*ibuf_copy[0] + 0.5*ibuf_copy[2];
+                    ibuf1 = 0.5*ibuf_copy[1] + 0.5*ibuf_copy[3];
 
                     /* pan it */
                     f = cll * ibuf0 + clr * ibuf1;
@@ -221,7 +226,7 @@
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[1] = f;
                     obuf += 2;
-                    ibuf += 4;
+                    ibuf_copy += 4;
                 }
             }
             else /* to the right */
@@ -237,8 +242,8 @@
                 {
                     register double ibuf0, ibuf1, f;
 
-                    ibuf0 = 0.5*ibuf[0] + 0.5*ibuf[2];
-                    ibuf1 = 0.5*ibuf[1] + 0.5*ibuf[3];
+                    ibuf0 = 0.5*ibuf_copy[0] + 0.5*ibuf_copy[2];
+                    ibuf1 = 0.5*ibuf_copy[1] + 0.5*ibuf_copy[3];
 
                     f = cl * ibuf0;
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
@@ -247,7 +252,7 @@
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[1] = f;
                     obuf += 2;
-                    ibuf += 4;
+                    ibuf_copy += 4;
                 }
             }
             break;
@@ -269,14 +274,14 @@
                 {
                     double f;
 
-                    f = cl * ibuf[0];
+                    f = cl * ibuf_copy[0];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[2] = obuf[0] = f;
-                    f = cr * ibuf[0];
+                    f = cr * ibuf_copy[0];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
-                    ibuf[3] = obuf[1] = f;
+                    ibuf_copy[3] = obuf[1] = f;
                     obuf += 4;
-                    ibuf++;
+                    ibuf_copy++;
                 }
             }
             break;
@@ -294,14 +299,14 @@
                 {
                     double f;
 
-                    f = cll * ibuf[0] + clr * ibuf[1];
+                    f = cll * ibuf_copy[0] + clr * ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[2] = obuf[0] = f;
-                    f = cr * ibuf[1];
+                    f = cr * ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
-                    ibuf[3] = obuf[1] = f;
+                    ibuf_copy[3] = obuf[1] = f;
                     obuf += 4;
-                    ibuf += 2;
+                    ibuf_copy += 2;
                 }
             }
             else /* to the right */
@@ -317,14 +322,14 @@
                 {
                     double f;
 
-                    f = cl * ibuf[0];
+                    f = cl * ibuf_copy[0];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[2] = obuf[0] =f ;
-                    f = crl * ibuf[0] + crr * ibuf[1];
+                    f = crl * ibuf_copy[0] + crr * ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
-                    ibuf[3] = obuf[1] = f;
+                    ibuf_copy[3] = obuf[1] = f;
                     obuf += 4;
-                    ibuf += 2;
+                    ibuf_copy += 2;
                 }
             }
             break;
@@ -343,20 +348,20 @@
                 {
                     double f;
 
-                    f = cown*ibuf[0] + cright*ibuf[1];
+                    f = cown*ibuf_copy[0] + cright*ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[0] = f;
-                    f = cown*ibuf[1] + cright*ibuf[3];
+                    f = cown*ibuf_copy[1] + cright*ibuf_copy[3];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[1] = f;
-                    f = cown*ibuf[2] + cright*ibuf[0];
+                    f = cown*ibuf_copy[2] + cright*ibuf_copy[0];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[2] = f;
-                    f = cown*ibuf[3] + cright*ibuf[2];
+                    f = cown*ibuf_copy[3] + cright*ibuf_copy[2];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[3] = f;
                     obuf += 4;
-                    ibuf += 4;              
+                    ibuf_copy += 4;              
                 }
             }
             else /* to the right */
@@ -370,20 +375,20 @@
                 {
                     double f;
 
-                    f = cleft*ibuf[2] + cown*ibuf[0];
+                    f = cleft*ibuf_copy[2] + cown*ibuf_copy[0];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[0] = f;
-                    f = cleft*ibuf[0] + cown*ibuf[1];
+                    f = cleft*ibuf_copy[0] + cown*ibuf_copy[1];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[1] = f;
-                    f = cleft*ibuf[3] + cown*ibuf[2];
+                    f = cleft*ibuf_copy[3] + cown*ibuf_copy[2];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[2] = f;
-                    f = cleft*ibuf[1] + cown*ibuf[3];
+                    f = cleft*ibuf_copy[1] + cown*ibuf_copy[3];
                     ST_EFF_SAMPLE_CLIP_COUNT(f);
                     obuf[3] = f;
                     obuf += 4;
-                    ibuf += 4;
+                    ibuf_copy += 4;
                 }
             }
             break;
@@ -397,6 +402,8 @@
         break;
     } /* end switch out channel */
 
+    free(ibuf_copy);
+    
     return ST_SUCCESS;
 }
 
--- a/src/phaser.c
+++ b/src/phaser.c
@@ -194,7 +194,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_phaser_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_phaser_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                    st_size_t *isamp, st_size_t *osamp)
 {
         phaser_t phaser = (phaser_t) effp->priv;
--- a/src/pitch.c
+++ b/src/pitch.c
@@ -169,7 +169,7 @@
  */
 static void interpolation(
   pitch_t pitch,
-  st_sample_t *ibuf, int ilen, 
+  const st_sample_t *ibuf, int ilen, 
   double * out, int olen,
   double rate) /* signed */
 {
@@ -445,7 +445,7 @@
 
 /* Processes input.
  */
-int st_pitch_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_pitch_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                 st_size_t *isamp, st_size_t *osamp)
 {
     pitch_t pitch = (pitch_t) effp->priv;
--- a/src/polyphas.c
+++ b/src/polyphas.c
@@ -523,7 +523,7 @@
 
 }
 
-int st_poly_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
+int st_poly_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf,
                  st_size_t *isamp, st_size_t *osamp)
 {
   poly_t rate = (poly_t) effp->priv;
--- a/src/rabbit.c
+++ b/src/rabbit.c
@@ -104,7 +104,7 @@
 /*
  * Read all the data.
  */
-int st_rabbit_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
+int st_rabbit_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf,
                    st_size_t *isamp, st_size_t *osamp)
 {
   rabbit_t r = (rabbit_t) effp->priv;
--- a/src/rate.c
+++ b/src/rate.c
@@ -9,7 +9,7 @@
  
 int st_resample_getopts(eff_t effp, int n, char **argv);
 int st_resample_start(eff_t effp);
-int st_resample_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_resample_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                      st_size_t *isamp, st_size_t *osamp);
 int st_resample_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp);
 int st_resample_stop(eff_t effp);
--- a/src/repeat.c
+++ b/src/repeat.c
@@ -70,7 +70,7 @@
         return (ST_SUCCESS);
 }
 
-int st_repeat_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
+int st_repeat_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf,
                 st_size_t *isamp, st_size_t *osamp)
 {
         repeat_t repeat = (repeat_t)effp->priv;
--- a/src/resample.c
+++ b/src/resample.c
@@ -309,7 +309,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_resample_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_resample_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                      st_size_t *isamp, st_size_t *osamp)
 {
         resample_t r = (resample_t) effp->priv;
--- a/src/reverb.c
+++ b/src/reverb.c
@@ -208,7 +208,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_reverb_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_reverb_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                    st_size_t *isamp, st_size_t *osamp)
 {
         reverb_t reverb = (reverb_t) effp->priv;
--- a/src/reverse.c
+++ b/src/reverse.c
@@ -67,7 +67,7 @@
  * Effect flow: a degenerate case: write input samples on temporary file,
  * don't generate any output samples.
  */
-int st_reverse_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_reverse_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
         reverse_t reverse = (reverse_t) effp->priv;
--- a/src/silence.c
+++ b/src/silence.c
@@ -385,7 +385,7 @@
 
 /* Process signed long samples from ibuf to obuf. */
 /* Return number of samples processed in isamp and osamp. */
-int st_silence_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_silence_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
     silence_t silence = (silence_t) effp->priv;
--- a/src/skeleff.c
+++ b/src/skeleff.c
@@ -57,7 +57,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_skeleff_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_skeleff_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
     skeleff_t skeleff = (skeleff_t) effp->priv;
--- a/src/sox.c
+++ b/src/sox.c
@@ -1369,7 +1369,8 @@
 static int flow_effect(int e)
 {
     st_ssize_t i, done, idone, odone, idonel, odonel, idoner, odoner;
-    st_sample_t *ibuf, *obuf;
+    const st_sample_t *ibuf;
+    st_sample_t *obuf;
     int effstatus, effstatusl, effstatusr;
 
     /* Do not attempt to do any more effect processing during
--- a/src/speed.c
+++ b/src/speed.c
@@ -192,14 +192,18 @@
 
 /* handle a flow.
  */
-int st_speed_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_speed_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                   st_size_t *isamp, st_size_t *osamp)
 {
     speed_t speed;
-    register st_size_t len, iindex, oindex;
+    st_size_t len, iindex, oindex;
+    st_sample_t *ibuf_copy;
 
     speed = (speed_t) effp->priv;
 
+    ibuf_copy = (st_sample_t *)malloc(*isamp * sizeof(st_sample_t));
+    memcpy(ibuf_copy, ibuf, *isamp * sizeof(st_sample_t));
+
     len = min(*isamp, *osamp);
     iindex = 0;
     oindex = 0;
@@ -209,7 +213,7 @@
         /* store to input buffer. */
         if (speed->state==sp_input)
         {
-            speed->ibuf[speed->index++] = ibuf[iindex++];
+            speed->ibuf[speed->index++] = ibuf_copy[iindex++];
             if (speed->index==speed->compression)
                 speed->state = sp_transfer;
         }
@@ -226,6 +230,8 @@
     *isamp = iindex;
     *osamp = oindex;
 
+    free(ibuf_copy);
+    
     return ST_SUCCESS;
 }
 
--- a/src/st.h
+++ b/src/st.h
@@ -301,7 +301,7 @@
 
     int (*getopts)(eff_t effp, int argc, char **argv);
     int (*start)(eff_t effp);
-    int (*flow)(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
+    int (*flow)(eff_t effp, const const st_sample_t *ibuf, st_sample_t *obuf,
                 st_size_t *isamp, st_size_t *osamp);
     int (*drain)(eff_t effp, st_sample_t *obuf, st_size_t *osamp);
     int (*stop)(eff_t effp);
--- a/src/stat.c
+++ b/src/stat.c
@@ -152,7 +152,7 @@
  * Return number of samples processed.
  */
 
-int st_stat_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
+int st_stat_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf,
                  st_size_t *isamp, st_size_t *osamp)
 {
         stat_t stat = (stat_t) effp->priv;
--- a/src/stretch.c
+++ b/src/stretch.c
@@ -276,7 +276,7 @@
 /*
  * Processes flow.
  */
-int st_stretch_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_stretch_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                     st_size_t *isamp, st_size_t *osamp)
 {
     stretch_t stretch = (stretch_t) effp->priv;
--- a/src/swap.c
+++ b/src/swap.c
@@ -128,7 +128,7 @@
  * Processed signed long samples from ibuf to obuf.
  * Return number of samples processed.
  */
-int st_swap_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_swap_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
     swap_t swap = (swap_t) effp->priv;
--- a/src/synth.c
+++ b/src/synth.c
@@ -678,7 +678,7 @@
 /*
  * Processed signed long samples from ibuf to obuf.
  */
-int st_synth_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_synth_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                   st_size_t *isamp, st_size_t *osamp)
 {
     synth_t synth = (synth_t) effp->priv;
--- a/src/trim.c
+++ b/src/trim.c
@@ -128,7 +128,7 @@
  * Place in buf[].
  * Return number of samples read.
  */
-int st_trim_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_trim_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                  st_size_t *isamp, st_size_t *osamp)
 {
     int finished = 0;
--- a/src/vibro.c
+++ b/src/vibro.c
@@ -104,7 +104,7 @@
  * Return number of samples processed.
  */
 
-int st_vibro_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_vibro_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                   st_size_t *isamp, st_size_t *osamp)
 {
         vibro_t vibro = (vibro_t) effp->priv;
--- a/src/vol.c
+++ b/src/vol.c
@@ -119,7 +119,7 @@
 /*
  * Process data.
  */
-int st_vol_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf, 
+int st_vol_flow(eff_t effp, const st_sample_t *ibuf, st_sample_t *obuf, 
                 st_size_t *isamp, st_size_t *osamp)
 {
     vol_t vol = (vol_t) effp->priv;