shithub: sox

Download patch

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)