|
From: robs <ro...@us...> - 2008-03-16 15:13:57
|
Update of /cvsroot/sox/sox/src In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv10836 Modified Files: sphere.c misc.c sox.h Log Message: sphere updates Index: sphere.c =================================================================== RCS file: /cvsroot/sox/sox/src/sphere.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- sphere.c 9 Mar 2008 20:38:30 -0000 1.50 +++ sphere.c 16 Mar 2008 15:13:51 -0000 1.51 @@ -8,253 +8,179 @@ */ #include "sox_i.h" - -#include <math.h> #include <string.h> -#include <errno.h> -/* Private data for sphere file */ -typedef struct spherestuff { - char shorten_check[4]; - sox_size_t numSamples; -} *sphere_t; - -/* - * Do anything required before you start reading samples. - * Read file header. - * Find out sampling rate, - * size and encoding of samples, - * mono/stereo/quad. - */ -static int startread(sox_format_t * ft) +static int start_read(sox_format_t * ft) { - sphere_t sphere = (sphere_t) ft->priv; - char *buf; - char fldname[64], fldtype[16], fldsval[128]; - int i; - sox_size_t header_size, bytes_read; - long rate; - - /* Magic header */ - if (sox_reads(ft, fldname, 8) == SOX_EOF || strncmp(fldname, "NIST_1A", 7) != 0) - { - sox_fail_errno(ft,SOX_EHDR,"Sphere header does not begin with magic mord 'NIST_1A'"); - return(SOX_EOF); - } - - if (sox_reads(ft, fldsval, 8) == SOX_EOF) - { - sox_fail_errno(ft,SOX_EHDR,"Error reading Sphere header"); - return(SOX_EOF); - } - - /* Determine header size, and allocate a buffer large enough to hold it. */ - sscanf(fldsval, "%u", &header_size); - buf = xmalloc(header_size); - - /* Skip what we have read so far */ - header_size -= 16; - - if (sox_reads(ft, buf, header_size) == SOX_EOF) - { - sox_fail_errno(ft,SOX_EHDR,"Error reading Sphere header"); - free(buf); - return(SOX_EOF); - } - - header_size -= (strlen(buf) + 1); - - while (strncmp(buf, "end_head", 8) != 0) - { - if (strncmp(buf, "sample_n_bytes", 14) == 0 && !ft->encoding.bits_per_sample) - { - sscanf(buf, "%63s %15s %d", fldname, fldtype, &i); - ft->encoding.bits_per_sample = i << 3; - } - if (strncmp(buf, "channel_count", 13) == 0 && - ft->signal.channels == 0) - { - sscanf(buf, "%63s %15s %d", fldname, fldtype, &i); - ft->signal.channels = i; - } - if (strncmp(buf, "sample_coding", 13) == 0) - { - sscanf(buf, "%63s %15s %127s", fldname, fldtype, fldsval); - /* Only bother looking for ulaw flag. All others - * should be caught below by default PCM check - */ - if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN && - strncmp(fldsval,"ulaw",4) == 0) - { - ft->encoding.encoding = SOX_ENCODING_ULAW; - } - } - if (strncmp(buf, "sample_rate ", 12) == 0 && - ft->signal.rate == 0) - { - sscanf(buf, "%53s %15s %ld", fldname, fldtype, &rate); - ft->signal.rate = rate; - } - if (strncmp(buf, "sample_byte_format", 18) == 0) - { - sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval); - if (strncmp(fldsval,"01",2) == 0) - ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN; /* Data is little endian. */ - else if (strncmp(fldsval,"10",2) == 0) - ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN; /* Data is big endian. */ - } + sox_encoding_t encoding = SOX_ENCODING_SIGN2; + sox_size_t header_size, bytes_read; + sox_size_t num_samples = 0; + unsigned bytes_per_sample = 0; + unsigned channels = 1; + unsigned rate = 16000; + char fldname[64], fldtype[16], fldsval[128]; + char * buf; - if (sox_reads(ft, buf, header_size) == SOX_EOF) - { - sox_fail_errno(ft,SOX_EHDR,"Error reading Sphere header"); - free(buf); - return(SOX_EOF); - } + /* Magic header */ + if (sox_reads(ft, fldname, 8) || strncmp(fldname, "NIST_1A", 7) != 0) { + sox_fail_errno(ft, SOX_EHDR, "Sphere header does not begin with magic word 'NIST_1A'"); + return (SOX_EOF); + } - header_size -= (strlen(buf) + 1); - } + if (sox_reads(ft, fldsval, 8)) { + sox_fail_errno(ft, SOX_EHDR, "Error reading Sphere header"); + return (SOX_EOF); + } - if (!ft->encoding.bits_per_sample) - ft->encoding.bits_per_sample = 8; + /* Determine header size, and allocate a buffer large enough to hold it. */ + sscanf(fldsval, "%u", &header_size); + buf = xmalloc(header_size); - /* sample_coding is optional and is PCM if missing. - * This means encoding is signed if size = word or - * unsigned if size = byte. - */ - if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN) - { - if (ft->encoding.bits_per_sample == 8) - ft->encoding.encoding = SOX_ENCODING_UNSIGNED; - else - ft->encoding.encoding = SOX_ENCODING_SIGN2; - } + /* Skip what we have read so far */ + header_size -= 16; - while (header_size) - { - bytes_read = sox_readbuf(ft, buf, header_size); - if (bytes_read == 0) - { - free(buf); - return(SOX_EOF); - } - header_size -= bytes_read; - } + if (sox_reads(ft, buf, header_size) == SOX_EOF) { + sox_fail_errno(ft, SOX_EHDR, "Error reading Sphere header"); + free(buf); + return (SOX_EOF); + } - sphere->shorten_check[0] = 0; + header_size -= (strlen(buf) + 1); - if (ft->seekable) { - /* Check first four bytes of data to see if it's shorten compressed. */ - sox_ssize_t pos = sox_tell(ft); - sox_reads(ft, sphere->shorten_check, 4); + while (strncmp(buf, "end_head", 8) != 0) { + if (strncmp(buf, "sample_n_bytes", 14) == 0) + sscanf(buf, "%63s %15s %u", fldname, fldtype, &bytes_per_sample); + else if (strncmp(buf, "channel_count", 13) == 0) + sscanf(buf, "%63s %15s %u", fldname, fldtype, &channels); + else if (strncmp(buf, "sample_count ", 13) == 0) + sscanf(buf, "%53s %15s %u", fldname, fldtype, &num_samples); + else if (strncmp(buf, "sample_rate ", 12) == 0) + sscanf(buf, "%53s %15s %u", fldname, fldtype, &rate); + else if (strncmp(buf, "sample_coding", 13) == 0) { + sscanf(buf, "%63s %15s %127s", fldname, fldtype, fldsval); + if (!strcasecmp(fldsval, "ulaw") || !strcasecmp(fldsval, "mu-law")) + encoding = SOX_ENCODING_ULAW; + else if (!strcasecmp(fldsval, "pcm")) + encoding = SOX_ENCODING_SIGN2; + else { + sox_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval); + free(buf); + return SOX_EOF; + } + } + else if (strncmp(buf, "sample_byte_format", 18) == 0) { + sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval); + if (strcmp(fldsval, "01") == 0) /* Data is little endian. */ + ft->encoding.reverse_bytes = SOX_IS_BIGENDIAN; + else if (strcmp(fldsval, "10") == 0) /* Data is big endian. */ + ft->encoding.reverse_bytes = SOX_IS_LITTLEENDIAN; + else if (strcmp(fldsval, "1")) { + sox_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval); + free(buf); + return SOX_EOF; + } + } - if (!strcmp(sphere->shorten_check,"ajkg")) { - sox_fail_errno(ft, SOX_EFMT, "File uses shorten compression, cannot handle this."); - free(buf); - return(SOX_EOF); - } + if (sox_reads(ft, buf, header_size) == SOX_EOF) { + sox_fail_errno(ft, SOX_EHDR, "Error reading Sphere header"); + free(buf); + return (SOX_EOF); + } - /* Can't just seek -4, as sox_reads has read 1-4 bytes */ - sox_seeki(ft, pos, SEEK_SET); - } + header_size -= (strlen(buf) + 1); + } - free(buf); - return sox_rawstartread(ft); -} + if (!bytes_per_sample) + bytes_per_sample = encoding == SOX_ENCODING_ULAW? 1 : 2; -static int startwrite(sox_format_t * ft) -{ - int rc; - int x; - sphere_t sphere = (sphere_t) ft->priv; + if (encoding == SOX_ENCODING_SIGN2 && bytes_per_sample == 1) + ft->encoding.encoding = SOX_ENCODING_UNSIGNED; - if (!ft->seekable) - { - sox_fail_errno(ft,SOX_EOF,"File must be seekable for sphere file output"); - return (SOX_EOF); + while (header_size) { + bytes_read = sox_readbuf(ft, buf, header_size); + if (bytes_read == 0) { + free(buf); + return (SOX_EOF); } + header_size -= bytes_read; + } + free(buf); - sphere->numSamples = 0; + if (ft->seekable) { + /* Check first four bytes of data to see if it's shorten compressed. */ + char shorten_check[4]; - /* Needed for rawwrite */ - rc = sox_rawstartwrite(ft); - if (rc) - return rc; + if (sox_readchars(ft, shorten_check, sizeof(shorten_check))) + return SOX_EOF; + sox_seeki(ft, -(sox_ssize_t)sizeof(shorten_check), SEEK_CUR); - for (x = 0; x < 1024; x++) - { - sox_writeb(ft, ' '); + if (!memcmp(shorten_check, "ajkg", sizeof(shorten_check))) { + sox_fail_errno(ft, SOX_EFMT, + "File uses shorten compression, cannot handle this."); + return (SOX_EOF); } + } - return(SOX_SUCCESS); - -} - -static sox_size_t write_samples(sox_format_t * ft, const sox_sample_t *buf, sox_size_t len) -{ - sphere_t sphere = (sphere_t) ft->priv; - - sphere->numSamples += len; /* must later be divided by channels */ - return sox_rawwrite(ft, buf, len); + return sox_check_read_params(ft, channels, (sox_rate_t)rate, encoding, + bytes_per_sample << 3, (off_t)(num_samples * channels)); } -static int stopwrite(sox_format_t * ft) +static int write_header(sox_format_t * ft) { - char buf[128]; - sphere_t sphere = (sphere_t) ft->priv; - long samples, rate; - - if (sox_seeki(ft, 0, 0) != 0) - { - sox_fail_errno(ft,errno,"Could not rewind output file to rewrite sphere header."); - return (SOX_EOF); - } + char buf[128]; + long samples = (ft->olength ? ft->olength : ft->length) / ft->signal.channels; - sox_writes(ft, "NIST_1A\n"); - sox_writes(ft, " 1024\n"); + sox_writes(ft, "NIST_1A\n"); + sox_writes(ft, " 1024\n"); - samples = sphere->numSamples/ft->signal.channels; + if (samples) { sprintf(buf, "sample_count -i %ld\n", samples); sox_writes(ft, buf); + } - sprintf(buf, "sample_n_bytes -i %d\n", ft->encoding.bits_per_sample >> 3); - sox_writes(ft, buf); + sprintf(buf, "sample_n_bytes -i %d\n", ft->encoding.bits_per_sample >> 3); + sox_writes(ft, buf); - sprintf(buf, "channel_count -i %d\n", ft->signal.channels); - sox_writes(ft, buf); + sprintf(buf, "channel_count -i %d\n", ft->signal.channels); + sox_writes(ft, buf); + if (ft->encoding.bits_per_sample == 8) + sprintf(buf, "sample_byte_format -s1 1\n"); + else sprintf(buf, "sample_byte_format -s2 %s\n", - ft->encoding.reverse_bytes != SOX_IS_BIGENDIAN ? "10" : "01"); - sox_writes(ft, buf); + ft->encoding.reverse_bytes != SOX_IS_BIGENDIAN ? "10" : "01"); + sox_writes(ft, buf); - rate = ft->signal.rate; - sprintf(buf, "sample_rate -i %ld\n", rate); - sox_writes(ft, buf); + sprintf(buf, "sample_rate -i %u\n", (unsigned) (ft->signal.rate + .5)); + sox_writes(ft, buf); - if (ft->encoding.encoding == SOX_ENCODING_ULAW) - sox_writes(ft, "sample_coding -s4 ulaw\n"); - else - sox_writes(ft, "sample_coding -s3 pcm\n"); + if (ft->encoding.encoding == SOX_ENCODING_ULAW) + sox_writes(ft, "sample_coding -s4 ulaw\n"); + else + sox_writes(ft, "sample_coding -s3 pcm\n"); - sox_writes(ft, "end_head\n"); + sox_writes(ft, "end_head\n"); - return (SOX_SUCCESS); + sox_padbytes(ft, 1024 - (sox_size_t)sox_tell(ft)); + return SOX_SUCCESS; } SOX_FORMAT_HANDLER(sphere) { - static char const * const names[] = {"sph", "nist", NULL}; + static char const *const names[] = { "sph", "nist", NULL }; static unsigned const write_encodings[] = { - SOX_ENCODING_SIGN2, 8, 16, 24, 32, 0, - SOX_ENCODING_UNSIGNED, 8, 16, 24, 32, 0, + SOX_ENCODING_SIGN2, 16, 24, 32, 0, + SOX_ENCODING_UNSIGNED, 8, 0, SOX_ENCODING_ULAW, 8, 0, - 0}; + 0 + }; static sox_format_handler_t const handler = { SOX_LIB_VERSION_CODE, "SPeech HEader Resources; defined by NIST", - names, 0, - startread, sox_rawread, sox_rawstopread, - startwrite, write_samples, stopwrite, - NULL, write_encodings, NULL + names, SOX_FILE_REWIND, + start_read, sox_rawread, NULL, + write_header, sox_rawwrite, NULL, + sox_rawseek, write_encodings, NULL }; return &handler; } Index: sox.h =================================================================== RCS file: /cvsroot/sox/sox/src/sox.h,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- sox.h 16 Mar 2008 07:52:57 -0000 1.50 +++ sox.h 16 Mar 2008 15:13:51 -0000 1.51 @@ -336,6 +336,7 @@ FILE *fp; /* File stream pointer */ int sox_errno; /* Failure error codes */ char sox_errstr[256]; /* Extend Failure text */ + off_t tell; off_t data_start; sox_format_handler_t handler; /* format struct for this file */ }; Index: misc.c =================================================================== RCS file: /cvsroot/sox/sox/src/misc.c,v retrieving revision 1.122 retrieving revision 1.123 diff -u -d -r1.122 -r1.123 --- misc.c 16 Mar 2008 07:52:57 -0000 1.122 +++ misc.c 16 Mar 2008 15:13:51 -0000 1.123 @@ -141,19 +141,19 @@ ft->data_start = sox_tell(ft); if (channels && ft->signal.channels && ft->signal.channels != channels) - sox_warn("'%s': overriding number of channels", ft->filename); + sox_warn("`%s': overriding number of channels", ft->filename); else ft->signal.channels = channels; if (rate && ft->signal.rate && ft->signal.rate != rate) - sox_warn("'%s': overriding sample rate", ft->filename); + sox_warn("`%s': overriding sample rate", ft->filename); else ft->signal.rate = rate; if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding) - sox_warn("'%s': overriding encoding type", ft->filename); + sox_warn("`%s': overriding encoding type", ft->filename); else ft->encoding.encoding = encoding; if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample) - sox_warn("'%s': overriding encoding size", ft->filename); + sox_warn("`%s': overriding encoding size", ft->filename); ft->encoding.bits_per_sample = bits_per_sample; if (ft->encoding.bits_per_sample && sox_filelength(ft)) { @@ -161,10 +161,10 @@ if (!ft->length) ft->length = calculated_length; else if (length != calculated_length) - sox_warn("file header gives the total number of samples as %u but file length indicates the number is in fact %u", (unsigned)length, (unsigned)calculated_length); /* FIXME: casts */ + sox_warn("`%s': file header gives the total number of samples as %u but file length indicates the number is in fact %u", ft->filename, (unsigned)length, (unsigned)calculated_length); /* FIXME: casts */ } - if ( sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample)) + if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample)) return SOX_SUCCESS; sox_fail_errno(ft, EINVAL, "invalid format for this file type"); return SOX_EOF; @@ -214,6 +214,7 @@ size_t ret = fread(buf, 1, len, ft->fp); if (ret != len && ferror(ft->fp)) sox_fail_errno(ft, errno, "sox_readbuf"); + ft->tell += ret; return ret; } @@ -250,6 +251,7 @@ sox_fail_errno(ft, errno, "error writing output file"); clearerr(ft->fp); /* Allows us to seek back to write header */ } + ft->tell += ret; return ret; } @@ -268,7 +270,7 @@ sox_ssize_t sox_tell(sox_format_t * ft) { - return (sox_ssize_t)ftello(ft->fp); + return ft->seekable? (sox_ssize_t)ftello(ft->fp) : ft->tell; } int sox_eof(sox_format_t * ft) @@ -582,6 +584,7 @@ while (offset > 0 && !feof(ft->fp)) { getc(ft->fp); offset--; + ++ft->tell; } if (offset) sox_fail_errno(ft,SOX_EOF, "offset past EOF"); |