ref: 444f41c6fcdf4142c6bca1c6c76df2e4603a24a8
parent: 65f0f47558b878892b5e2b8b77bc3c4f958abbe0
author: robs <robs>
date: Sun Apr 29 13:21:04 EDT 2007
Added gnuplot plotting
--- a/AUTHORS
+++ b/AUTHORS
@@ -92,7 +92,8 @@
Formats: M3U, PLS, FLAC, AMR-WB, 24bit support for popular
formats.
Effects: pad, bass, treble, new flanger, soft-knee companding,
- speed via resampling, filters makeover inc. octave plots.
+ speed via resampling, filters makeover inc. gnuplot & octave
+ plotting.
Others: open input files via URL, file merging, play
multiple files with mixed format types, play with replay-gain,
much manual improvement and expansion, various fixes,
--- a/ChangeLog
+++ b/ChangeLog
@@ -22,10 +22,13 @@
Effects:
+ o --octave option changed to --plot; can now also use gnuplot to
+ plot effect transfer function. (robs)
o Added soft-knee companding. (robs)
- o Show (with --octave) compand transfer function. (robs)
+ o Show (with --plot) compand transfer function. (robs)
o Allow e.g. "vol 6dB" (as well as "vol 6 dB"). (robs)
- o Changed deemph to be a true biquad for better accuracy. (robs)
+ o Changed deemph filter from 1st order to 2nd order for
+ better accuracy. (robs)
o Add option to silence effect to leave periods of silence
in and only strip out extra silence. (Mark Schreiber)
--- a/sox.1
+++ b/sox.1
@@ -480,15 +480,19 @@
See \fBInput File Combining\fR above for a description of the different
combining methods.
.TP
-\fB\-\-octave\fR
-Run in a mode that can be used, in conjunction with the GNU
-Octave program, to assist with the selection and configuration
-of many of the filtering effects. For the first given effect
-that supports the \fB\-\-octave\fR option, SoX will output Octave
-commands to plot the effect's transfer function, and then exit
-without actually processing any audio. E.g.
+\fB\-\-plot gnuplot\fR\^|\^\fBoctave\fR\^|\^\fBoff\fR
+If not set to
+.B off
+(the default if
+.B \-\-plot
+is not given), run in a mode that can be used, in conjunction with the
+gnuplot program or the GNU Octave program, to assist with the selection
+and configuration of many of the transfer-function based effects.
+For the first given effect that supports the selected plotting program,
+SoX will output commands to plot the effect's transfer function, and
+then exit without actually processing any audio. E.g.
.EX
- sox --octave input-file -n highpass 1320 > plot.m
+ sox --plot octave input-file -n highpass 1320 > plot.m
octave plot.m
.EE
.TP
@@ -495,16 +499,8 @@
\fB\-q\fR, \fB\-\-no\-show\-progress\fR
Run in quiet mode when SoX wouldn't otherwise do so;
this is the opposite of the \fB\-S\fR option.
-.PP
-\fB\-\-replay\-gain track\fR
-.br
-\fB\-\-replay\-gain album\fR
-.br
-\fB\-\-replay\-gain off\fR
-.if t .sp -.5
-.if n .sp -1
.TP
-\
+\fB\-\-replay\-gain track\fR\^|\^\fBalbum\fR\^|\^\fBoff\fR
Select whether or not to apply replay-gain adjustment to input files.
The default is
.B track
@@ -1245,7 +1241,7 @@
audio's frequency to phase relationship without changing its frequency
to amplitude relationship. The filter is described in detail in [1].
.SP
-This effect supports the \fB\-\-octave\fR global option.
+This effect supports the \fB\-\-plot\fR global option.
.TP
\fBband\fR [\fB\-n\fR] \fIcenter\fR [width\fR[\fBh\fR\^|\^\fBo\fR\^|\^\fBq\fR]]
Apply a band-pass filter.
@@ -1281,7 +1277,7 @@
.I center
frequency and settling around it.
.SP
-This effect supports the \fB\-\-octave\fR global option.
+This effect supports the \fB\-\-plot\fR global option.
.SP
See also \fBfilter\fR for a bandpass filter with steeper shoulders.
.TP
@@ -1299,7 +1295,7 @@
The filters roll off at 6dB per octave (20dB per decade)
and are described in detail in [1].
.SP
-These effects support the \fB\-\-octave\fR global option.
+These effects support the \fB\-\-plot\fR global option.
.SP
See also \fBfilter\fR for a bandpass filter with steeper shoulders.
.TP
@@ -1342,7 +1338,7 @@
.SP
The filters are described in detail in [1].
.SP
-These effects support the \fB\-\-octave\fR global option.
+These effects support the \fB\-\-plot\fR global option.
.SP
See also \fBequalizer\fR for a peaking equalisation effect.
.TP
@@ -1391,7 +1387,7 @@
allows the compander to effectively operate in a `predictive' rather than a
reactive mode.
.SP
-This effect supports the \fB\-\-octave\fR global option (for the transfer function).
+This effect supports the \fB\-\-plot\fR global option (for the transfer function).
.SP
See also
.B mcompand
@@ -1417,7 +1413,7 @@
recordings is rectified. The filter is defined in the
standard document ISO 908.
.SP
-This effect supports the \fB\-\-octave\fR global option.
+This effect supports the \fB\-\-plot\fR global option.
.SP
See also the \fBbass\fR and \fBtreble\fR shelving equalisation effects.
.TP
@@ -1481,7 +1477,7 @@
.SP
The filter is described in detail in [1].
.SP
-This effect supports the \fB\-\-octave\fR global option.
+This effect supports the \fB\-\-plot\fR global option.
.SP
See also \fBbass\fR and \fBtreble\fR for shelving equalisation effects.
.TP
@@ -1575,7 +1571,7 @@
roll off at 6dB per pole per octave (20dB per pole per decade). The
double-pole filters are described in detail in [1].
.SP
-These effects support the \fB\-\-octave\fR global option.
+These effects support the \fB\-\-plot\fR global option.
.SP
See also \fBfilter\fR for filters with a steeper roll-off.
.TP
@@ -2296,8 +2292,10 @@
Please report any bugs found in this version of SoX to the mailing list
(sox-users@lists.sourceforge.net).
.SH SEE ALSO
-.BR soxexam (7),
+.BR gnuplot (1),
.BR libsox (3),
+.BR octave (1),
+.BR soxexam (7),
.BR wget (1)
.SP
The SoX web page at http://sox.sourceforge.net
--- a/src/biquad.c
+++ b/src/biquad.c
@@ -66,8 +66,9 @@
p->a2 = p->a2/p->a0;
p->a1 = p->a1/p->a0;
- if (effp->globalinfo->octave_plot_effect) {
+ if (effp->globalinfo->plot == sox_plot_octave) {
printf(
+ "%% GNU Octave file (may also work with MATLAB(R) )\n"
"title('SoX effect: %s gain=%g frequency=%g %s=%g (rate=%u)')\n"
"xlabel('Frequency (Hz)')\n"
"ylabel('Amplitude Response (dB)')\n"
@@ -76,8 +77,30 @@
"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),'b')\n"
+ "semilogx(w,20*log10(h))\n"
+ "disp('Hit return to continue')\n"
"pause\n"
+ , effp->name, p->gain, p->fc, width_str[p->width_type], p->width
+ , effp->ininfo.rate, effp->ininfo.rate
+ , p->b0, p->b1, p->b2, p->a1, p->a2
+ );
+ return SOX_EOF;
+ }
+ if (effp->globalinfo->plot == sox_plot_gnuplot) {
+ printf(
+ "# gnuplot file\n"
+ "set title 'SoX effect: %s gain=%g frequency=%g %s=%g (rate=%u)'\n"
+ "set xlabel 'Frequency (Hz)'\n"
+ "set ylabel 'Amplitude Response (dB)'\n"
+ "Fs=%u.\n"
+ "b0=%g; b1=%g; b2=%g; a1=%g; a2=%g\n"
+ "o=2*pi/Fs\n"
+ "H(f)=sqrt((b0*b0+b1*b1+b2*b2+2.*(b0*b1+b1*b2)*cos(f*o)+2.*(b0*b2)*cos(2.*f*o))/(1.+a1*a1+a2*a2+2.*(a1+a1*a2)*cos(f*o)+2.*a2*cos(2.*f*o)))\n"
+ "set logscale x\n"
+ "set grid xtics ytics\n"
+ "set key off\n"
+ "plot [f=10:Fs/2] [-35:25] 20*log10(H(f))\n"
+ "pause -1 'Hit return to continue'\n"
, effp->name, p->gain, p->fc, width_str[p->width_type], p->width
, effp->ininfo.rate, effp->ininfo.rate
, p->b0, p->b1, p->b2, p->a1, p->a2
--- a/src/compand.c
+++ b/src/compand.c
@@ -137,7 +137,7 @@
for (i = 0; i < l->expectedChannels; ++i)
sox_debug("Channel %i: attack = %g decay = %g", i,
l->channels[i].attack_times[0], l->channels[i].attack_times[1]);
- if (!sox_compandt_show(&l->transfer_fn, effp->globalinfo->octave_plot_effect))
+ if (!sox_compandt_show(&l->transfer_fn, effp->globalinfo->plot))
return SOX_EOF;
/* Convert attack and decay rates using number of samples */
--- a/src/compandt.c
+++ b/src/compandt.c
@@ -21,7 +21,7 @@
#define LOG_TO_LOG10(x) ((x) * 20 / log(10.))
-sox_bool sox_compandt_show(sox_compandt_t * t, sox_bool plot)
+sox_bool sox_compandt_show(sox_compandt_t * t, sox_plot_t plot)
{
int i;
@@ -32,27 +32,47 @@
LOG_TO_LOG10(t->segments[i].a),
LOG_TO_LOG10(t->segments[i].b));
- if (!plot)
- return sox_true;
- printf(
- "title('SoX effect: compand')\n"
- "xlabel('Input level (dB)')\n"
- "ylabel('Output level (dB)')\n"
- "%%axis([-100 0 -100 0])\n"
- "in=linspace(-99.5,0,200);\n"
- "grid on\n"
- "out=[");
- for (i = -199; i <= 0; ++i) {
- double in = i/2.;
- double in_lin = pow(10., in/20);
- printf("%g ", in + 20 * log10(sox_compandt(t, in_lin)));
+ 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.;
+ double in_lin = pow(10., in/20);
+ printf("%g ", in + 20 * log10(sox_compandt(t, in_lin)));
+ }
+ printf(
+ "];\n"
+ "%%plot(in,out) %% hmm.. doesn't work :(\n"
+ "semilogx(exp(in),out)\n"
+ "pause\n");
+ return sox_false;
}
- printf(
- "];\n"
- "%%plot(in,out,'b') %% hmm.. doesn't work :(\n"
- "semilogx(exp(in),out,'b')\n"
- "pause\n");
- return sox_false;
+ if (plot == sox_plot_gnuplot) {
+ printf(
+ "# gnuplot file\n"
+ "set title 'SoX effect: compand'\n"
+ "set xlabel 'Input level (dB)'\n"
+ "set ylabel 'Output level (dB)'\n"
+ "set grid xtics ytics\n"
+ "set key off\n"
+ "plot '-' with lines\n");
+ for (i = -199; i <= 0; ++i) {
+ double in = i/2.;
+ double in_lin = pow(10., in/20);
+ printf("%g %g\n", in, in + 20 * log10(sox_compandt(t, in_lin)));
+ }
+ printf(
+ "e\n"
+ "pause -1 'Hit return to continue'\n");
+ return sox_false;
+ }
+ return sox_true;
}
static void prepare_transfer_fn(sox_compandt_t * t)
--- a/src/compandt.h
+++ b/src/compandt.h
@@ -31,7 +31,7 @@
} sox_compandt_t;
sox_bool sox_compandt_parse(sox_compandt_t * t, char * points, char * gain);
-sox_bool sox_compandt_show(sox_compandt_t * t, sox_bool plot);
+sox_bool sox_compandt_show(sox_compandt_t * t, sox_plot_t plot);
void sox_compandt_kill(sox_compandt_t * p);
/* Place in header to allow in-lining */
--- a/src/sox.c
+++ b/src/sox.c
@@ -662,7 +662,7 @@
{"endian" , required_argument, NULL, 0},
{"interactive" , no_argument, NULL, 0},
{"help-effect" , required_argument, NULL, 0},
- {"octave" , no_argument, NULL, 0},
+ {"plot" , required_argument, NULL, 0},
{"replay-gain" , required_argument, NULL, 0},
{"version" , no_argument, NULL, 0},
@@ -700,6 +700,12 @@
ENUM_ITEM(ENDIAN_,swap)
{0, 0}};
+static enum_item const plot_methods[] = {
+ ENUM_ITEM(sox_plot_,off)
+ ENUM_ITEM(sox_plot_,octave)
+ ENUM_ITEM(sox_plot_,gnuplot)
+ {0, 0}};
+
static int enum_option(int option_index, enum_item const * items)
{
enum_item const * p = find_enum_text(optarg, items);
@@ -797,7 +803,7 @@
break;
case 7:
- globalinfo.octave_plot_effect = sox_true;
+ globalinfo.plot = enum_option(option_index, plot_methods);
break;
case 8:
--- a/src/sox.h
+++ b/src/sox.h
@@ -185,12 +185,14 @@
SOX_ENCODINGS /* End of list marker */
} sox_encoding_t;
-/* Global parameters */
+typedef enum {sox_plot_off, sox_plot_octave, sox_plot_gnuplot} sox_plot_t;
+/* Global parameters (for effects) */
+
typedef struct sox_globalinfo
{
- sox_bool octave_plot_effect;/* To help user choose effect & options */
- double speed; /* Gather up all speed changes here, then resample */
+ sox_plot_t plot; /* To help the user choose effect & options */
+ double speed; /* Gather up all speed changes here, then resample */
} sox_globalinfo_t;
typedef enum {SOX_OPTION_NO, SOX_OPTION_YES, SOX_OPTION_DEFAULT} sox_option_t;