ref: 892e60436b7b9d2014d4aa8dc583bc6331c41ad8
parent: 56b927281e4045f05dbfb7deb3dde17af8053540
author: robs <robs>
date: Fri Sep 26 04:50:34 EDT 2008
plot fix/update
--- a/ChangeLog
+++ b/ChangeLog
@@ -39,9 +39,9 @@
File formats:
+ o New unfiltered CVSD; supports any bit-rate. (robs)
o Fix WAV write on 64-bit arch. (robs)
o Fix writing PRC ADPCM files. (Silas Brown)
- o Unfiltered CVSD; supports any bit-rate. (robs)
Effects:
@@ -54,10 +54,12 @@
compensation. (robs)
o New -b option for the norm effect; can be used to fix stereo
imbalance. (robs)
- o Fix broken audio pass-through with noiseprof effect. (robs)
- o Improved documentation for the `stat' effect. (robs)
o New --effects-file option to read effects and arguments from
a file instead of command line. (cbagwell)
+ o `filter' effect now supports --plot octave. (robs)
+ o Improved documentation for the `stat' effect. (robs)
+ o Fix broken audio pass-through with noiseprof effect. (robs)
+ o Fix graph legend display when using --plot octave. (robs)
Other new features:
@@ -69,6 +71,7 @@
o New -t option for soxi; to display the detected file type. (robs)
o New -b/--bits, -e/--encoding alternative options for specifying
audio encoding parameters. (robs)
+ o [FR 1958680] Support more than 32 input files. (robs)
Other bug fixes:
@@ -88,7 +91,7 @@
o Fixed all compiler warnings (with gcc 4.3.1, 64-bit arch.). (robs)
o Updates to internal effects chain API. (cbagwell)
- o Retire old FFT routines (speeds up noisered effect). (robs)
+ o Retire old FFT routines (speeds up `noisered' effect). (robs)
o Allow effects to use getopt. (robs)
--- a/sox.1
+++ b/sox.1
@@ -1223,9 +1223,13 @@
A typical value is
.B 0\*d2
seconds.
+.TS
+center;
+c8 c8 c.
+* * *
+.TE
+.DT
.SP
-This effect supports the \fB\-\-plot\fR global option (for the transfer function).
-.SP
The following example might be used to make a piece of music with both
quiet and loud passages suitable for listening to in a noisy environment
such as a moving vehicle:
@@ -1246,6 +1250,8 @@
with near silence, and the delay of 0\*d2 (seconds) has the effect of causing
the compander to react a bit more quickly to sudden volume changes.
.SP
+This effect supports the \fB\-\-plot\fR global option (for the transfer function).
+.SP
See also
.B mcompand
for a multiple-band companding effect.
@@ -1494,7 +1500,7 @@
.SP
The \fIbeta\fR parameter
determines the type of filter window used. Any value greater than 2 is
-the beta for a Kaiser window. Beta \(<= 2 selects a Nuttall window.
+the beta for a Kaiser window. Beta \(<= 2 selects a Blackman-Nuttall window.
If unspecified, the default is a Kaiser window with beta 16.
.SP
In the case of Kaiser window (beta > 2), lower betas produce a
@@ -1501,11 +1507,13 @@
somewhat faster transition from pass-band to stop-band, at the cost of
noticeable artifacts. A beta of 16 is the default, beta less than 10
is not recommended. If you want a sharper cut-off, don't use low
-beta's, use a longer sample window. A Nuttall window is selected by
-specifying any `beta' \(<= 2, and the Nuttall window has somewhat
+beta's, use a longer sample window. A Blackman-Nuttall window is selected by
+specifying any `beta' \(<= 2, and the Blackman-Nuttall window has somewhat
steeper cut-off than the default Kaiser window. You will probably not
need to use the beta parameter at all, unless you are just curious
-about comparing the effects of Nuttall vs. Kaiser windows.
+about comparing the effects of Blackman-Nuttall vs. Kaiser windows.
+.SP
+This effect supports the \fB\-\-plot octave\fR global option.
.TP
\fBflanger\fR [\fIdelay depth regen width speed shape phase interp\fR]
Apply a flanging effect to the audio.
@@ -2941,9 +2949,9 @@
and, compared with the \fBrate\fR effect, is generally slow, memory intensive,
and has poorer stop-band rejection.
.SP
-If the \fB\-w\fR parameter is \fBnut\fR, then a Nuttall (~90 dB
+If the \fB\-w\fR parameter is \fBnut\fR, then a Blackman-Nuttall (~90 dB
stop-band) window will be used; \fBham\fR selects a Hamming (~43
-dB stop-band) window. The default is Nuttall.
+dB stop-band) window. The default is Blackman-Nuttall.
.SP
The \fB\-width\fR parameter specifies the (approximate) width of the filter. The default is 1024 samples, which produces reasonable results.
.SP
@@ -3049,7 +3057,7 @@
these artifacts, with closer also being better.
.SP
The \fIbeta\fR, if unspecified, defaults to 16. This selects a Kaiser window.
-You can select a Nuttall window by specifying anything \(<= 2 here.
+You can select a Blackman-Nuttall window by specifying anything \(<= 2 here.
For more discussion of beta, look under the \fBfilter\fR effect.
.SP
Default parameters are, as indicated above, Kaiser window of length 45,
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -70,20 +70,20 @@
if (effp->global_info->plot == sox_plot_octave) {
printf(
"%% GNU Octave file (may also work with MATLAB(R) )\n"
+ "Fs=%g;minF=10;maxF=Fs/2;\n"
+ "sweepF=logspace(log10(minF),log10(maxF),200);\n"
+ "[h,w]=freqz([%g %g %g],[1 %g %g],sweepF,Fs);\n"
+ "semilogx(w,20*log10(h))\n"
"title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%g)')\n"
"xlabel('Frequency (Hz)')\n"
"ylabel('Amplitude Response (dB)')\n"
- "Fs=%g;minF=10;maxF=Fs/2;\n"
"axis([minF maxF -35 25])\n"
- "sweepF=logspace(log10(minF),log10(maxF),200);\n"
"grid on\n"
- "[h,w]=freqz([%g %g %g],[1 %g %g],sweepF,Fs);\n"
- "semilogx(w,20*log10(h))\n"
"disp('Hit return to continue')\n"
"pause\n"
+ , effp->in_signal.rate, p->b0, p->b1, p->b2, p->a1, p->a2
, effp->handler.name, p->gain, p->fc, width_str[p->width_type], p->width
- , effp->in_signal.rate, effp->in_signal.rate
- , p->b0, p->b1, p->b2, p->a1, p->a2);
+ , effp->in_signal.rate);
return SOX_EOF;
}
if (effp->global_info->plot == sox_plot_gnuplot) {
--- a/src/compandt.c
+++ b/src/compandt.c
@@ -36,11 +36,7 @@
if (plot == sox_plot_octave) {
printf(
"%% GNU Octave file (may also work with MATLAB(R) )\n"
- "title('SoX effect: compand')\n"
- "xlabel('Input level (dB)')\n"
- "ylabel('Output level (dB)')\n"
"in=linspace(-99.5,0,200);\n"
- "grid on\n"
"out=[");
for (i = -199; i <= 0; ++i) {
double in = i/2.;
@@ -49,8 +45,12 @@
}
printf(
"];\n"
- "%%plot(in,out) %% hmm.. doesn't work :(\n"
- "semilogx(exp(in),out)\n"
+ "plot(in,out)\n"
+ "title('SoX effect: compand')\n"
+ "xlabel('Input level (dB)')\n"
+ "ylabel('Output level (dB)')\n"
+ "grid on\n"
+ "disp('Hit return to continue')\n"
"pause\n");
return sox_false;
}
--- a/src/filter.c
+++ b/src/filter.c
@@ -35,8 +35,8 @@
/* Private data for Lerp via LCM file */
typedef struct {
sox_rate_t rate;
- sox_sample_t freq0;/* low corner freq */
- sox_sample_t freq1;/* high corner freq */
+ double freq0;/* low corner freq */
+ double freq1;/* high corner freq */
double beta;/* >2 is kaiser window beta, <=2 selects nuttall window */
long Nwin;
double *Fp;/* [Xh+1] Filter coefficients */
@@ -53,9 +53,6 @@
* reference: "Digital Filters, 2nd edition"
* R.W. Hamming, pp. 178-179
*
- * Izero() computes the 0th order modified bessel function of the first kind.
- * (Needed to compute Kaiser window).
- *
* LpFilter() computes the coeffs of a Kaiser-windowed low pass filter with
* the following characteristics:
*
@@ -86,25 +83,6 @@
*/
-#define IzeroEPSILON 1E-21 /* Max error acceptable in Izero */
-
-static double Izero(double x)
-{
- double sum, u, halfx, temp;
- long n;
-
- sum = u = n = 1;
- halfx = x/2.0;
- do {
- temp = halfx/(double)n;
- n += 1;
- temp *= temp;
- u *= temp;
- sum += u;
- } while (u >= IzeroEPSILON*sum);
- return(sum);
-}
-
static void LpFilter(double *c, long N, double frq, double Beta, long Num)
{
long i;
@@ -117,15 +95,15 @@
}
if (Beta>2) { /* Apply Kaiser window to filter coeffs: */
- double IBeta = 1.0/Izero(Beta);
+ double IBeta = 1.0/lsx_bessel_I_0(Beta);
for (i=1; i<N; i++) {
double x = (double)i / (double)(N);
- c[i] *= Izero(Beta*sqrt(1.0-x*x)) * IBeta;
+ c[i] *= lsx_bessel_I_0(Beta*sqrt(1.0-x*x)) * IBeta;
}
} else { /* Apply Nuttall window: */
for(i = 0; i < N; i++) {
double x = M_PI*i / N;
- c[i] *= 0.36335819 + 0.4891775*cos(x) + 0.1365995*cos(2*x) + 0.0106411*cos(3*x);
+ c[i] *= 0.3635819 + 0.4891775*cos(x) + 0.1365995*cos(2*x) + 0.0106411*cos(3*x);
}
}
}
@@ -203,7 +181,7 @@
}
if (*p) f->freq1 = f->freq0 = 0;
}
- sox_debug("freq: %d-%d", f->freq0, f->freq1);
+ sox_debug("freq: %g-%g", f->freq0, f->freq1);
if (f->freq0 == 0 && f->freq1 == 0)
return lsx_usage(effp);
@@ -217,7 +195,7 @@
if ((n >= 3) && !sscanf(argv[2], "%lf", &f->beta))
return lsx_usage(effp);
- sox_debug("filter opts: %d-%d, window-len %ld, beta %f", f->freq0, f->freq1, f->Nwin, f->beta);
+ sox_debug("filter opts: %g-%g, window-len %ld, beta %f", f->freq0, f->freq1, f->Nwin, f->beta);
return (SOX_SUCCESS);
}
@@ -239,7 +217,7 @@
if ((f->freq0 < 0) || (f->freq0 > f->freq1))
{
- sox_fail("filter: low(%d),high(%d) parameters must satisfy 0 <= low <= high <= %g",
+ sox_fail("filter: low(%g),high(%g) parameters must satisfy 0 <= low <= high <= %g",
f->freq0, f->freq1, f->rate/2);
return (SOX_EOF);
}
@@ -285,11 +263,30 @@
Xh -= 1; /* Xh = 0 can only happen if filter was identity 0-Nyquist */
if (Xh<=0)
- sox_warn("filter: adjusted freq %d-%d is identity", f->freq0, f->freq1);
+ sox_warn("filter: adjusted freq %g-%g is identity", f->freq0, f->freq1);
f->Nwin = 2*Xh + 1; /* not really used afterwards */
f->Xh = Xh;
f->Xt = Xh;
+
+ if (effp->global_info->plot == sox_plot_octave) {
+ printf("%% GNU Octave file (may also work with MATLAB(R) )\nb=[");
+ for (i = 1; i < Xh + 1; ++i)
+ printf("%24.16e\n", f->Fp[Xh + 1 - i]);
+ for (i = 0; i < Xh + 1; ++i)
+ printf("%24.16e\n", f->Fp[i]);
+ printf("];\n"
+ "[h,w]=freqz(b);\n"
+ "plot(%g*w/pi,20*log10(h))\n"
+ "title('SoX effect: filter frequency=%g-%g')\n"
+ "xlabel('Frequency (Hz)')\n"
+ "ylabel('Amplitude Response (dB)')\n"
+ "grid on\n"
+ "disp('Hit return to continue')\n"
+ "pause\n"
+ , effp->in_signal.rate / 2, f->freq0, f->freq1);
+ return SOX_EOF;
+ }
f->X = lsx_malloc(sizeof(double) * (2*BUFFSIZE + 2*Xh));
f->Y = f->X + BUFFSIZE + 2*Xh;