ref: a47bf7b62b44263a454c9c3f112dbf0d7b930bc1
parent: 21fd3cdec88d01cdbfbde2316e88fb2406f9abb6
author: robs <robs>
date: Sun Mar 11 03:50:58 EDT 2007
Added M3U and internet support.
--- a/AUTHORS
+++ b/AUTHORS
@@ -88,9 +88,10 @@
Build system makeover, Lua scripting, Secret Rabbit
Code resampling, much cleanup.
Rob Sykes [email protected]
- Bass & treble effects, FLAC & AMR-WB formats, initial 24bit
- support, filters makeover inc. octave plots, new flanger,
- file merging, speed via resampling, soft-knee companding,
- pad effect, various fixes, enhancements and clean-ups,
- much manual improvement and expansion, play multiple
- files with mixed format types.
+ Formats: M3U, 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.
+ Others: open input files via URL, file merging, play
+ multiple files with mixed format types, much manual
+ improvement and expansion, various fixes, enhancements
+ and clean-ups.
--- a/ChangeLog
+++ b/ChangeLog
@@ -11,8 +11,8 @@
o Added support for ADPCM-encoded PRC files, based on Danny Smith's
rec2wav and sndcmp.
-
o Added AMR-WB format. (robs)
+ o Added M3U playlist format [FR# 1667341]. (robs)
Effects:
@@ -23,6 +23,7 @@
Other new features:
o Show (with -S) if clipping is occurring. (robs)
+ o Added internet input file support (needs wget). (robs)
Bug fixes:
@@ -38,6 +39,7 @@
duplications with other existing libst libraries. (Rueben)
o Renamed libst-config to more standard sox-config. (cbagwell)
o Removed library information from sox-config --cflags. (cbagwell)
+ o Got rid of several hundred compiler warnings. (robs)
sox-13.0.0
----------
--- a/sox.1
+++ b/sox.1
@@ -375,6 +375,18 @@
differently: pressing it once causes SoX to skip to the next file;
pressing it twice in quick succession causes SoX to exit.
.SH FILENAMES
+Filenames can be simple file names, absolute or relative path names,
+or URLs (inut files only). Note that URL support requires that
+.BR wget (1)
+is available.
+.SP
+Note:
+Giving SoX an input or output filename that is the same as a SoX
+effect-name will not work since SoX will treat it as an effect
+specification. The only work-around to this is to avoid such
+filenames; however, this is generally not difficult since most audio
+filenames have a filename `extension', whilst effect-names do not.
+.SP
The following `special' filenames may be used in certain circumstances
in place of a normal filename on the command line:
.TP
@@ -425,13 +437,6 @@
This is an alias of
.B \-n
and is retained for backwards compatibility only.
-.PP
-.B N.B.
-Giving SoX an input or output filename that is the same as a SoX
-effect-name will not work since SoX will treat it as an effect
-specification. The only work-around to this is to avoid such
-filenames; however, this is generally not difficult since most audio
-filenames have a filename `extension', whilst effect-names do not.
.SH OPTIONS
.SS Global Options
These options can be specified on the command line at any point
@@ -955,6 +960,12 @@
\&\fB.mat\fR, \fB.mat4\fR, \fB.mat5\fR \fB(libsndfile)\fR
Matlab 4.2/5.0 (respectively GNU Octave 2.0/2.1) format (.mat is the same as .mat4).
.TP
+.B .m3u
+A
+.I playlist
+format; contains a list of audio files.
+See [5] for details of this format.
+.TP
.B .maud
An IFF-conforming audio file type, registered by
MS MacroSystem Computer GmbH, published along
@@ -2229,7 +2240,8 @@
([email protected]).
.SH SEE ALSO
.BR soxexam (7),
-.BR libsox (3)
+.BR libsox (3),
+.BR wget (1)
.SP
The SoX web page at http://sox.sourceforge.net
.SS References
@@ -2253,6 +2265,11 @@
Wikipedia,
.IR "Decibel" ,
http://en.wikipedia.org/wiki/Decibel
+.TP
+[5]
+Wikipedia,
+.IR "M3U" ,
+http://en.wikipedia.org/wiki/M3U
.SH LICENSE
Copyright 1991 Lance Norskog and Sundry Contributors.
Copyright 1998\-2007 by Chris Bagwell and SoX Contributors.
--- a/src/sox.c
+++ b/src/sox.c
@@ -30,6 +30,7 @@
#include <signal.h>
#include <sys/time.h>
#include <time.h>
+#include <ctype.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for unlink() */
@@ -266,6 +267,99 @@
}
}
+static sox_bool is_playlist(char const * filename)
+{
+ size_t i = strlen(filename);
+ return i >= sizeof(".m3u") - 1 &&
+ strcasecmp(filename + i - (sizeof(".m3u") - 1), ".m3u") == 0;
+}
+
+static void parse_playlist(const file_t f0, char const * const filename)
+{
+ size_t text_length = 100;
+ char * text = xmalloc(text_length + 1);
+ char * dirname = xstrdup(filename);
+#if defined(DOS) || defined(WIN32)
+ char * slash_pos = max(strrchr(dirname, '/'), strrchr(dirname, '\\'));
+#else
+ char * slash_pos = strrchr(dirname, '/');
+#endif
+ FILE * file = xfopen(filename, "r");
+ int c;
+
+ if (!slash_pos)
+ *dirname = '\0';
+ else
+ *slash_pos = '\0';
+
+ if (file == NULL) {
+ sox_fail("Can't open playlist file `%s': %s", filename, strerror(errno));
+ exit(1);
+ }
+
+ do {
+ size_t i = 0;
+ char * last = NULL;
+
+ while (isspace(c = getc(file)));
+ if (c == EOF)
+ break;
+ while (c != EOF && !strchr("#\r\n", c)) {
+ if (i == text_length)
+ text = xrealloc(text, (text_length <<= 1) + 1);
+ text[i] = c;
+ if (!strchr(" \t\f", c))
+ last = text + i;
+ ++i;
+ c = getc(file);
+ }
+ if (ferror(file))
+ break;
+ if (c == '#') {
+ do c = getc(file);
+ while (c != EOF && !strchr("\r\n", c));
+ if (ferror(file))
+ break;
+ }
+ if (last) {
+ file_t f;
+
+ if (file_count >= MAX_FILES) {
+ sox_fail("Too many filenames; maximum is %d input files and 1 output file", MAX_INPUT_FILES);
+ exit(1);
+ }
+
+ last[1] = '\0';
+ f = new_file();
+ *f = *f0;
+ if (!dirname[0] || is_uri(text)
+#if defined(DOS) || defined(WIN32)
+ || text[0] == '\\' || text[1] == ':'
+#endif
+ || text[0] == '/')
+ f->filename = xstrdup(text);
+ else {
+ f->filename = xmalloc(strlen(dirname) + strlen(text) + 2);
+ sprintf(f->filename, "%s/%s", dirname, text);
+ }
+ if (is_playlist(f->filename)) {
+ parse_playlist(f, f->filename);
+ free(f->filename);
+ free(f);
+ continue;
+ }
+ files[file_count++] = f;
+ }
+ } while (c != EOF);
+ if (ferror(file)) {
+ sox_fail("Error reading playlist file `%s': %s", filename, strerror(errno));
+ exit(1);
+ }
+ fclose(file);
+ free(text);
+ free(dirname);
+}
+
static void parse_options_and_filenames(int argc, char **argv)
{
file_t f = NULL;
@@ -288,6 +382,12 @@
} else {
if (optind >= argc || is_effect_name(argv[optind]))
break;
+ if (is_playlist(argv[optind])) {
+ parse_playlist(f, argv[optind++]);
+ free(f);
+ f = NULL;
+ continue;
+ }
f->filename = xstrdup(argv[optind++]);
}
files[file_count++] = f;
@@ -364,6 +464,7 @@
usage("-v can only be given for an input file;\n"
"\tuse 'vol' to set the output file volume");
+ signal(SIGINT, SIG_IGN); /* So child pipes aren't killed by track skip */
for (i = 0; i < input_count; i++) {
int j = input_count - 1 - i; /* Open in reverse order 'cos of rec (below) */
file_t f = files[j];
@@ -396,6 +497,7 @@
if (files[j]->desc->comment)
set_replay_gain(files[j]->desc->comment, f);
}
+ signal(SIGINT, SIG_DFL);
/* Loop through the rest of the arguments looking for effects */
parse_effects(argc, argv);
@@ -1761,6 +1863,7 @@
while (*names++)
formats++;
}
+ ++formats;
format_list = (const char **)xmalloc(formats * sizeof(char *));
for (i = 0, formats = 0; sox_format_fns[i]; i++) {
char const * const *names = sox_format_fns[i]()->names;
@@ -1767,6 +1870,7 @@
while (*names)
format_list[formats++] = *names++;
}
+ format_list[formats++] = "m3u";
qsort(format_list, formats, sizeof(char *), strcmp_p);
for (i = 0; i < formats; i++)
printf(" %s", format_list[i]);
--- a/src/sox_i.h
+++ b/src/sox_i.h
@@ -149,6 +149,8 @@
extern sox_output_message_handler_t sox_output_message_handler;
extern int sox_output_verbosity_level;
void sox_output_message(FILE *file, const char *filename, const char *fmt, va_list ap);
+sox_bool is_uri(char const * text);
+FILE * xfopen(char const * identifier, char const * mode);
void sox_fail(const char *, ...);
void sox_warn(const char *, ...);
--- a/src/soxio.c
+++ b/src/soxio.c
@@ -124,7 +124,7 @@
SET_BINARY_MODE(stdin);
ft->fp = stdin;
}
- else if ((ft->fp = fopen(ft->filename, "rb")) == NULL)
+ else if ((ft->fp = xfopen(ft->filename, "rb")) == NULL)
{
sox_warn("Can't open input file `%s': %s", ft->filename,
strerror(errno));
--- a/src/util.c
+++ b/src/util.c
@@ -20,6 +20,9 @@
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
+#ifdef _MSC_VER
+#define popen _popen
+#endif
sox_output_message_handler_t sox_output_message_handler = NULL;
int sox_output_verbosity_level = 2;
@@ -361,3 +364,30 @@
}
return NULL;
}
+
+sox_bool is_uri(char const * text)
+{
+ if (!isalpha(*text))
+ return sox_false;
+ ++text;
+ do {
+ if (!isalnum(*text) && !strchr("+-.", *text))
+ return sox_false;
+ ++text;
+ } while (*text && *text != ':');
+ return *text == ':';
+}
+
+FILE * xfopen(char const * identifier, char const * mode)
+{
+ if (is_uri(identifier)) {
+ FILE * f;
+ char const * const command_format = "wget -q -O- \"%s\"";
+ char * command = xmalloc(strlen(command_format) + strlen(identifier));
+ sprintf(command, command_format, identifier);
+ f = popen(command, "r");
+ free(command);
+ return f;
+ }
+ return fopen(identifier, mode);
+}