ref: e0e9c9962ab93d08f9f7f5ddee482e77fb44e8fe
parent: 8e0aa733262401fd8b59e804ef6b82e8604be9ca
author: cbagwell <cbagwell>
date: Sun Feb 19 13:13:29 EST 2006
Stop "filter" infinit loop. Stop crashing when no filename extension.
--- a/Changelog
+++ b/Changelog
@@ -4,6 +4,17 @@
This file contains a list of all changes starting after the release of
sox-11gamma.
+sox-12.1x.xx
+------------
+
+ o The "filter" effect could go into infinite drain mode. Now
+ only drain 1 buffer.
+ o SoX was ignoring user aborts (ctrl-c) if it occured during
+ effect drain operations. This was bad if effects had
+ bugs and stuck in infinite loop.
+ o Stop SoX from crashing when file type could not be auto
+ determined (bug 1417776).
+
sox-12.17.9
-----------
--- a/src/auto.c
+++ b/src/auto.c
@@ -173,6 +173,11 @@
type = NULL;
}
+ if(!type)
+ {
+ st_fail_errno(ft,ST_EFMT, "Could not determine file type.\n");
+ return (ST_EOF);
+ }
free(ft->filetype);
ft->filetype = strdup(type);
rc = st_gettype(ft); /* Change ft->h to the new format */
--- a/src/filter.c
+++ b/src/filter.c
@@ -39,15 +39,15 @@
/* Private data for Lerp via LCM file */
typedef struct filterstuff {
- st_rate_t rate;
- st_sample_t freq0;/* low corner freq */
- st_sample_t freq1;/* high corner freq */
- double beta;/* >2 is kaiser window beta, <=2 selects nuttall window */
- long Nwin;
- Float *Fp;/* [Xh+1] Filter coefficients */
- long Xh;/* number of past/future samples needed by filter */
- long Xt;/* target to enter new data into X */
- Float *X, *Y;/* I/O buffers */
+ st_rate_t rate;
+ st_sample_t freq0;/* low corner freq */
+ st_sample_t freq1;/* high corner freq */
+ double beta;/* >2 is kaiser window beta, <=2 selects nuttall window */
+ long Nwin;
+ Float *Fp;/* [Xh+1] Filter coefficients */
+ long Xh;/* number of past/future samples needed by filter */
+ long Xt;/* target to enter new data into X */
+ Float *X, *Y;/* I/O buffers */
} *filter_t;
/* makeFilter() declared in resample.c */
@@ -61,49 +61,49 @@
*/
int st_filter_getopts(eff_t effp, int n, char **argv)
{
- filter_t f = (filter_t) effp->priv;
+ filter_t f = (filter_t) effp->priv;
- f->beta = 16; /* Kaiser window, beta 16 */
- f->Nwin = 128;
-
- f->freq0 = f->freq1 = 0;
- if (n >= 1) {
- char *p;
- p = argv[0];
- if (*p != '-') {
- f->freq1 = strtol(p, &p, 10);
- }
- if (*p == '-') {
- f->freq0 = f->freq1;
- f->freq1 = strtol(p+1, &p, 10);
- }
- if (*p) f->freq1 = f->freq0 = 0;
- }
- /* fprintf(stderr,"freq: %d-%d\n", f->freq0, f->freq1);fflush(stderr); */
- if (f->freq0 == 0 && f->freq1 == 0)
- {
- st_fail("Usage: filter low-high [ windowlength [ beta ] ]");
- return (ST_EOF);
- }
+ f->beta = 16; /* Kaiser window, beta 16 */
+ f->Nwin = 128;
+
+ f->freq0 = f->freq1 = 0;
+ if (n >= 1) {
+ char *p;
+ p = argv[0];
+ if (*p != '-') {
+ f->freq1 = strtol(p, &p, 10);
+ }
+ if (*p == '-') {
+ f->freq0 = f->freq1;
+ f->freq1 = strtol(p+1, &p, 10);
+ }
+ if (*p) f->freq1 = f->freq0 = 0;
+ }
+ /* fprintf(stderr,"freq: %d-%d\n", f->freq0, f->freq1);fflush(stderr); */
+ if (f->freq0 == 0 && f->freq1 == 0)
+ {
+ st_fail("Usage: filter low-high [ windowlength [ beta ] ]");
+ return (ST_EOF);
+ }
- if ((n >= 2) && !sscanf(argv[1], "%ld", &f->Nwin))
- {
- st_fail("Usage: filter low-high [ windowlength ]");
- return (ST_EOF);
- }
- else if (f->Nwin < 4) {
- st_fail("filter: window length (%ld) <4 is too short", f->Nwin);
- return (ST_EOF);
- }
+ if ((n >= 2) && !sscanf(argv[1], "%ld", &f->Nwin))
+ {
+ st_fail("Usage: filter low-high [ windowlength ]");
+ return (ST_EOF);
+ }
+ else if (f->Nwin < 4) {
+ st_fail("filter: window length (%ld) <4 is too short", f->Nwin);
+ return (ST_EOF);
+ }
- if ((n >= 3) && !sscanf(argv[2], "%lf", &f->beta))
- {
- st_fail("Usage: filter low-high [ windowlength [ beta ] ]");
- return (ST_EOF);
- }
+ if ((n >= 3) && !sscanf(argv[2], "%lf", &f->beta))
+ {
+ st_fail("Usage: filter low-high [ windowlength [ beta ] ]");
+ return (ST_EOF);
+ }
- st_report("filter opts: %d-%d, window-len %d, beta %f\n", f->freq0, f->freq1, f->Nwin, f->beta);
- return (ST_SUCCESS);
+ st_report("filter opts: %d-%d, window-len %d, beta %f\n", f->freq0, f->freq1, f->Nwin, f->beta);
+ return (ST_SUCCESS);
}
/*
@@ -111,76 +111,76 @@
*/
int st_filter_start(eff_t effp)
{
- filter_t f = (filter_t) effp->priv;
- Float *Fp0, *Fp1;
- long Xh0, Xh1, Xh;
- int i;
+ filter_t f = (filter_t) effp->priv;
+ Float *Fp0, *Fp1;
+ long Xh0, Xh1, Xh;
+ int i;
- f->rate = effp->ininfo.rate;
+ f->rate = effp->ininfo.rate;
- /* adjust upper frequency to Nyquist if necessary */
- if (f->freq1 > f->rate/2 || f->freq1 <= 0)
- f->freq1 = f->rate/2;
+ /* adjust upper frequency to Nyquist if necessary */
+ if (f->freq1 > f->rate/2 || f->freq1 <= 0)
+ f->freq1 = f->rate/2;
- if ((f->freq0 < 0) || (f->freq0 > f->freq1))
- {
- st_fail("filter: low(%d),high(%d) parameters must satisfy 0 <= low <= high <= %d",
- f->freq0, f->freq1, f->rate/2);
- return (ST_EOF);
- }
-
- Xh = f->Nwin/2;
- Fp0 = (Float *) malloc(sizeof(Float) * (Xh + 2)) + 1;
- if (f->freq0 > f->rate/200) {
- Xh0 = makeFilter(Fp0, Xh, 2.0*(double)f->freq0/f->rate, f->beta, 1, 0);
- if (Xh0 <= 1)
- {
- st_fail("filter: Unable to make low filter\n");
- return (ST_EOF);
- }
- } else {
- Xh0 = 0;
- }
- Fp1 = (Float *) malloc(sizeof(Float) * (Xh + 2)) + 1;
- /* need Fp[-1] and Fp[Xh] for makeFilter */
- if (f->freq1 < f->rate/2) {
- Xh1 = makeFilter(Fp1, Xh, 2.0*(double)f->freq1/f->rate, f->beta, 1, 0);
- if (Xh1 <= 1)
- {
- st_fail("filter: Unable to make high filter\n");
- return (ST_EOF);
- }
- } else {
- Fp1[0] = 1.0;
- Xh1 = 1;
- }
- /* now subtract Fp0[] from Fp1[] */
- Xh = (Xh0>Xh1)? Xh0:Xh1; /* >=1, by above */
- for (i=0; i<Xh; i++) {
- Float c0,c1;
- c0 = (i<Xh0)? Fp0[i]:0;
- c1 = (i<Xh1)? Fp1[i]:0;
- Fp1[i] = c1-c0;
- }
+ if ((f->freq0 < 0) || (f->freq0 > f->freq1))
+ {
+ st_fail("filter: low(%d),high(%d) parameters must satisfy 0 <= low <= high <= %d",
+ f->freq0, f->freq1, f->rate/2);
+ return (ST_EOF);
+ }
+
+ Xh = f->Nwin/2;
+ Fp0 = (Float *) malloc(sizeof(Float) * (Xh + 2)) + 1;
+ if (f->freq0 > f->rate/200) {
+ Xh0 = makeFilter(Fp0, Xh, 2.0*(double)f->freq0/f->rate, f->beta, 1, 0);
+ if (Xh0 <= 1)
+ {
+ st_fail("filter: Unable to make low filter\n");
+ return (ST_EOF);
+ }
+ } else {
+ Xh0 = 0;
+ }
+ Fp1 = (Float *) malloc(sizeof(Float) * (Xh + 2)) + 1;
+ /* need Fp[-1] and Fp[Xh] for makeFilter */
+ if (f->freq1 < f->rate/2) {
+ Xh1 = makeFilter(Fp1, Xh, 2.0*(double)f->freq1/f->rate, f->beta, 1, 0);
+ if (Xh1 <= 1)
+ {
+ st_fail("filter: Unable to make high filter\n");
+ return (ST_EOF);
+ }
+ } else {
+ Fp1[0] = 1.0;
+ Xh1 = 1;
+ }
+ /* now subtract Fp0[] from Fp1[] */
+ Xh = (Xh0>Xh1)? Xh0:Xh1; /* >=1, by above */
+ for (i=0; i<Xh; i++) {
+ Float c0,c1;
+ c0 = (i<Xh0)? Fp0[i]:0;
+ c1 = (i<Xh1)? Fp1[i]:0;
+ Fp1[i] = c1-c0;
+ }
- free(Fp0 - 1); /* all done with Fp0 */
- f->Fp = Fp1;
+ free(Fp0 - 1); /* all done with Fp0 */
+ f->Fp = Fp1;
- Xh -= 1; /* Xh = 0 can only happen if filter was identity 0-Nyquist */
- if (Xh<=0)
- st_warn("filter: adjusted freq %d-%d is identity", f->freq0, f->freq1);
+ Xh -= 1; /* Xh = 0 can only happen if filter was identity 0-Nyquist */
+ if (Xh<=0)
+ st_warn("filter: adjusted freq %d-%d is identity", f->freq0, f->freq1);
- f->Nwin = 2*Xh + 1; /* not really used afterwards */
- f->Xh = Xh;
- f->Xt = Xh;
+ f->Nwin = 2*Xh + 1; /* not really used afterwards */
+ f->Xh = Xh;
+ f->Xt = Xh;
- f->X = (Float *) malloc(sizeof(Float) * (2*BUFFSIZE + 2*Xh));
- f->Y = f->X + BUFFSIZE + 2*Xh;
+ f->X = (Float *) malloc(sizeof(Float) * (2*BUFFSIZE + 2*Xh));
+ f->Y = f->X + BUFFSIZE + 2*Xh;
- /* Need Xh zeros at beginning of X */
- for (i = 0; i < Xh; i++)
- f->X[i] = 0;
- return (ST_SUCCESS);
+ /* Need Xh zeros at beginning of X */
+ for (i = 0; i < Xh; i++)
+ f->X[i] = 0;
+ return (ST_SUCCESS);
}
/*
@@ -190,50 +190,50 @@
int st_filter_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
st_size_t *isamp, st_size_t *osamp)
{
- filter_t f = (filter_t) effp->priv;
- long i, Nx, Nproc;
+ filter_t f = (filter_t) effp->priv;
+ long i, Nx, Nproc;
- /* constrain amount we actually process */
- /* fprintf(stderr,"Xh %d, Xt %d, isamp %d, ",f->Xh, f->Xt, *isamp);fflush(stderr); */
- Nx = BUFFSIZE + 2*f->Xh - f->Xt;
- if (Nx > *isamp) Nx = *isamp;
- if (Nx > *osamp) Nx = *osamp;
- *isamp = Nx;
+ /* constrain amount we actually process */
+ /* fprintf(stderr,"Xh %d, Xt %d, isamp %d, ",f->Xh, f->Xt, *isamp);fflush(stderr); */
+ Nx = BUFFSIZE + 2*f->Xh - f->Xt;
+ if (Nx > *isamp) Nx = *isamp;
+ if (Nx > *osamp) Nx = *osamp;
+ *isamp = Nx;
- {
- Float *xp, *xtop;
- xp = f->X + f->Xt;
- xtop = xp + Nx;
- if (ibuf != NULL) {
- while (xp < xtop)
- *xp++ = (Float)(*ibuf++) / ISCALE;
- } else {
- while (xp < xtop)
- *xp++ = 0;
- }
- }
+ {
+ Float *xp, *xtop;
+ xp = f->X + f->Xt;
+ xtop = xp + Nx;
+ if (ibuf != NULL) {
+ while (xp < xtop)
+ *xp++ = (Float)(*ibuf++) / ISCALE;
+ } else {
+ while (xp < xtop)
+ *xp++ = 0;
+ }
+ }
- Nproc = f->Xt + Nx - 2*f->Xh;
+ Nproc = f->Xt + Nx - 2*f->Xh;
- if (Nproc <= 0) {
- f->Xt += Nx;
- *osamp = 0;
- return (ST_SUCCESS);
- }
- /* fprintf(stderr,"flow Nproc %d\n",Nproc); */
- FiltWin(f, Nproc);
+ if (Nproc <= 0) {
+ f->Xt += Nx;
+ *osamp = 0;
+ return (ST_SUCCESS);
+ }
+ /* fprintf(stderr,"flow Nproc %d\n",Nproc); */
+ FiltWin(f, Nproc);
- /* Copy back portion of input signal that must be re-used */
- Nx += f->Xt;
- if (f->Xh)
- memmove(f->X, f->X + Nx - 2*f->Xh, sizeof(Float)*2*f->Xh);
- f->Xt = 2*f->Xh;
+ /* Copy back portion of input signal that must be re-used */
+ Nx += f->Xt;
+ if (f->Xh)
+ memmove(f->X, f->X + Nx - 2*f->Xh, sizeof(Float)*2*f->Xh);
+ f->Xt = 2*f->Xh;
- for (i = 0; i < Nproc; i++)
- *obuf++ = f->Y[i] * ISCALE;
+ for (i = 0; i < Nproc; i++)
+ *obuf++ = f->Y[i] * ISCALE;
- *osamp = Nproc;
- return (ST_SUCCESS);
+ *osamp = Nproc;
+ return (ST_SUCCESS);
}
/*
@@ -241,32 +241,32 @@
*/
int st_filter_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp)
{
- filter_t f = (filter_t) effp->priv;
- long isamp_res, osamp_res;
- st_sample_t *Obuf;
+ filter_t f = (filter_t) effp->priv;
+ long isamp_res, osamp_res;
+ st_sample_t *Obuf;
- /* fprintf(stderr,"Xh %d, Xt %d <--- DRAIN\n",f->Xh, f->Xt); */
+ /* fprintf(stderr,"Xh %d, Xt %d <--- DRAIN\n",f->Xh, f->Xt); */
- /* stuff end with Xh zeros */
- isamp_res = f->Xh;
- osamp_res = *osamp;
- Obuf = obuf;
- while (isamp_res>0 && osamp_res>0) {
- st_sample_t Isamp, Osamp;
- Isamp = isamp_res;
- Osamp = osamp_res;
- st_filter_flow(effp, NULL, Obuf, (st_size_t *)&Isamp, (st_size_t *)&Osamp);
- /* fprintf(stderr,"DRAIN isamp,osamp (%d,%d) -> (%d,%d)\n",
- * isamp_res,osamp_res,Isamp,Osamp); */
- Obuf += Osamp;
- osamp_res -= Osamp;
- isamp_res -= Isamp;
- };
- *osamp -= osamp_res;
- /* fprintf(stderr,"DRAIN osamp %d\n", *osamp); */
- if (isamp_res)
- st_warn("drain overran obuf by %d\n", isamp_res); fflush(stderr);
- return (ST_SUCCESS);
+ /* stuff end with Xh zeros */
+ isamp_res = f->Xh;
+ osamp_res = *osamp;
+ Obuf = obuf;
+ while (isamp_res>0 && osamp_res>0) {
+ st_sample_t Isamp, Osamp;
+ Isamp = isamp_res;
+ Osamp = osamp_res;
+ st_filter_flow(effp, NULL, Obuf, (st_size_t *)&Isamp, (st_size_t *)&Osamp);
+ /* fprintf(stderr,"DRAIN isamp,osamp (%d,%d) -> (%d,%d)\n",
+ * isamp_res,osamp_res,Isamp,Osamp); */
+ Obuf += Osamp;
+ osamp_res -= Osamp;
+ isamp_res -= Isamp;
+ };
+ *osamp -= osamp_res;
+ /* fprintf(stderr,"DRAIN osamp %d\n", *osamp); */
+ if (isamp_res)
+ st_warn("drain overran obuf by %d\n", isamp_res); fflush(stderr);
+ return (ST_EOF);
}
/*
@@ -275,39 +275,39 @@
*/
int st_filter_stop(eff_t effp)
{
- filter_t f = (filter_t) effp->priv;
+ filter_t f = (filter_t) effp->priv;
- free(f->Fp - 1);
- free(f->X);
- return (ST_SUCCESS);
+ free(f->Fp - 1);
+ free(f->X);
+ return (ST_SUCCESS);
}
static double jprod(const Float *Fp, const Float *Xp, long ct)
{
- const Float *fp, *xp, *xq;
- double v = 0;
-
- fp = Fp + ct; /* so sum starts with smaller coef's */
- xp = Xp - ct;
- xq = Xp + ct;
- while (fp > Fp) { /* ct = 0 can happen */
- v += *fp * (*xp + *xq);
- xp++; xq--; fp--;
- }
- v += *fp * *xp;
- return v;
+ const Float *fp, *xp, *xq;
+ double v = 0;
+
+ fp = Fp + ct; /* so sum starts with smaller coef's */
+ xp = Xp - ct;
+ xq = Xp + ct;
+ while (fp > Fp) { /* ct = 0 can happen */
+ v += *fp * (*xp + *xq);
+ xp++; xq--; fp--;
+ }
+ v += *fp * *xp;
+ return v;
}
static void FiltWin(filter_t f, long Nx)
{
- Float *Y;
- Float *X, *Xend;
+ Float *Y;
+ Float *X, *Xend;
- Y = f->Y;
- X = f->X + f->Xh; /* Ptr to current input sample */
- Xend = X + Nx;
- while (X < Xend) {
- *Y++ = jprod(f->Fp, X, f->Xh);
- X++;
- }
+ Y = f->Y;
+ X = f->X + f->Xh; /* Ptr to current input sample */
+ Xend = X + Nx;
+ while (X < Xend) {
+ *Y++ = jprod(f->Fp, X, f->Xh);
+ X++;
+ }
}
--- a/src/map.c
+++ /dev/null
@@ -1,65 +1,0 @@
-/*
- * July 5, 1991
- * Copyright 1991 Lance Norskog And Sundry Contributors
- * This source code is freely redistributable and may be used for
- * any purpose. This copyright notice must be maintained.
- * Lance Norskog And Sundry Contributors are not responsible for
- * the consequences of using this software.
- */
-
-/*
- * Sound Tools Map effect file.
- *
- * Print out map of sound file instrument specifications.
- */
-
-#include <math.h>
-#include "st_i.h"
-
-/*
- * Process options
- */
-int st_map_getopts(eff_t effp, int n, char **argv)
-{
- if (n)
- {
- st_fail("Map effect takes no options.");
- return (ST_EOF);
- }
- return (ST_SUCCESS);
-}
-
-/*
- * Prepare processing.
- */
-int st_map_start(eff_t effp)
-{
- int i;
-
- fprintf(stderr, "Loop info:\n");
- for(i = 0; i < 8; i++) {
- fprintf(stderr, "Loop %d: start: %6d",i,effp->loops[i].start);
- fprintf(stderr, " length: %6d", effp->loops[i].length);
- fprintf(stderr, " count: %6d", effp->loops[i].count);
- fprintf(stderr, " type: ");
- switch(effp->loops[i].type) {
- case 0: fprintf(stderr, "off\n"); break;
- case 1: fprintf(stderr, "forward\n"); break;
- case 2: fprintf(stderr, "forward/backward\n"); break;
- }
- }
- fprintf(stderr, "MIDI note: %d\n", effp->instr.MIDInote);
- fprintf(stderr, "MIDI low : %d\n", effp->instr.MIDIlow);
- fprintf(stderr, "MIDI hi : %d\n", effp->instr.MIDIhi);
- return (ST_SUCCESS);
-}
-
-/*
- * Processed signed long samples from ibuf to obuf.
- * Return number of samples processed.
- */
-int st_map_flow(eff_t effp, st_sample_t *ibuf, st_sample_t *obuf,
- st_size_t *isamp, st_size_t *osamp)
-{
- return (ST_SUCCESS);
-}
--- a/src/sox.c
+++ b/src/sox.c
@@ -1107,6 +1107,12 @@
total = 0;
do
{
+ /* Do not do any more writing during user aborts as
+ * we may be stuck in an infinite writing loop.
+ */
+ if (user_abort)
+ return ST_EOF;
+
len = st_write(file_desc[file_count-1],
&efftab[neffects-1].obuf[total],
(st_ssize_t)efftab[neffects-1].olen-total);
@@ -1207,6 +1213,12 @@
st_ssize_t i, done, idone, odone, idonel, odonel, idoner, odoner;
st_sample_t *ibuf, *obuf;
int effstatus;
+
+ /* Do not attempt to do any more effect processing during
+ * user aborts as we may be stuck in an infinit flow loop.
+ */
+ if (user_abort)
+ return ST_EOF;
/* I have no input data ? */
if (efftab[e-1].odone == efftab[e-1].olen)