ref: 373c331aeb24401d81acb7afd0aecd3ba75da8d9
parent: f31b93dfccbc215a427c75c73b03128815e179cb
author: robs <robs>
date: Wed Jan 10 16:05:55 EST 2007
Nibble & bit ordering.
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -453,7 +453,7 @@
if (is_sowt)
{
aiff->nsamples -= 4;
- ft->signal.swap_bytes = !ft->signal.swap_bytes;
+ ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
}
if (foundmark && !foundinstr)
@@ -695,10 +695,9 @@
return rc;
aiff->nsamples = 0;
- if ((ft->signal.encoding == ST_ENCODING_ULAW ||
- ft->signal.encoding == ST_ENCODING_ALAW) &&
+ if (ft->signal.encoding < ST_ENCODING_SIZE_IS_WORD &&
ft->signal.size == ST_SIZE_BYTE) {
- st_report("expanding 8-bit u-law to signed 16 bits");
+ st_report("expanding compressed bytes to signed 16 bits");
ft->signal.encoding = ST_ENCODING_SIGN2;
ft->signal.size = ST_SIZE_WORD;
}
@@ -901,10 +900,9 @@
return rc;
aiff->nsamples = 0;
- if ((ft->signal.encoding == ST_ENCODING_ULAW ||
- ft->signal.encoding == ST_ENCODING_ALAW) &&
+ if (ft->signal.encoding < ST_ENCODING_SIZE_IS_WORD &&
ft->signal.size == ST_SIZE_BYTE) {
- st_report("expanding 8-bit u-law to signed 16 bits");
+ st_report("expanding compressed bytes to signed 16 bits");
ft->signal.encoding = ST_ENCODING_SIGN2;
ft->signal.size = ST_SIZE_WORD;
}
--- a/src/alsa.c
+++ b/src/alsa.c
@@ -381,7 +381,7 @@
}
else
{
- read_buf(buf+(len*sizeof(st_sample_t)), alsa->buf, err, ft->signal.swap_bytes, &ft->clippedCount);
+ read_buf(buf+(len*sizeof(st_sample_t)), alsa->buf, err, ft->signal.reverse_bytes, &ft->clippedCount);
len += err * ft->signal.channels;
}
}
@@ -486,7 +486,7 @@
st_size_t len;
osamp = min(nsamp - done, alsa->buf_size / ft->signal.size);
- write_buf(alsa->buf, buf, osamp, ft->signal.swap_bytes, &ft->clippedCount);
+ write_buf(alsa->buf, buf, osamp, ft->signal.reverse_bytes, &ft->clippedCount);
buf += osamp;
for (len = 0; len < osamp;) {
--- a/src/au.c
+++ b/src/au.c
@@ -164,11 +164,11 @@
* left over from pre-standardize period of testing for
* endianess. Its not hurting though.
*/
- ft->signal.swap_bytes = !ft->signal.swap_bytes;
+ ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
st_debug("Found inverted DEC magic word. Swapping bytes.");
}
else if (magic == SUN_INV_MAGIC) {
- ft->signal.swap_bytes = !ft->signal.swap_bytes;
+ ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
st_debug("Found inverted Sun/NeXT magic word. Swapping bytes.");
}
else if (magic == SUN_MAGIC) {
--- a/src/auto.c
+++ b/src/auto.c
@@ -176,7 +176,7 @@
}
st_debug("Detected file format type: %s", type);
- set_swap_if_not_already_set(ft);
+ set_endianness_if_not_already_set(ft);
return (* ft->h->startread)(ft);
}
--- a/src/cvsd.c
+++ b/src/cvsd.c
@@ -84,7 +84,6 @@
} bit;
unsigned bytes_written;
unsigned cvsd_rate;
- char swapbits;
};
static int debug_count = 0;
@@ -120,7 +119,6 @@
ft->signal.channels = 1;
ft->signal.size = ST_SIZE_WORD; /* make output format default to words */
ft->signal.encoding = ST_ENCODING_SIGN2;
- p->swapbits = ft->signal.reverse_bits;
/*
* initialize the decoder
*/
@@ -139,7 +137,7 @@
* initialize bit shift register
*/
p->bit.shreg = p->bit.cnt = 0;
- p->bit.mask = p->swapbits ? 0x80 : 1;
+ p->bit.mask = 1;
/*
* count the bytes written
*/
@@ -147,7 +145,7 @@
p->com.v_min = 1;
p->com.v_max = -1;
st_report("cvsd: bit rate %dbit/s, bits from %s", p->cvsd_rate,
- p->swapbits ? "msb to lsb" : "lsb to msb");
+ ft->signal.reverse_bits ? "msb to lsb" : "lsb to msb");
}
/* ---------------------------------------------------------------------- */
@@ -239,7 +237,7 @@
if (st_readb(ft, &(p->bit.shreg)) == ST_EOF)
return done;
p->bit.cnt = 8;
- p->bit.mask = p->swapbits ? 0x80 : 1;
+ p->bit.mask = 1;
}
/*
* handle one bit
@@ -247,10 +245,7 @@
p->bit.cnt--;
p->com.overload = ((p->com.overload << 1) |
(!!(p->bit.shreg & p->bit.mask))) & 7;
- if (p->swapbits)
- p->bit.mask >>= 1;
- else
- p->bit.mask <<= 1;
+ p->bit.mask <<= 1;
p->com.mla_int *= p->com.mla_tc0;
if ((p->com.overload == 0) || (p->com.overload == 7))
p->com.mla_int += p->com.mla_tc1;
@@ -334,13 +329,9 @@
st_writeb(ft, p->bit.shreg);
p->bytes_written++;
p->bit.shreg = p->bit.cnt = 0;
- p->bit.mask = p->swapbits ? 0x80 : 1;
- } else {
- if (p->swapbits)
- p->bit.mask >>= 1;
- else
- p->bit.mask <<= 1;
- }
+ p->bit.mask = 1;
+ } else
+ p->bit.mask <<= 1;
p->com.phase += p->com.phase_inc;
st_debug_more("input %d %f\n", debug_count, inval);
st_debug_more("recon %d %f\n", debug_count, p->c.enc.recon_int);
@@ -489,7 +480,6 @@
static int st_dvmsstartread(ft_t ft)
{
- struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
struct dvms_header hdr;
int rc;
@@ -520,7 +510,6 @@
if (rc)
return rc;
- p->swapbits = 0;
return(ST_SUCCESS);
}
@@ -528,7 +517,6 @@
static int st_dvmsstartwrite(ft_t ft)
{
- struct cvsdpriv *p = (struct cvsdpriv *) ft->priv;
struct dvms_header hdr;
int rc;
@@ -546,7 +534,6 @@
if (!ft->seekable)
st_warn("Length in output .DVMS header will wrong since can't seek to fix it");
- p->swapbits = 0;
return(ST_SUCCESS);
}
--- a/src/flac.c
+++ b/src/flac.c
@@ -330,10 +330,7 @@
}
/* FIXME: FLAC should not need to know about this oddity */
- if (format->signal.encoding == ST_ENCODING_ULAW ||
- format->signal.encoding == ST_ENCODING_ALAW ||
- format->signal.encoding == ST_ENCODING_INV_ULAW ||
- format->signal.encoding == ST_ENCODING_INV_ALAW)
+ if (format->signal.encoding < ST_ENCODING_SIZE_IS_WORD)
format->signal.size = ST_SIZE_WORD;
encoder->bits_per_sample = (format->signal.size > 4 ? 4 : format->signal.size) << 3;
--- a/src/misc.c
+++ b/src/misc.c
@@ -55,20 +55,23 @@
const char * const st_encodings_str[] = {
"NONSENSE!",
- "unsigned",
- "signed (2's complement)",
+
"u-law",
"a-law",
- "floating point",
- "ADPCM",
+ "G72x-ADPCM",
+ "MS-ADPCM",
"IMA-ADPCM",
+ "OKI-ADPCM",
+
+ "", /* FIXME, see st.h */
+
+ "unsigned",
+ "signed (2's complement)",
+ "floating point",
"GSM",
- "inversed u-law",
- "inversed A-law",
"MPEG audio (layer I, II or III)",
"Vorbis",
"FLAC",
- "OKI-ADPCM"
};
assert_static(array_length(st_encodings_str) == ST_ENCODINGS,
@@ -77,6 +80,32 @@
static const char readerr[] = "Premature EOF while reading sample file.";
static const char writerr[] = "Error writing sample file. You are probably out of disk space.";
+/* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
+static uint8_t const cswap[256] = {
+ 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
+ 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
+ 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
+ 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
+ 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
+ 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
+ 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
+ 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
+ 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
+ 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
+ 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
+ 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
+ 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
+ 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
+ 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
+ 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
+ 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
+ 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
+ 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
+ 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
+ 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
+ 0x3F, 0xBF, 0x7F, 0xFF
+};
+
/* Utilities */
/* Read in a buffer of data of length len and each element is size bytes.
@@ -201,23 +230,29 @@
/* Read byte. */
int st_readb(ft_t ft, uint8_t *ub)
{
- if (st_readbuf(ft, ub, 1, 1) != 1)
- {
- st_fail_errno(ft,errno,readerr);
- return(ST_EOF);
- }
- return ST_SUCCESS;
+ if (st_readbuf(ft, ub, 1, 1) != 1) {
+ st_fail_errno(ft,errno,readerr);
+ return ST_EOF;
+ }
+ if (ft->signal.reverse_bits)
+ *ub = cswap[*ub];
+ if (ft->signal.reverse_nibbles)
+ *ub = ((*ub & 15) << 4) | (*ub >> 4);
+ return ST_SUCCESS;
}
/* Write byte. */
int st_writeb(ft_t ft, uint8_t ub)
{
- if (st_writebuf(ft, &ub, 1, 1) != 1)
- {
- st_fail_errno(ft,errno,writerr);
- return(ST_EOF);
- }
- return(ST_SUCCESS);
+ if (ft->signal.reverse_nibbles)
+ ub = ((ub & 15) << 4) | (ub >> 4);
+ if (ft->signal.reverse_bits)
+ ub = cswap[ub];
+ if (st_writebuf(ft, &ub, 1, 1) != 1) {
+ st_fail_errno(ft,errno,writerr);
+ return ST_EOF;
+ }
+ return ST_SUCCESS;
}
/* Read word. */
@@ -228,7 +263,7 @@
st_fail_errno(ft,errno,readerr);
return (ST_EOF);
}
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
*uw = st_swapw(*uw);
return ST_SUCCESS;
}
@@ -236,7 +271,7 @@
/* Write word. */
int st_writew(ft_t ft, uint16_t uw)
{
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
uw = st_swapw(uw);
if (st_writebuf(ft, &uw, 2, 1) != 1)
{
@@ -254,7 +289,7 @@
st_fail_errno(ft,errno,readerr);
return (ST_EOF);
}
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
*u3 = st_swap24(*u3);
return ST_SUCCESS;
}
@@ -262,7 +297,7 @@
/* Write three bytes. */
int st_write3(ft_t ft, uint24_t u3)
{
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
u3 = st_swap24(u3);
if (st_writebuf(ft, &u3, 3, 1) != 1)
{
@@ -280,7 +315,7 @@
st_fail_errno(ft,errno,readerr);
return (ST_EOF);
}
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
*udw = st_swapdw(*udw);
return ST_SUCCESS;
}
@@ -288,7 +323,7 @@
/* Write double word. */
int st_writedw(ft_t ft, uint32_t udw)
{
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
udw = st_swapdw(udw);
if (st_writebuf(ft, &udw, 4, 1) != 1)
{
@@ -306,7 +341,7 @@
st_fail_errno(ft,errno,readerr);
return(ST_EOF);
}
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
*f = st_swapf(*f);
return ST_SUCCESS;
}
@@ -316,7 +351,7 @@
{
float t = f;
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
t = st_swapf(t);
if (st_writebuf(ft, &t, sizeof(float), 1) != 1)
{
@@ -334,7 +369,7 @@
st_fail_errno(ft,errno,readerr);
return(ST_EOF);
}
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
*d = st_swapd(*d);
return ST_SUCCESS;
}
@@ -342,7 +377,7 @@
/* Write double. */
int st_writedf(ft_t ft, double d)
{
- if (ft->signal.swap_bytes)
+ if (ft->signal.reverse_bytes)
d = st_swapd(d);
if (st_writebuf(ft, &d, sizeof(double), 1) != 1)
{
--- a/src/oss.c
+++ b/src/oss.c
@@ -132,7 +132,7 @@
}
if (samplesize == 16)
- ft->signal.swap_bytes = ST_IS_BIGENDIAN != (sampletype == AFMT_S16_BE);
+ ft->signal.reverse_bytes = ST_IS_BIGENDIAN != (sampletype == AFMT_S16_BE);
if (ft->signal.channels == 2) dsp_stereo = 1;
else dsp_stereo = 0;
--- a/src/raw.c
+++ b/src/raw.c
@@ -1,8 +1,6 @@
/*
- * Sound Tools raw format file.
+ * Sound Tools raw file formats
*
- * Includes .ub, .uw, .sb, .sw, and .ul formats at end
- *
* July 5, 1991
* Copyright 1991 Lance Norskog And Sundry Contributors
* This source code is freely redistributable and may be used for
@@ -11,12 +9,6 @@
* the consequences of using this software.
*/
-/*
- * Notes: most of the headerless formats set their handlers to raw
- * in their startread/write routines.
- *
- */
-
#include "st_i.h"
#include "g711.h"
@@ -24,49 +16,11 @@
#include <stdlib.h>
#include <errno.h>
-/* Lookup table to reverse the bit order of a byte. ie MSB become LSB */
-unsigned char cswap[256] = {
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0,
- 0x30, 0xB0, 0x70, 0xF0, 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
- 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8, 0x04, 0x84, 0x44, 0xC4,
- 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC,
- 0x3C, 0xBC, 0x7C, 0xFC, 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
- 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2, 0x0A, 0x8A, 0x4A, 0xCA,
- 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6,
- 0x36, 0xB6, 0x76, 0xF6, 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
- 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE, 0x01, 0x81, 0x41, 0xC1,
- 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9,
- 0x39, 0xB9, 0x79, 0xF9, 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
- 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5, 0x0D, 0x8D, 0x4D, 0xCD,
- 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3,
- 0x33, 0xB3, 0x73, 0xF3, 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
- 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB, 0x07, 0x87, 0x47, 0xC7,
- 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF,
- 0x3F, 0xBF, 0x7F, 0xFF
-};
-
#define ST_ULAW_BYTE_TO_SAMPLE(d,clips) ST_SIGNED_WORD_TO_SAMPLE(st_ulaw2linear16(d),clips)
#define ST_ALAW_BYTE_TO_SAMPLE(d,clips) ST_SIGNED_WORD_TO_SAMPLE(st_alaw2linear16(d),clips)
#define ST_SAMPLE_TO_ULAW_BYTE(d,c) st_14linear2ulaw(ST_SAMPLE_TO_SIGNED_WORD(d,c) >> 2)
#define ST_SAMPLE_TO_ALAW_BYTE(d,c) st_13linear2alaw(ST_SAMPLE_TO_SIGNED_WORD(d,c) >> 3)
-/* Some hardware sends MSB last. These account for that */
-#define ST_INVERT_ULAW_BYTE_TO_SAMPLE(d,clips) \
- ST_SIGNED_WORD_TO_SAMPLE(st_ulaw2linear16(cswap[d]),clips)
-#define ST_INVERT_ALAW_BYTE_TO_SAMPLE(d,clips) \
- ST_SIGNED_WORD_TO_SAMPLE(st_alaw2linear16(cswap[d]),clips)
-#define ST_SAMPLE_TO_INVERT_ULAW_BYTE(d,c) \
- cswap[st_14linear2ulaw(ST_SAMPLE_TO_SIGNED_WORD(d,c) >> 2)]
-#define ST_SAMPLE_TO_INVERT_ALAW_BYTE(d,c) \
- cswap[st_13linear2alaw(ST_SAMPLE_TO_SIGNED_WORD(d,c) >> 3)]
-
-static void rawdefaults(ft_t ft);
-
int st_rawseek(ft_t ft, st_size_t offset)
{
st_size_t new_offset, channel_block, alignment;
@@ -101,15 +55,48 @@
/* Works nicely for starting read and write; st_rawstart{read,write}
are #defined in st_i.h */
-int st_rawstart(ft_t ft)
+int st_rawstart(ft_t ft, bool default_rate, bool default_channels, st_encoding_t encoding, signed char size, st_reverse_t rev_bits)
{
- ft->eof = 0;
+ if (default_rate && ft->signal.rate == 0) {
+ st_warn("'%s': sample rate not specified; trying 8kHz", ft->filename);
+ ft->signal.rate = 8000;
+ }
- return ST_SUCCESS;
+ if (default_channels && ft->signal.channels == 0) {
+ st_warn("'%s': # channels not specified; trying mono", ft->filename);
+ ft->signal.channels = 1;
+ }
+
+ if (encoding != ST_ENCODING_UNKNOWN) {
+ if (ft->mode == 'r' &&
+ ft->signal.encoding != ST_ENCODING_UNKNOWN &&
+ ft->signal.encoding != encoding)
+ st_report("'%s': Format options overriding file-type encoding", ft->filename);
+ else ft->signal.encoding = encoding;
+ }
+
+ if (size != -1) {
+ if (ft->mode == 'r' &&
+ ft->signal.size != -1 && ft->signal.size != size)
+ st_report("'%s': Format options overriding file-type sample-size", ft->filename);
+ else ft->signal.size = size;
+ }
+
+ if (rev_bits != ST_REVERSE_DEFAULT) {
+ if (ft->mode == 'r' &&
+ ft->signal.reverse_bits != ST_REVERSE_DEFAULT &&
+ ft->signal.reverse_bits != rev_bits)
+ st_report("'%s': Format options overriding file-type bit-order", ft->filename);
+ else ft->signal.reverse_bits = rev_bits;
+ }
+
+ ft->eof = 0;
+ return ST_SUCCESS;
}
#define READ_FUNC(size, sign, ctype, uctype, cast) \
- static st_size_t st_ ## sign ## size ## _read_buf(st_sample_t *buf, ft_t ft, st_size_t len, st_size_t *clippedCount UNUSED) \
+ static st_size_t st_ ## sign ## size ## _read_buf( \
+ ft_t ft, st_sample_t *buf, st_size_t len) \
{ \
st_size_t n; \
for (n = 0; n < len; n++) { \
@@ -117,7 +104,7 @@
int ret = st_read ## size(ft, (uctype *)&datum); \
if (ret != ST_SUCCESS) \
break; \
- *buf++ = ST_ ## cast ## _TO_SAMPLE(datum, *clippedCount); \
+ *buf++ = ST_ ## cast ## _TO_SAMPLE(datum, ft->clippedCount); \
} \
return n; \
}
@@ -126,8 +113,6 @@
READ_FUNC(b, s, int8_t, uint8_t, SIGNED_BYTE)
READ_FUNC(b, ulaw, uint8_t, uint8_t, ULAW_BYTE)
READ_FUNC(b, alaw, uint8_t, uint8_t, ALAW_BYTE)
-READ_FUNC(b, inv_ulaw, uint8_t, uint8_t, INVERT_ULAW_BYTE)
-READ_FUNC(b, inv_alaw, uint8_t, uint8_t, INVERT_ALAW_BYTE)
READ_FUNC(w, u, uint16_t, uint16_t, UNSIGNED_WORD)
READ_FUNC(w, s, int16_t, uint16_t, SIGNED_WORD)
READ_FUNC(3, u, uint24_t, uint24_t, UNSIGNED_24BIT)
@@ -138,11 +123,12 @@
READ_FUNC(df, su, double, double, FLOAT_DDWORD)
#define WRITE_FUNC(size, sign, cast) \
- static st_size_t st_ ## sign ## size ## _write_buf(st_sample_t *buf, ft_t ft, st_size_t len, st_size_t *clippedCount UNUSED) \
+ static st_size_t st_ ## sign ## size ## _write_buf( \
+ ft_t ft, st_sample_t *buf, st_size_t len) \
{ \
st_size_t n; \
for (n = 0; n < len; n++) { \
- int ret = st_write ## size(ft, ST_SAMPLE_TO_ ## cast(*buf++, *clippedCount)); \
+ int ret = st_write ## size(ft, ST_SAMPLE_TO_ ## cast(*buf++, ft->clippedCount)); \
if (ret != ST_SUCCESS) \
break; \
} \
@@ -153,8 +139,6 @@
WRITE_FUNC(b, s, SIGNED_BYTE)
WRITE_FUNC(b, ulaw, ULAW_BYTE)
WRITE_FUNC(b, alaw, ALAW_BYTE)
-WRITE_FUNC(b, inv_ulaw, INVERT_ULAW_BYTE)
-WRITE_FUNC(b, inv_alaw, INVERT_ALAW_BYTE)
WRITE_FUNC(w, u, UNSIGNED_WORD)
WRITE_FUNC(w, s, SIGNED_WORD)
WRITE_FUNC(3, u, UNSIGNED_24BIT)
@@ -164,7 +148,7 @@
WRITE_FUNC(f, su, FLOAT_DWORD)
WRITE_FUNC(df, su, FLOAT_DDWORD)
-typedef st_size_t (ft_io_fun)(st_sample_t *buf, ft_t ft, st_size_t len, st_size_t *clippedCount);
+typedef st_size_t (ft_io_fun)(ft_t ft, st_sample_t *buf, st_size_t len);
static ft_io_fun *check_format(ft_t ft, bool write)
{
@@ -179,10 +163,6 @@
return write ? st_ulawb_write_buf : st_ulawb_read_buf;
case ST_ENCODING_ALAW:
return write ? st_alawb_write_buf : st_alawb_read_buf;
- case ST_ENCODING_INV_ULAW:
- return write ? st_inv_ulawb_write_buf : st_inv_ulawb_read_buf;
- case ST_ENCODING_INV_ALAW:
- return write ? st_inv_alawb_write_buf : st_inv_alawb_read_buf;
default:
break;
}
@@ -244,10 +224,10 @@
/* Read a stream of some type into SoX's internal buffer format. */
st_size_t st_rawread(ft_t ft, st_sample_t *buf, st_size_t nsamp)
{
- st_size_t (*read_buf)(st_sample_t *, ft_t, st_size_t, st_size_t *) = check_format(ft, false);
+ ft_io_fun * read_buf = check_format(ft, false);
if (read_buf && nsamp)
- return read_buf(buf, ft, nsamp, &ft->clippedCount);
+ return read_buf(ft, buf, nsamp);
return 0;
}
@@ -264,7 +244,7 @@
ft_io_fun *write_buf = check_format(ft, true);
if (write_buf && nsamp)
- return write_buf((st_sample_t *)buf, ft, nsamp, &ft->clippedCount);
+ return write_buf(ft, (st_sample_t *)buf, nsamp);
return 0;
}
@@ -275,389 +255,46 @@
return ST_SUCCESS;
}
-/*
-* Set parameters to the fixed parameters known for this format,
-* and change format to raw format.
-*/
-
-#define STARTREAD(NAME,SIZE,STYLE) \
-static int NAME(ft_t ft) \
-{ \
- ft->signal.size = SIZE; \
- ft->signal.encoding = STYLE; \
- rawdefaults(ft); \
- return st_rawstartread(ft); \
+static int raw_start(ft_t ft) {
+ return st_rawstart(ft,false,false,ST_ENCODING_UNKNOWN,-1,ST_REVERSE_DEFAULT);
}
-
-#define STARTWRITE(NAME,SIZE,STYLE)\
-static int NAME(ft_t ft) \
-{ \
- ft->signal.size = SIZE; \
- ft->signal.encoding = STYLE; \
- rawdefaults(ft); \
- return st_rawstartwrite(ft); \
+st_format_t const * st_raw_format_fn(void) {
+ static char const * names[] = {"raw", NULL};
+ static st_format_t driver = {
+ names, NULL, ST_FILE_STEREO | ST_FILE_SEEK,
+ raw_start, st_rawread , st_rawstopread,
+ raw_start, st_rawwrite, st_rawstopwrite,
+ st_rawseek
+ };
+ return &driver;
}
-STARTREAD(st_sbstartread,ST_SIZE_BYTE,ST_ENCODING_SIGN2)
-STARTWRITE(st_sbstartwrite,ST_SIZE_BYTE,ST_ENCODING_SIGN2)
-
-STARTREAD(st_ubstartread,ST_SIZE_BYTE,ST_ENCODING_UNSIGNED)
-STARTWRITE(st_ubstartwrite,ST_SIZE_BYTE,ST_ENCODING_UNSIGNED)
-
-STARTREAD(st_uwstartread,ST_SIZE_WORD,ST_ENCODING_UNSIGNED)
-STARTWRITE(st_uwstartwrite,ST_SIZE_WORD,ST_ENCODING_UNSIGNED)
-
-STARTREAD(st_swstartread,ST_SIZE_WORD,ST_ENCODING_SIGN2)
-STARTWRITE(st_swstartwrite,ST_SIZE_WORD,ST_ENCODING_SIGN2)
-
-STARTREAD(st_u3startread,ST_SIZE_24BIT,ST_ENCODING_UNSIGNED)
-STARTWRITE(st_u3startwrite,ST_SIZE_24BIT,ST_ENCODING_UNSIGNED)
-
-STARTREAD(st_s3startread,ST_SIZE_24BIT,ST_ENCODING_SIGN2)
-STARTWRITE(st_s3startwrite,ST_SIZE_24BIT,ST_ENCODING_SIGN2)
-
-STARTREAD(st_u4startread,ST_SIZE_DWORD,ST_ENCODING_UNSIGNED)
-STARTWRITE(st_u4startwrite,ST_SIZE_DWORD,ST_ENCODING_UNSIGNED)
-
-STARTREAD(st_slstartread,ST_SIZE_DWORD,ST_ENCODING_SIGN2)
-STARTWRITE(st_slstartwrite,ST_SIZE_DWORD,ST_ENCODING_SIGN2)
-
-STARTREAD(st_ulstartread,ST_SIZE_BYTE,ST_ENCODING_ULAW)
-STARTWRITE(st_ulstartwrite,ST_SIZE_BYTE,ST_ENCODING_ULAW)
-
-STARTREAD(st_alstartread,ST_SIZE_BYTE,ST_ENCODING_ALAW)
-STARTWRITE(st_alstartwrite,ST_SIZE_BYTE,ST_ENCODING_ALAW)
-
-STARTREAD(st_lustartread,ST_SIZE_BYTE,ST_ENCODING_INV_ULAW)
-STARTWRITE(st_lustartwrite,ST_SIZE_BYTE,ST_ENCODING_INV_ULAW)
-
-STARTREAD(st_lastartread,ST_SIZE_BYTE,ST_ENCODING_INV_ALAW)
-STARTWRITE(st_lastartwrite,ST_SIZE_BYTE,ST_ENCODING_INV_ALAW)
-
-void rawdefaults(ft_t ft)
-{
- if (ft->signal.rate == 0)
- ft->signal.rate = 8000;
- if (ft->signal.channels == 0)
- ft->signal.channels = 1;
+#define RAW_FORMAT(id,alt1,alt2,size,rev_bits,encoding) \
+static int id##_start(ft_t ft) { \
+ return st_rawstart(ft,true,true,ST_ENCODING_##encoding,ST_SIZE_##size,ST_REVERSE_##rev_bits); \
+} \
+st_format_t const * st_##id##_format_fn(void) { \
+ static char const * names[] = {#id, alt1, alt2, NULL}; \
+ static st_format_t driver = { \
+ names, NULL, ST_FILE_STEREO, \
+ id##_start, st_rawread , st_rawstopread, \
+ id##_start, st_rawwrite, st_rawstopwrite, \
+ st_format_nothing_seek \
+ }; \
+ return &driver; \
}
-static const char *rawnames[] = {
- "raw",
- NULL
-};
-
-static st_format_t st_raw_format = {
- rawnames,
- NULL,
- ST_FILE_STEREO | ST_FILE_SEEK,
- st_rawstartread,
- st_rawread,
- st_rawstopread,
- st_rawstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_rawseek
-};
-
-const st_format_t *st_raw_format_fn(void)
-{
- return &st_raw_format;
-}
-
-/* a-law byte raw */
-static const char *alnames[] = {
- "al",
- NULL
-};
-
-static st_format_t st_al_format = {
- alnames,
- NULL,
- ST_FILE_STEREO,
- st_alstartread,
- st_rawread,
- st_rawstopread,
- st_alstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_al_format_fn(void)
-{
- return &st_al_format;
-}
-
-/* inverse a-law byte raw */
-static const char *lanames[] = {
- "la",
- NULL
-};
-
-static st_format_t st_la_format = {
- lanames,
- NULL,
- ST_FILE_STEREO,
- st_lastartread,
- st_rawread,
- st_rawstopread,
- st_lastartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_la_format_fn(void)
-{
- return &st_la_format;
-}
-
-/* inverse u-law byte raw */
-static const char *lunames[] = {
- "lu",
- NULL
-};
-
-static st_format_t st_lu_format = {
- lunames,
- NULL,
- ST_FILE_STEREO,
- st_lustartread,
- st_rawread,
- st_rawstopread,
- st_lustartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_lu_format_fn(void)
-{
- return &st_lu_format;
-}
-
-static const char *sbnames[] = {
- "sb",
- NULL
-};
-
-static st_format_t st_sb_format = {
- sbnames,
- NULL,
- ST_FILE_STEREO,
- st_sbstartread,
- st_rawread,
- st_rawstopread,
- st_sbstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_sb_format_fn(void)
-{
- return &st_sb_format;
-}
-
-
-
-/* Unsigned 4 byte raw; used for testing only; not documented in the man page */
-
-static const char *u4names[] = {
- "u4",
- NULL,
-};
-
-static st_format_t st_u4_format = {
- u4names,
- NULL,
- ST_FILE_STEREO,
- st_u4startread,
- st_rawread,
- st_rawstopread,
- st_u4startwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_u4_format_fn(void)
-{
- return &st_u4_format;
-}
-
-
-
-static const char *slnames[] = {
- "sl",
- NULL,
-};
-
-static st_format_t st_sl_format = {
- slnames,
- NULL,
- ST_FILE_STEREO,
- st_slstartread,
- st_rawread,
- st_rawstopread,
- st_slstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_sl_format_fn(void)
-{
- return &st_sl_format;
-}
-
-static const char *swnames[] = {
- "sw",
- NULL
-};
-
-static st_format_t st_sw_format = {
- swnames,
- NULL,
- ST_FILE_STEREO,
- st_swstartread,
- st_rawread,
- st_rawstopread,
- st_swstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_sw_format_fn(void)
-{
- return &st_sw_format;
-}
-
-
-
-/* Signed 3 byte raw; used for testing only; not documented in the man page */
-
-static const char *s3names[] = {
- "s3",
- NULL
-};
-
-static st_format_t st_s3_format = {
- s3names,
- NULL,
- ST_FILE_STEREO,
- st_s3startread,
- st_rawread,
- st_rawstopread,
- st_s3startwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_s3_format_fn(void)
-{
- return &st_s3_format;
-}
-
-
-
-static const char *ubnames[] = {
- "ub",
- "sou",
- "fssd",
- NULL
-};
-
-static st_format_t st_ub_format = {
- ubnames,
- NULL,
- ST_FILE_STEREO,
- st_ubstartread,
- st_rawread,
- st_rawstopread,
- st_ubstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_ub_format_fn(void)
-{
- return &st_ub_format;
-}
-
-static const char *ulnames[] = {
- "ul",
- NULL
-};
-
-static st_format_t st_ul_format = {
- ulnames,
- NULL,
- ST_FILE_STEREO,
- st_ulstartread,
- st_rawread,
- st_rawstopread,
- st_ulstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_ul_format_fn(void)
-{
- return &st_ul_format;
-}
-
-static const char *uwnames[] = {
- "uw",
- NULL
-};
-
-static st_format_t st_uw_format = {
- uwnames,
- NULL,
- ST_FILE_STEREO,
- st_uwstartread,
- st_rawread,
- st_rawstopread,
- st_uwstartwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_uw_format_fn(void)
-{
- return &st_uw_format;
-}
-
-
-
-/* Unsigned 3 byte raw; used for testing only; not documented in the man page */
-
-static const char *u3names[] = {
- "u3",
- NULL
-};
-
-static st_format_t st_u3_format = {
- u3names,
- NULL,
- ST_FILE_STEREO,
- st_u3startread,
- st_rawread,
- st_rawstopread,
- st_u3startwrite,
- st_rawwrite,
- st_rawstopwrite,
- st_format_nothing_seek
-};
-
-const st_format_t *st_u3_format_fn(void)
-{
- return &st_u3_format;
-}
+RAW_FORMAT(sb,NULL ,NULL ,BYTE ,DEFAULT,SIGN2)
+RAW_FORMAT(sl,NULL ,NULL ,DWORD,DEFAULT,SIGN2)
+RAW_FORMAT(s3,NULL ,NULL ,24BIT,DEFAULT,SIGN2)
+RAW_FORMAT(sw,NULL ,NULL ,WORD ,DEFAULT,SIGN2)
+
+RAW_FORMAT(ub,"sou","fssd",BYTE ,DEFAULT,UNSIGNED)
+RAW_FORMAT(uw,NULL ,NULL ,WORD ,DEFAULT,UNSIGNED)
+RAW_FORMAT(u3,NULL ,NULL ,24BIT,DEFAULT,UNSIGNED)
+RAW_FORMAT(u4,NULL ,NULL ,DWORD,DEFAULT,UNSIGNED)
+
+RAW_FORMAT(al,NULL ,NULL ,BYTE ,NO ,ALAW)
+RAW_FORMAT(ul,NULL ,NULL ,BYTE ,NO ,ULAW)
+RAW_FORMAT(la,NULL ,NULL ,BYTE ,YES ,ALAW)
+RAW_FORMAT(lu,NULL ,NULL ,BYTE ,YES ,ULAW)
--- a/src/sf.c
+++ b/src/sf.c
@@ -39,7 +39,7 @@
sfcodep = (SFCODE *) &sfcodes(sfhead);
do {
sfcharp = (char *) sfcodep + sizeof(SFCODE);
- if (ft->signal.swap_bytes) {
+ if (ft->signal.reverse_bytes) {
sfcodep->bsize = st_swapdw(sfcodep->bsize);
sfcodep->code = st_swapdw(sfcodep->code);
}
@@ -103,7 +103,7 @@
return(ST_EOF);
}
memcpy(&sf->info, &sfhead.sfinfo, sizeof(struct sfinfo));
- if (ft->signal.swap_bytes) {
+ if (ft->signal.reverse_bytes) {
sf->info.sf_srate = st_swapf(sf->info.sf_srate);
sf->info.sf_packmode = st_swapdw(sf->info.sf_packmode);
sf->info.sf_chans = st_swapdw(sf->info.sf_chans);
--- a/src/sox.c
+++ b/src/sox.c
@@ -108,6 +108,7 @@
/* Arrays tracking input and output files */
static file_info_t file_opts[MAX_FILES];
static ft_t file_desc[MAX_FILES];
+#define ofile file_desc[file_count - 1]
static size_t file_count = 0;
static size_t input_count = 0;
@@ -174,7 +175,7 @@
static void cleanup(void)
{
size_t i;
- ft_t ft = file_desc[file_count - 1];
+ ft_t ft = ofile;
/* Close the input and output files before exiting. */
for (i = 0; i < input_count; i++)
@@ -212,7 +213,9 @@
fo->signal.size = -1;
fo->signal.encoding = ST_ENCODING_UNKNOWN;
fo->signal.channels = 0;
- fo->signal.swap_bytes = ST_SWAP_DEFAULT;
+ fo->signal.reverse_bytes = ST_REVERSE_DEFAULT;
+ fo->signal.reverse_nibbles = ST_REVERSE_DEFAULT;
+ fo->signal.reverse_bits = ST_REVERSE_DEFAULT;
fo->signal.compression = HUGE_VAL;
fo->volume = HUGE_VAL;
fo->volume_clips = 0;
@@ -413,7 +416,7 @@
return result;
}
-static char *getoptstr = "+r:v:t:c:C:hsuUAaig1b2w34lf8dxV::SqoenmMRLBX";
+static char *getoptstr = "+abc:defghilmnoqr:st:uv:wxABC:DLMNRSUV::X12348";
static struct option long_options[] =
{
@@ -433,6 +436,7 @@
{"no-show-progress", no_argument, NULL, 'q'},
{"rate" , required_argument, NULL, 'r'},
{"reverse-bits" , no_argument, NULL, 'X'},
+ {"reverse-nibbles" , no_argument, NULL, 'N'},
{"show-progress" , no_argument, NULL, 'S'},
{"type" , no_argument, NULL, 't'},
{"volume" , required_argument, NULL, 'v'},
@@ -462,11 +466,11 @@
case 2:
if (!strcmp(optarg, "little"))
- fo->signal.swap_bytes = ST_IS_BIGENDIAN;
+ fo->signal.reverse_bytes = ST_IS_BIGENDIAN;
else if (!strcmp(optarg, "big"))
- fo->signal.swap_bytes = ST_IS_LITTLEENDIAN;
+ fo->signal.reverse_bytes = ST_IS_LITTLEENDIAN;
else if (!strcmp(optarg, "swap"))
- fo->signal.swap_bytes = true;
+ fo->signal.reverse_bytes = true;
break;
case 3:
@@ -558,7 +562,9 @@
case 'u': fo->signal.encoding = ST_ENCODING_UNSIGNED; break;
case 'f': fo->signal.encoding = ST_ENCODING_FLOAT; break;
case 'a': fo->signal.encoding = ST_ENCODING_ADPCM; break;
+ case 'D': fo->signal.encoding = ST_ENCODING_MS_ADPCM; break; /* WIP */
case 'i': fo->signal.encoding = ST_ENCODING_IMA_ADPCM; break;
+ case 'o': fo->signal.encoding = ST_ENCODING_OKI_ADPCM; break; /* WIP */
case 'g': fo->signal.encoding = ST_ENCODING_GSM; break;
case 'U': fo->signal.encoding = ST_ENCODING_ULAW;
@@ -572,21 +578,25 @@
break;
case 'L':
- fo->signal.swap_bytes = ST_IS_BIGENDIAN;
+ fo->signal.reverse_bytes = ST_IS_BIGENDIAN;
break;
case 'B':
- fo->signal.swap_bytes = ST_IS_LITTLEENDIAN;
+ fo->signal.reverse_bytes = ST_IS_LITTLEENDIAN;
break;
case 'x':
- fo->signal.swap_bytes = ST_SWAP_YES;
+ fo->signal.reverse_bytes = ST_REVERSE_YES;
break;
case 'X':
- fo->signal.reverse_bits = true;
+ fo->signal.reverse_bits = ST_REVERSE_YES;
break;
+ case 'N':
+ fo->signal.reverse_nibbles = ST_REVERSE_YES;
+ break;
+
case 'V':
if (optarg == NULL)
++st_output_verbosity_level;
@@ -622,6 +632,32 @@
return ST_EOF;
}
+static void report_file(ft_t f)
+{
+ static char const * const no_yes[] = {"no", "yes"};
+
+ st_report("\n\n%s: %s\n"
+ "Sample Size : %s\n"
+ "Sample Encoding: %s\n"
+ "Channels : %u\n"
+ "Sample Rate : %lu\n"
+ "Endian Type : %s\n"
+ "Reverse Nibbles: %s\n"
+ "Reverse Bits : %s\n"
+ "Comment : \"%s%c\n", /* Deliberate \n to get blank line */
+ f->mode == 'r'? "Input Filename " : "Output Filename",
+ f->filename,
+ st_sizes_str[(unsigned char)f->signal.size],
+ st_encodings_str[(unsigned char)f->signal.encoding],
+ f->signal.channels,
+ f->signal.rate,
+ f->signal.size == 1? "N/A" :
+ f->signal.reverse_bytes != ST_IS_BIGENDIAN? "big" : "little",
+ no_yes[f->signal.reverse_nibbles],
+ no_yes[f->signal.reverse_bits],
+ f->comment? f->comment : "\bnone", f->comment? '"' : ' ');
+}
+
/*
* Process input file -> effect table -> output file one buffer at a time
*/
@@ -634,17 +670,10 @@
st_sample_t *ibuf[MAX_INPUT_FILES];
for (f = 0; f < input_count; f++) {
- st_report("Input file %s: using sample rate %lu\n\tsize %s, encoding %s, %d %s, volume %g",
- file_desc[f]->filename, file_desc[f]->signal.rate,
- st_sizes_str[(unsigned char)file_desc[f]->signal.size],
- st_encodings_str[(unsigned char)file_desc[f]->signal.encoding],
- file_desc[f]->signal.channels,
- (file_desc[f]->signal.channels > 1) ? "channels" : "channel",
- file_opts[f]->volume == HUGE_VAL? 1 : file_opts[f]->volume);
-
- if (file_desc[f]->comment)
- st_report("Input file %s: comment \"%s\"",
- file_desc[f]->filename, file_desc[f]->comment);
+ report_file(file_desc[f]);
+ if (file_opts[f]->volume != HUGE_VAL && file_opts[f]->volume != 1)
+ st_report("%s input level %g",
+ file_desc[f]->filename, file_opts[f]->volume);
}
for (f = 0; f < input_count; f++) {
@@ -695,8 +724,7 @@
loops[i].type = file_desc[0]->loops[i].type;
}
- file_desc[file_count - 1] =
- st_open_write(overwrite_permitted,
+ ofile = st_open_write(overwrite_permitted,
info->filename,
&info->signal,
info->filetype,
@@ -704,7 +732,7 @@
&file_desc[0]->instr,
loops);
- if (!file_desc[file_count - 1])
+ if (!ofile)
/* st_open_write() will call st_warn for most errors.
* Rely on that printing something. */
exit(2);
@@ -712,23 +740,13 @@
/* When writing to an audio device, auto turn on the
* status display to match behavior of ogg123 status,
* unless the user requested us not to display anything. */
- if ((strcmp(file_desc[file_count - 1]->filetype, "alsa") == 0 ||
- strcmp(file_desc[file_count - 1]->filetype, "ossdsp") == 0 ||
- strcmp(file_desc[file_count - 1]->filetype, "sunau") == 0) &&
+ if ((strcmp(ofile->filetype, "alsa") == 0 ||
+ strcmp(ofile->filetype, "ossdsp") == 0 ||
+ strcmp(ofile->filetype, "sunau") == 0) &&
!quiet)
status = 1;
- st_report("Output file %s: using sample rate %lu\n\tsize %s, encoding %s, %d %s",
- file_desc[file_count-1]->filename,
- file_desc[file_count-1]->signal.rate,
- st_sizes_str[(unsigned char)file_desc[file_count-1]->signal.size],
- st_encodings_str[(unsigned char)file_desc[file_count-1]->signal.encoding],
- file_desc[file_count-1]->signal.channels,
- (file_desc[file_count-1]->signal.channels > 1) ? "channels" : "channel");
-
- if (file_desc[file_count - 1]->comment)
- st_report("Output file: comment \"%s\"",
- file_desc[file_count - 1]->comment);
+ report_file(ofile);
}
/* Adjust the input rate for the speed effect */
@@ -914,12 +932,12 @@
break;
/* If there's an error, don't try to write more. */
- if (file_desc[file_count - 1]->st_errno)
+ if (ofile->st_errno)
break;
} while (flowstatus == 0);
/* Drain the effects; don't write if output is indicating errors. */
- if (file_desc[file_count - 1]->st_errno == 0)
+ if (ofile->st_errno == 0)
drain_effect_out();
}
@@ -1001,8 +1019,8 @@
int effects_mask = 0;
int status;
- needrate = (file_desc[0]->signal.rate != file_desc[file_count-1]->signal.rate);
- needchan = (file_desc[0]->signal.channels != file_desc[file_count-1]->signal.channels);
+ needrate = (file_desc[0]->signal.rate != ofile->signal.rate);
+ needchan = (file_desc[0]->signal.channels != ofile->signal.channels);
for (i = 0; i < nuser_effects; i++) {
if (user_efftab[i].h->flags & ST_EFF_CHAN)
@@ -1027,7 +1045,7 @@
* after the avg effect.
*/
if (needchan && !(haschan) &&
- (file_desc[0]->signal.channels > file_desc[file_count-1]->signal.channels))
+ (file_desc[0]->signal.channels > ofile->signal.channels))
{
/* Find effect and update initial pointers */
st_geteffect(&efftab[neffects], "avg");
@@ -1043,7 +1061,7 @@
/* Copy format info to effect table */
effects_mask = st_updateeffect(&efftab[neffects],
&file_desc[0]->signal,
- &file_desc[file_count-1]->signal,
+ &ofile->signal,
effects_mask);
neffects++;
@@ -1053,7 +1071,7 @@
* after the resample effect.
*/
if (needrate && !(hasrate) &&
- (file_desc[0]->signal.rate > file_desc[file_count-1]->signal.rate))
+ (file_desc[0]->signal.rate > ofile->signal.rate))
{
st_geteffect(&efftab[neffects], "resample");
@@ -1068,7 +1086,7 @@
/* Copy format info to effect table */
effects_mask = st_updateeffect(&efftab[neffects],
&file_desc[0]->signal,
- &file_desc[file_count-1]->signal,
+ &ofile->signal,
effects_mask);
/* Rate can't handle multiple channels so be sure and
@@ -1088,7 +1106,7 @@
/* Copy format info to effect table */
effects_mask = st_updateeffect(&efftab[neffects],
&file_desc[0]->signal,
- &file_desc[file_count - 1]->signal,
+ &ofile->signal,
effects_mask);
/* If this effect can't handle multiple channels then
@@ -1118,7 +1136,7 @@
/* Copy format info to effect table */
effects_mask = st_updateeffect(&efftab[neffects],
&file_desc[0]->signal,
- &file_desc[file_count - 1]->signal,
+ &ofile->signal,
effects_mask);
/* Rate can't handle multiple channels so be sure and
@@ -1144,7 +1162,7 @@
/* Copy format info to effect table */
effects_mask = st_updateeffect(&efftab[neffects],
&file_desc[0]->signal,
- &file_desc[file_count - 1]->signal,
+ &ofile->signal,
effects_mask);
neffects++;
@@ -1220,22 +1238,22 @@
if (user_abort)
return ST_EOF;
- len = st_write(file_desc[file_count - 1],
+ len = st_write(ofile,
&efftab[neffects - 1].obuf[total],
efftab[neffects - 1].olen - total);
- if (len != efftab[neffects - 1].olen - total || file_desc[file_count - 1]->eof) {
- st_warn("Error writing: %s", file_desc[file_count - 1]->st_errstr);
+ if (len != efftab[neffects - 1].olen - total || ofile->eof) {
+ st_warn("Error writing: %s", ofile->st_errstr);
return ST_EOF;
}
total += len;
} while (total < efftab[neffects-1].olen);
- output_samples += (total / file_desc[file_count - 1]->signal.channels);
+ output_samples += (total / ofile->signal.channels);
efftab[neffects-1].odone = efftab[neffects-1].olen = 0;
} else {
/* Make it look like everything was consumed */
output_samples += (efftab[neffects-1].olen /
- file_desc[file_count - 1]->signal.channels);
+ ofile->signal.channels);
efftab[neffects-1].odone = efftab[neffects-1].olen = 0;
}
@@ -1259,7 +1277,7 @@
* will cause stereo channels to be inversed.
*/
if ((efftab[e].olen - efftab[e].odone) >=
- file_desc[file_count - 1]->signal.channels)
+ ofile->signal.channels)
havedata = 1;
else
st_warn("Received buffer with incomplete amount of samples.");
@@ -1643,7 +1661,8 @@
" Specify file containing comment text for the output file\n"
"-r rate sample rate of audio\n"
"-t filetype file type of audio\n"
- "-x invert auto-detected endianess of data\n"
+ "-x/-N/-X invert auto-detected endianness/nibble-order/bit-order of data\n"
+ "-B/-L force endian type to big/little\n"
"-s/-u/-U/-A/ sample encoding: signed/unsigned/u-law/A-law\n"
" -a/-i/-g/-f ADPCM/IMA_ADPCM/GSM/floating point\n"
"-1/-2/-3/-4/-8 sample size in bytes\n"
--- a/src/sphere.c
+++ b/src/sphere.c
@@ -105,9 +105,9 @@
{
sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval);
if (strncmp(fldsval,"01",2) == 0)
- ft->signal.swap_bytes = ST_IS_BIGENDIAN; /* Data is little endian. */
+ ft->signal.reverse_bytes = ST_IS_BIGENDIAN; /* Data is little endian. */
else if (strncmp(fldsval,"10",2) == 0)
- ft->signal.swap_bytes = ST_IS_LITTLEENDIAN; /* Data is big endian. */
+ ft->signal.reverse_bytes = ST_IS_LITTLEENDIAN; /* Data is big endian. */
}
if (st_reads(ft, buf, header_size) == ST_EOF)
@@ -263,7 +263,7 @@
st_writes(ft, buf);
sprintf(buf, "sample_byte_format -s2 %s\n",
- ft->signal.swap_bytes != ST_IS_BIGENDIAN ? "10" : "01");
+ ft->signal.reverse_bytes != ST_IS_BIGENDIAN ? "10" : "01");
st_writes(ft, buf);
rate = ft->signal.rate;
--- a/src/st.h
+++ b/src/st.h
@@ -171,20 +171,23 @@
typedef enum {
ST_ENCODING_UNKNOWN ,
- ST_ENCODING_UNSIGNED , /* unsigned linear: Sound Blaster */
- ST_ENCODING_SIGN2 , /* signed linear 2's comp: Mac */
+
ST_ENCODING_ULAW , /* u-law signed logs: US telephony, SPARC */
ST_ENCODING_ALAW , /* A-law signed logs: non-US telephony */
+ ST_ENCODING_ADPCM , /* G72x Compressed PCM */
+ ST_ENCODING_MS_ADPCM , /* Microsoft Compressed PCM */
+ ST_ENCODING_IMA_ADPCM , /* IMA Compressed PCM */
+ ST_ENCODING_OKI_ADPCM , /* Dialogic/OKI Compressed PCM */
+
+ ST_ENCODING_SIZE_IS_WORD, /* FIXME: marks raw types (above) that mis-report size. st_signalinfo_t really needs a precision_in_bits item */
+
+ ST_ENCODING_UNSIGNED , /* unsigned linear: Sound Blaster */
+ ST_ENCODING_SIGN2 , /* signed linear 2's comp: Mac */
ST_ENCODING_FLOAT , /* 32-bit float */
- ST_ENCODING_ADPCM , /* Compressed PCM */
- ST_ENCODING_IMA_ADPCM , /* Compressed PCM */
ST_ENCODING_GSM , /* GSM 6.10 33byte frame lossy compression */
- ST_ENCODING_INV_ULAW , /* Inversed bit-order u-law */
- ST_ENCODING_INV_ALAW , /* Inversed bit-order A-law */
ST_ENCODING_MP3 , /* MP3 compression */
ST_ENCODING_VORBIS , /* Vorbis compression */
ST_ENCODING_FLAC , /* FLAC compression */
- ST_ENCODING_OKI_ADPCM , /* Compressed PCM */
ST_ENCODINGS /* End of list marker */
} st_encoding_t;
@@ -197,6 +200,8 @@
double speed; /* Gather up all speed changes here, then resample */
} st_globalinfo_t;
+typedef enum {ST_REVERSE_NO, ST_REVERSE_YES, ST_REVERSE_DEFAULT} st_reverse_t;
+
/* Signal parameters */
typedef struct st_signalinfo
@@ -205,8 +210,9 @@
signed char size; /* word length of data */
st_encoding_t encoding; /* format of sample numbers */
unsigned channels; /* number of sound channels */
- enum {ST_SWAP_NO, ST_SWAP_YES, ST_SWAP_DEFAULT} swap_bytes; /* endian */
- bool reverse_bits;
+ st_reverse_t reverse_bytes; /* endiannesses... */
+ st_reverse_t reverse_nibbles;
+ st_reverse_t reverse_bits;
double compression; /* compression factor (where applicable) */
} st_signalinfo_t;
@@ -384,7 +390,7 @@
char priv[ST_MAX_EFFECT_PRIVSIZE]; /* private area for effect */
};
-void set_swap_if_not_already_set(ft_t ft);
+void set_endianness_if_not_already_set(ft_t ft);
extern ft_t st_open_read(const char *path, const st_signalinfo_t *info,
const char *filetype);
ft_t st_open_write(
--- a/src/st_i.h
+++ b/src/st_i.h
@@ -251,10 +251,11 @@
int st_effect_nothing_drain(eff_t effp, st_sample_t *obuf, st_size_t *osamp);
int st_effect_nothing_getopts(eff_t effp, int n, char **argv UNUSED);
+int st_rawstart(ft_t ft, bool default_rate, bool default_channels, st_encoding_t encoding, signed char size, st_reverse_t rev_bits);
+#define st_rawstartread(ft) st_rawstart(ft, false, false, ST_ENCODING_UNKNOWN, -1, ST_REVERSE_DEFAULT)
+#define st_rawstartwrite st_rawstartread
#define st_rawstopread st_format_nothing
-int st_rawstart(ft_t ft);
-#define st_rawstartread st_rawstart
-#define st_rawstartwrite st_rawstart
+
/*=============================================================================
* Effects
--- a/src/stio.c
+++ b/src/stio.c
@@ -25,14 +25,18 @@
#define SET_BINARY_MODE(file)
#endif
-void set_swap_if_not_already_set(ft_t ft)
+void set_endianness_if_not_already_set(ft_t ft)
{
- if (ft->signal.swap_bytes == ST_SWAP_DEFAULT) {
+ if (ft->signal.reverse_bytes == ST_REVERSE_DEFAULT) {
if (ft->h->flags & ST_FILE_ENDIAN)
- ft->signal.swap_bytes = ST_IS_LITTLEENDIAN != !(ft->h->flags & ST_FILE_ENDBIG);
+ ft->signal.reverse_bytes = ST_IS_LITTLEENDIAN != !(ft->h->flags & ST_FILE_ENDBIG);
else
- ft->signal.swap_bytes = ST_SWAP_NO;
+ ft->signal.reverse_bytes = ST_REVERSE_NO;
}
+ if (ft->signal.reverse_nibbles == ST_REVERSE_DEFAULT)
+ ft->signal.reverse_nibbles = ST_REVERSE_NO;
+ if (ft->signal.reverse_bits == ST_REVERSE_DEFAULT)
+ ft->signal.reverse_bits = ST_REVERSE_NO;
}
static int is_seekable(ft_t ft)
@@ -132,7 +136,7 @@
}
if (filetype)
- set_swap_if_not_already_set(ft);
+ set_endianness_if_not_already_set(ft);
/* Read and write starters can change their formats. */
if ((*ft->h->startread)(ft) != ST_SUCCESS)
@@ -268,7 +272,7 @@
if (instr)
ft->instr = *instr;
- set_swap_if_not_already_set(ft);
+ set_endianness_if_not_already_set(ft);
/* Read and write starters can change their formats. */
if ((*ft->h->startwrite)(ft) != ST_SUCCESS)
--- a/src/wav.c
+++ b/src/wav.c
@@ -408,7 +408,7 @@
if (strncmp("RIFX", magic, 4) == 0)
{
st_debug("Found RIFX header, swapping bytes");
- ft->signal.swap_bytes = ST_IS_LITTLEENDIAN;
+ ft->signal.reverse_bytes = ST_IS_LITTLEENDIAN;
}
st_readdw(ft, &dwRiffLength);
@@ -1457,7 +1457,7 @@
/* If user specified opposite swap then we think, assume they are
* asking to write a RIFX file.
*/
- if (ft->signal.swap_bytes != ST_IS_BIGENDIAN)
+ if (ft->signal.reverse_bytes != ST_IS_BIGENDIAN)
{
if (!second_header)
st_report("Requested to swap bytes so writing RIFX header");
--- a/src/wve.c
+++ b/src/wve.c
@@ -79,7 +79,7 @@
* testing for endianess was standardized. Leaving since
* it doesn't hurt.
*/
- ft->signal.swap_bytes = !ft->signal.swap_bytes;
+ ft->signal.reverse_bytes = !ft->signal.reverse_bytes;
st_debug("Found inverted PSION magic word. Swapping bytes.");
}
else if (version == PSION_VERSION)