ref: f37f0c8758b985ad853a3d7b06176a3bd76982e7
parent: 5c55ce9fdcbec4b08785337edea5a941d72b0c1b
author: cbagwell <cbagwell>
date: Sun Jan 23 20:13:00 EST 2005
Add RIFX support to WAV. Auto-detect DEC-style .sd headers.
--- a/Changelog
+++ b/Changelog
@@ -7,6 +7,10 @@
sox-12.17.8
-----------
o noisered effect had compile problems with some compilers.
+ o "-x" option was being ignored since 12.17.7.
+ o Stuart Brady added support for reading and writing RIFX files (big
+ endian RIFF/WAV files). Also added support for auto detecting
+ DEC-style ".sd\0" files.
sox-12.17.7
-----------
--- a/sox.1
+++ b/sox.1
@@ -625,6 +625,7 @@
(Obviously, Windows was of such incredible importance
to the computer industry that it just had to have its own
sound file format.)
+.br
Normally \fB.wav\fR files have all formatting information
in their headers, and so do not need any format options
specified for an input file. If any are, they will
@@ -632,10 +633,13 @@
You had better know what you are doing! Output format
options will cause a format conversion, and the \fB.wav\fR
will written appropriately.
+.br
SoX currently can read PCM, ULAW, ALAW, MS ADPCM, and IMA (or DVI) ADPCM.
-It can write all of these formats including
-.B (NEW!)
-the ADPCM encoding.
+It can write all of these formats including the ADPCM encoding.
+Big endian versions of RIFF files, called RIFX, can also be read
+and written. To write a RIFX file, use the
+.I -x
+option with the output file options.
.TP 10
.B .wve
Psion 8-bit A-law
--- a/src/auto.c
+++ b/src/auto.c
@@ -45,8 +45,11 @@
{
/* Look for .snd or dns. header of AU files */
if ((strncmp(header, ".snd", 4) == 0) ||
- (strncmp(header, "dns.", 4) == 0) ||
- ((header[0] == '\0') && (strncmp(header+1, "ds.", 3) == 0)))
+ (strncmp(header, "dns.", 4) == 0) ||
+ ((header[0] == '\0') &&
+ (strncmp(header+1, "ds.", 3) == 0)) ||
+ ((strncmp(header, "sd.", 3) == 0) &&
+ (header[3] == '\0')))
{
type = "au";
}
--- a/src/sox.c
+++ b/src/sox.c
@@ -291,6 +291,7 @@
file_desc[offset]->filetype = "auto";
else
file_desc[offset]->filetype = strdup(file_opts[offset]->filetype);
+ file_desc[offset]->swap = file_opts[offset]->swap;
if (st_gettype(file_desc[offset]))
st_fail("Unknown input file format for '%s': %s",
@@ -330,7 +331,8 @@
file_desc[offset]->info = file_opts[offset]->info;
file_desc[offset]->filename = file_opts[offset]->filename;
file_desc[offset]->filetype = file_opts[offset]->filetype;
-
+ file_desc[offset]->swap = file_opts[offset]->swap;
+
if (writing && !file_desc[offset]->filetype) {
/* Use filename extension to determine audio type. */
--- a/src/wav.c
+++ b/src/wav.c
@@ -457,12 +457,20 @@
if (ST_IS_BIGENDIAN) ft->swap = ft->swap ? 0 : 1;
- if (st_reads(ft, magic, 4) == ST_EOF || strncmp("RIFF", magic, 4))
+ if (st_reads(ft, magic, 4) == ST_EOF || (strncmp("RIFF", magic, 4) != 0 &&
+ strncmp("RIFX", magic, 4) != 0))
{
st_fail_errno(ft,ST_EHDR,"WAVE: RIFF header not found");
return ST_EOF;
}
+ /* RIFX is a Big-endian RIFF */
+ if (strncmp("RIFX", magic, 4) == 0)
+ {
+ st_report("Found RIFX header, swapping bytes");
+ ft->swap = ft->swap ? 0 : 1;
+ }
+
st_readdw(ft, &dwRiffLength);
if (st_reads(ft, magic, 4) == ST_EOF || strncmp("WAVE", magic, 4))
@@ -1174,39 +1182,40 @@
int st_wavstartwrite(ft_t ft)
{
- wav_t wav = (wav_t) ft->priv;
- int rc;
+ wav_t wav = (wav_t) ft->priv;
+ int rc;
- ft->st_errno = ST_SUCCESS;
+ ft->st_errno = ST_SUCCESS;
- if (ST_IS_BIGENDIAN) ft->swap = ft->swap ? 0 : 1;
+ if (ST_IS_BIGENDIAN) ft->swap = ft->swap ? 0 : 1;
- /* FIXME: This reserves memory but things could fail
- * later on and not release this memory.
- */
- if (ft->info.encoding != ST_ENCODING_ADPCM &&
- ft->info.encoding != ST_ENCODING_IMA_ADPCM &&
- ft->info.encoding != ST_ENCODING_GSM)
- {
- rc = st_rawstartwrite(ft);
- if (rc)
- return rc;
- }
-
- wav->numSamples = 0;
- wav->dataLength = 0;
- if (!ft->seekable)
- st_warn("Length in output .wav header will be wrong since can't seek to fix it");
- rc = wavwritehdr(ft, 0); /* also calculates various wav->* info */
- if (rc != 0)
+ /* FIXME: This reserves memory but things could fail
+ * later on and not release this memory.
+ */
+ if (ft->info.encoding != ST_ENCODING_ADPCM &&
+ ft->info.encoding != ST_ENCODING_IMA_ADPCM &&
+ ft->info.encoding != ST_ENCODING_GSM)
+ {
+ rc = st_rawstartwrite(ft);
+ if (rc)
return rc;
+ }
- wav->packet = NULL;
- wav->samples = NULL;
- wav->iCoefs = NULL;
- switch (wav->formatTag)
- {
+ wav->numSamples = 0;
+ wav->dataLength = 0;
+ if (!ft->seekable)
+ st_warn("Length in output .wav header will be wrong since can't seek to fix it");
+ rc = wavwritehdr(ft, 0); /* also calculates various wav->* info */
+ if (rc != 0)
+ return rc;
+
+ wav->packet = NULL;
+ wav->samples = NULL;
+ wav->iCoefs = NULL;
+ switch (wav->formatTag)
+ {
int ch, sbsize;
+
case WAVE_FORMAT_IMA_ADPCM:
initImaTable();
/* intentional case fallthru! */
@@ -1233,14 +1242,14 @@
#endif
default:
break;
- }
- return ST_SUCCESS;
+ }
+ return ST_SUCCESS;
}
/* wavwritehdr: write .wav headers as follows:
bytes variable description
-0 - 3 'RIFF'
+0 - 3 'RIFF'/'RIFX' Little/Big-endian
4 - 7 wRiffLength length of file minus the 8 byte riff header
8 - 11 'WAVE'
12 - 15 'fmt '
@@ -1492,7 +1501,20 @@
dwAvgBytesPerSec = (double)wBlockAlign*ft->info.rate / (double)wSamplesPerBlock + 0.5;
/* figured out header info, so write it */
- st_writes(ft, "RIFF");
+
+
+ /* If user specified opposite swap then we think, assume they are
+ * asking to write a RIFX file.
+ */
+ if ((!ST_IS_BIGENDIAN && ft->swap) ||
+ (ST_IS_BIGENDIAN && !ft->swap))
+ {
+ if (!second_header)
+ st_report("Requested to swap bytes so writing RIFX header");
+ st_writes(ft, "RIFX");
+ }
+ else
+ st_writes(ft, "RIFF");
st_writedw(ft, wRiffLength);
st_writes(ft, "WAVE");
st_writes(ft, "fmt ");