ref: 2b1a302ecab9325dc84e1e6c91b45d5ff194978d
parent: fc5263cf0f108d31f5afda9007227c3afa03852b
author: cbagwell <cbagwell>
date: Fri Apr 13 17:13:52 EDT 2001
Adding intial support for 12-bit audio data inside sox. AIFF files can now read 12-bit audio data.
--- a/Changelog
+++ b/Changelog
@@ -47,6 +47,8 @@
to use stderr.
o Corrected AU header length value when comments were less than
4 bytes.
+ o Added initial support for 12-bit audio data. AIFF files can now read 12-bit audio
+ data but can not write it (lacks command line support).
sox-12.17.1
-----------
--- a/src/aiff.c
+++ b/src/aiff.c
@@ -246,15 +246,7 @@
st_readw(ft, &releaseLoopBegin); /* begin marker */
st_readw(ft, &releaseLoopEnd); /* end marker */
- /* Required to ignore loops on playback if type
- * is 0 (NoLoop). The other check is done for
- * historical reason and is probably not needed.
- */
- if ((ft->loops[0].type == 0) ||
- (sustainLoopBegin == 0 && releaseLoopBegin == 0))
- foundinstr = 0;
- else
- foundinstr = 1;
+ foundinstr = 1;
}
else if (strncmp(buf, "APPL", 4) == 0) {
st_readdw(ft, &chunksize);
@@ -375,6 +367,9 @@
case 8:
ft->info.size = ST_SIZE_BYTE;
break;
+ case 12:
+ ft->info.size = ST_SIZE_12BIT;
+ break;
case 16:
ft->info.size = ST_SIZE_WORD;
break;
@@ -403,7 +398,11 @@
st_fail_errno(ft,ST_EFMT,"Bogus AIFF file: MARKers but no INSTrument.");
return(ST_EOF);
}
- if (!foundmark && foundinstr)
+ /* Check for INST chunk found but no MARK chunk. One case that is OK is
+ * if the INST chunk is of type NOLOOP which means its not much of an instrument
+ * anyways.
+ */
+ if (!foundmark && foundinstr && ft->loops[0].type != 0)
{
st_fail_errno(ft,ST_EFMT,"Bogus AIFF file: INSTrument but no MARKers.");
return(ST_EOF);
--- a/src/au.c
+++ b/src/au.c
@@ -402,6 +402,7 @@
ULONG sample_rate;
ULONG channels;
int x;
+ int comment_size;
if((encoding = st_ausunencoding(ft->info.size, ft->info.encoding)) == -1) {
st_report("Unsupported output encoding/size for Sun/NeXT header or .AU format not specified.");
@@ -422,9 +423,13 @@
if (ft->comment == NULL)
ft->comment = "SOX";
- hdr_size = SUN_HDRSIZE + strlen(ft->comment) + 1; /*+1 = null-term. */
- if (strlen(ft->comment) < 3)
- hdr_size += 3 - strlen(ft->comment);
+ hdr_size = SUN_HDRSIZE;
+
+ comment_size = strlen(ft->comment) + 1; /*+1 = null-term. */
+ if (comment_size < 4)
+ comment_size = 4; /* minimum size */
+
+ hdr_size += comment_size;
st_writedw(ft, hdr_size);
--- a/src/misc.c
+++ b/src/misc.c
@@ -30,7 +30,8 @@
"longs",
"32-bit floats",
"64-bit floats",
- "IEEE floats"
+ "IEEE floats",
+ "12-bit shorts"
};
const char *st_encodings_str[] = {
--- a/src/raw.c
+++ b/src/raw.c
@@ -43,16 +43,19 @@
switch(ft->info.size) {
case ST_SIZE_BYTE:
sample_size = 1;
- break;
+ break;
+ case ST_SIZE_12BIT:
+ sample_size = sizeof(short);
+ break;
case ST_SIZE_WORD:
sample_size = sizeof(short);
- break;
+ break;
case ST_SIZE_DWORD:
sample_size = sizeof(LONG);
- break;
+ break;
case ST_SIZE_FLOAT:
sample_size = sizeof(float);
- break;
+ break;
default:
st_fail_errno(ft,ST_ENOTSUP,"Can't seek this data size");
return(ft->st_errno);
@@ -172,6 +175,24 @@
swapn(p,n);
}
+static int blockr_s12bit(p0, n, ft)
+LONG *p0,n;
+ft_t ft;
+{
+ LONG x, done;
+ short s;
+
+ for (done=0; done < n;) {
+ blockr(&s, sizeof(short), ft);
+ x = s;
+ if (ft->file.eof) break;
+ /* scale signed up to long's range */
+ *p0++ = LEFT(x, 20);
+ done++;
+ }
+ return done;
+}
+
static int blockr_sw(p0, n, ft)
LONG *p0,n;
ft_t ft;
@@ -278,6 +299,35 @@
return 0;
}
break;
+ case ST_SIZE_12BIT:
+ switch(ft->info.encoding)
+ {
+ case ST_ENCODING_SIGN2:
+ return blockr_s12bit(buf, nsamp, ft);
+ case ST_ENCODING_UNSIGNED:
+ while(done < nsamp) {
+ LONG x;
+ unsigned short s;
+ blockr(&s, sizeof(short), ft);
+ x = s;
+ if (ft->file.eof)
+ return done;
+ /* Convert to signed */
+ x ^= 0x8000;
+ /* scale signed up to long's range */
+ *buf++ = LEFT(x, 20);
+ done++;
+ }
+ return done;
+ case ST_ENCODING_ULAW:
+ st_fail_errno(ft,ST_EFMT,"No U-Law support for shorts");
+ return 0;
+ case ST_ENCODING_ALAW:
+ st_fail_errno(ft,ST_EFMT,"No A-Law support for shorts");
+ return 0;
+ }
+ break;
+
case ST_SIZE_DWORD:
switch(ft->info.encoding)
{
--- a/src/st.h
+++ b/src/st.h
@@ -181,8 +181,9 @@
#define ST_SIZE_FLOAT 5
#define ST_SIZE_DOUBLE 6
#define ST_SIZE_IEEE 7 /* IEEE 80-bit floats. */
+#define ST_SIZE_12BIT 8
-#define ST_SIZE_MAX 7
+#define ST_SIZE_MAX 8
/* Style field */
#define ST_ENCODING_UNSIGNED 1 /* unsigned linear: Sound Blaster */
--- a/src/util.c
+++ b/src/util.c
@@ -436,7 +436,7 @@
if ((ft->info.size <= 0) || (ft->info.size > ST_SIZE_MAX))
{
- st_fail_errno(ft,ST_EFMT,"Data size %i for %s file is bogus\n", ft->filename,ft->info.size);
+ st_fail_errno(ft,ST_EFMT,"Data size %i for %s file is bogus\n", ft->info.size, ft->filename);
return ST_EOF;
}
@@ -443,7 +443,7 @@
/* anyway to check length on st_encoding_str[] ? */
if (ft->info.encoding <= 0 || ft->info.encoding > ST_ENCODING_MAX)
{
- st_fail_errno(ft,ST_EFMT,"Data encoding %i for %s file is bogus\n", ft->filename,ft->info.encoding);
+ st_fail_errno(ft,ST_EFMT,"Data encoding %i for %s file is bogus\n", ft->info.encoding, ft->filename);
return ST_EOF;
}