ref: 793a1f4a418744e14db3c95b3751b91decb4f557
parent: bf963ebdb03c67ec78e7a51b2164b3f6cf14575d
author: cbagwell <cbagwell>
date: Sun Aug 1 17:21:00 EDT 2004
Fix vox handler. Fix OSS rate calcs. Allow sphere headers > 265. Make vorbis comments KEY=value.
--- a/Changelog
+++ b/Changelog
@@ -26,6 +26,15 @@
machines.
o Tony Seebregts added a file handler for headerless Dialogic/OKI ADPCM
files (VOX files).
+ o Jan Paul Schmidt added a repeat effect to do loops the brute force way.
+ This is also good for file format that don't support loops as well.
+ o Fix for OSS driver in rate tolerance calcs that were off because
+ of type conversion problems. Guenter Geiger.
+ o Allow reading sphere files with headers greater then 256 bytes. Jimen
+ Ching.
+ o Fix for vorbis were comments are displayed in KEY=value format always.
+ Stop printing some info to stdout in case output is a pipe. Guenter
+ Geiger.
sox-12.17.4
-----------
--- a/src/handlers.c
+++ b/src/handlers.c
@@ -236,6 +236,11 @@
};
#endif
+static char *voxnames[] = {
+ "vox",
+ (char *) 0
+};
+
/* Microsoftt RIFF */
static char *wavnames[] = {
"wav",
@@ -376,7 +381,7 @@
st_vorbisstartwrite, st_vorbiswrite, st_vorbisstopwrite,
st_format_nothing_seek},
#endif
- {vorbisnames, 0,
+ {voxnames, 0,
st_voxstartread, st_voxread, st_voxstopread,
st_voxstartwrite, st_voxwrite, st_voxstopwrite,
st_format_nothing_seek},
--- a/src/oss.c
+++ b/src/oss.c
@@ -27,7 +27,7 @@
#include "st_i.h"
-#if defined(HAVE_OSS)
+#if defined(HAVE_OSS)
#include <unistd.h>
#include <stdlib.h>
@@ -49,34 +49,34 @@
if (ft->info.rate == 0.0) ft->info.rate = 8000;
if (ft->info.size == -1) ft->info.size = ST_SIZE_BYTE;
if (ft->info.size == ST_SIZE_BYTE) {
- sampletype = AFMT_U8;
- samplesize = 8;
- if (ft->info.encoding == -1)
- ft->info.encoding = ST_ENCODING_UNSIGNED;
- if (ft->info.encoding != ST_ENCODING_UNSIGNED) {
- st_report("OSS driver only supports unsigned with bytes");
- st_report("Forcing to unsigned");
- ft->info.encoding = ST_ENCODING_UNSIGNED;
- }
+ sampletype = AFMT_U8;
+ samplesize = 8;
+ if (ft->info.encoding == -1)
+ ft->info.encoding = ST_ENCODING_UNSIGNED;
+ if (ft->info.encoding != ST_ENCODING_UNSIGNED) {
+ st_report("OSS driver only supports unsigned with bytes");
+ st_report("Forcing to unsigned");
+ ft->info.encoding = ST_ENCODING_UNSIGNED;
+ }
}
else if (ft->info.size == ST_SIZE_WORD) {
- sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
- samplesize = 16;
- if (ft->info.encoding == -1)
- ft->info.encoding = ST_ENCODING_SIGN2;
- if (ft->info.encoding != ST_ENCODING_SIGN2) {
- st_report("OSS driver only supports signed with words");
- st_report("Forcing to signed linear");
- ft->info.encoding = ST_ENCODING_SIGN2;
- }
+ sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
+ samplesize = 16;
+ if (ft->info.encoding == -1)
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ if (ft->info.encoding != ST_ENCODING_SIGN2) {
+ st_report("OSS driver only supports signed with words");
+ st_report("Forcing to signed linear");
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ }
}
else {
- sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
- samplesize = 16;
+ sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
+ samplesize = 16;
ft->info.size = ST_SIZE_WORD;
- ft->info.encoding = ST_ENCODING_SIGN2;
- st_report("OSS driver only supports bytes and words");
- st_report("Forcing to signed linear word");
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ st_report("OSS driver only supports bytes and words");
+ st_report("Forcing to signed linear word");
}
if (ft->info.channels == -1) ft->info.channels = 1;
@@ -84,8 +84,8 @@
if (ioctl(fileno(ft->fp), SNDCTL_DSP_RESET, 0) < 0)
{
- st_fail_errno(ft,ST_EOF,"Unable to reset OSS driver. Possibly accessing an invalid file/device");
- return(ST_EOF);
+ st_fail_errno(ft,ST_EOF,"Unable to reset OSS driver. Possibly accessing an invalid file/device");
+ return(ST_EOF);
}
/* Query the supported formats and find the best match
@@ -92,47 +92,47 @@
*/
rc = ioctl(fileno(ft->fp), SNDCTL_DSP_GETFMTS, &tmp);
if (rc == 0) {
- if ((tmp & sampletype) == 0)
- {
- /* is 16-bit supported? */
- if (samplesize == 16 && (tmp & (AFMT_S16_LE|AFMT_S16_BE)) == 0)
- {
- /* Must not like 16-bits, try 8-bits */
- ft->info.size = ST_SIZE_BYTE;
- ft->info.encoding = ST_ENCODING_UNSIGNED;
- st_report("OSS driver doesn't like signed words");
- st_report("Forcing to unsigned bytes");
- tmp = sampletype = AFMT_U8;
- samplesize = 8;
- }
- /* is 8-bit supported */
- else if (samplesize == 8 && (tmp & AFMT_U8) == 0)
- {
- ft->info.size = ST_SIZE_WORD;
- ft->info.encoding = ST_ENCODING_SIGN2;
- st_report("OSS driver doesn't like unsigned bytes");
- st_report("Forcing to signed words");
- sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
- samplesize = 16;
- }
- /* determine which 16-bit format to use */
- if (samplesize == 16)
- {
- if ((tmp & sampletype) == 0)
- {
- sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_LE : AFMT_S16_BE;
- ft->swap = ft->swap ? 0 : 1;
- }
- }
- }
- tmp = sampletype;
- rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SETFMT, &tmp);
+ if ((tmp & sampletype) == 0)
+ {
+ /* is 16-bit supported? */
+ if (samplesize == 16 && (tmp & (AFMT_S16_LE|AFMT_S16_BE)) == 0)
+ {
+ /* Must not like 16-bits, try 8-bits */
+ ft->info.size = ST_SIZE_BYTE;
+ ft->info.encoding = ST_ENCODING_UNSIGNED;
+ st_report("OSS driver doesn't like signed words");
+ st_report("Forcing to unsigned bytes");
+ tmp = sampletype = AFMT_U8;
+ samplesize = 8;
+ }
+ /* is 8-bit supported */
+ else if (samplesize == 8 && (tmp & AFMT_U8) == 0)
+ {
+ ft->info.size = ST_SIZE_WORD;
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ st_report("OSS driver doesn't like unsigned bytes");
+ st_report("Forcing to signed words");
+ sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
+ samplesize = 16;
+ }
+ /* determine which 16-bit format to use */
+ if (samplesize == 16)
+ {
+ if ((tmp & sampletype) == 0)
+ {
+ sampletype = (ST_IS_BIGENDIAN) ? AFMT_S16_LE : AFMT_S16_BE;
+ ft->swap = ft->swap ? 0 : 1;
+ }
+ }
+ }
+ tmp = sampletype;
+ rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SETFMT, &tmp);
}
/* Give up and exit */
if (rc < 0 || tmp != sampletype)
{
- st_fail_errno(ft,ST_EOF,"Unable to set the sample size to %d", samplesize);
- return (ST_EOF);
+ st_fail_errno(ft,ST_EOF,"Unable to set the sample size to %d", samplesize);
+ return (ST_EOF);
}
if (ft->info.channels == 2) dsp_stereo = 1;
@@ -141,33 +141,33 @@
tmp = dsp_stereo;
if (ioctl(fileno(ft->fp), SNDCTL_DSP_STEREO, &tmp) < 0)
{
- st_warn("Couldn't set to %s", dsp_stereo? "stereo":"mono");
- dsp_stereo = 0;
+ st_warn("Couldn't set to %s", dsp_stereo? "stereo":"mono");
+ dsp_stereo = 0;
}
if (tmp != dsp_stereo)
{
- st_warn("Sound card appears to only support %d channels. Overriding format\n", tmp+1);
- ft->info.channels = tmp + 1;
+ st_warn("Sound card appears to only support %d channels. Overriding format\n", tmp+1);
+ ft->info.channels = tmp + 1;
}
tmp = ft->info.rate;
if (ioctl (fileno(ft->fp), SNDCTL_DSP_SPEED, &tmp) < 0 ||
- ft->info.rate != tmp) {
- /* If the rate the sound card is using is not within 1% of what
- * the user specified then override the user setting.
- * The only reason not to always override this is because of
- * clock-rounding problems. Sound cards will sometimes use
- * things like 44101 when you ask for 44100. No need overriding
- * this and having strange output file rates for something that
- * we can't hear anyways.
- */
- if (ft->info.rate - tmp > (tmp * .01) ||
- tmp - ft->info.rate > (tmp * .01)) {
- st_warn("Unable to set audio speed to %d (set to %d)",
- ft->info.rate, tmp);
- ft->info.rate = tmp;
- }
+ ft->info.rate != tmp) {
+ /* If the rate the sound card is using is not within 1% of what
+ * the user specified then override the user setting.
+ * The only reason not to always override this is because of
+ * clock-rounding problems. Sound cards will sometimes use
+ * things like 44101 when you ask for 44100. No need overriding
+ * this and having strange output file rates for something that
+ * we can't hear anyways.
+ */
+ if ((int)ft->info.rate - tmp > (tmp * .01) ||
+ tmp - (int)ft->info.rate > (tmp * .01)) {
+ st_warn("Unable to set audio speed to %d (set to %d)",
+ ft->info.rate, tmp);
+ ft->info.rate = tmp;
+ }
}
/* Find out block size to use last because the driver could compute
@@ -176,8 +176,8 @@
ft->file.size = 0;
ioctl (fileno(ft->fp), SNDCTL_DSP_GETBLKSIZE, &ft->file.size);
if (ft->file.size < 4 || ft->file.size > 65536) {
- st_fail_errno(ft,ST_EOF,"Invalid audio buffer size %d", ft->file.size);
- return (ST_EOF);
+ st_fail_errno(ft,ST_EOF,"Invalid audio buffer size %d", ft->file.size);
+ return (ST_EOF);
}
ft->file.count = 0;
ft->file.pos = 0;
@@ -184,13 +184,13 @@
ft->file.eof = 0;
if ((ft->file.buf = malloc (ft->file.size)) == NULL) {
- st_fail_errno(ft,ST_EOF,"Unable to allocate input/output buffer of size %d", ft->file.size);
- return (ST_EOF);
+ st_fail_errno(ft,ST_EOF,"Unable to allocate input/output buffer of size %d", ft->file.size);
+ return (ST_EOF);
}
if (ioctl(fileno(ft->fp), SNDCTL_DSP_SYNC, NULL) < 0) {
- st_fail_errno(ft,ST_EOF,"Unable to sync dsp");
- return (ST_EOF);
+ st_fail_errno(ft,ST_EOF,"Unable to sync dsp");
+ return (ST_EOF);
}
/* Change to non-buffered I/O */
@@ -200,15 +200,15 @@
/*
* Do anything required before you start reading samples.
* Read file header.
- * Find out sampling rate,
- * size and encoding of samples,
- * mono/stereo/quad.
+ * Find out sampling rate,
+ * size and encoding of samples,
+ * mono/stereo/quad.
*/
int st_ossdspstartread(ft_t ft)
{
int rc;
rc = ossdspinit(ft);
- sigintreg(ft); /* Prepare to catch SIGINT */
+ sigintreg(ft); /* Prepare to catch SIGINT */
return rc;
}
--- a/src/sphere.c
+++ b/src/sphere.c
@@ -33,12 +33,12 @@
{
sphere_t sphere = (sphere_t) ft->priv;
int rc;
- char buf[256];
+ char *buf;
char fldname[64], fldtype[16], fldsval[128];
int i;
int header_size, bytes_read;
long rate;
-
+
/* Needed for rawread() */
rc = st_rawstartread(ft);
if (rc)
@@ -45,7 +45,7 @@
return rc;
/* Magic header */
- if (st_reads(ft, buf, 8) == ST_EOF || strncmp(buf, "NIST_1A", 7) != 0)
+ if (st_reads(ft, fldname, 8) == ST_EOF || strncmp(fldname, "NIST_1A", 7) != 0)
{
st_fail_errno(ft,ST_EHDR,"Sphere header does not begin with magic mord 'NIST_1A'");
return(ST_EOF);
@@ -57,14 +57,22 @@
return(ST_EOF);
}
+ /* Determine header size, and allocate a buffer large enough to hold it. */
sscanf(fldsval, "%d", &header_size);
+ buf = (char *)malloc(header_size);
+ if (buf == NULL)
+ {
+ st_fail_errno(ft,ST_ENOMEM,"Unable to allocate memory");
+ return(ST_ENOMEM);
+ }
/* Skip what we have read so far */
header_size -= 16;
- if (st_reads(ft, buf, 255) == ST_EOF)
+ if (st_reads(ft, buf, header_size) == ST_EOF)
{
st_fail_errno(ft,ST_EHDR,"Error reading Sphere header");
+ free(buf);
return(ST_EOF);
}
@@ -122,9 +130,10 @@
}
}
- if (st_reads(ft, buf, 255) == ST_EOF)
+ if (st_reads(ft, buf, header_size) == ST_EOF)
{
st_fail_errno(ft,ST_EHDR,"Error reading Sphere header");
+ free(buf);
return(ST_EOF);
}
@@ -148,9 +157,10 @@
while (header_size)
{
- bytes_read = st_read(ft, buf, ST_SIZE_BYTE, (header_size > 256) ? 256 : header_size);
+ bytes_read = st_read(ft, buf, ST_SIZE_BYTE, header_size);
if (bytes_read == 0)
{
+ free(buf);
return(ST_EOF);
}
header_size -= bytes_read;
@@ -168,10 +178,12 @@
if (!strcmp(sphere->shorten_check,"ajkg"))
{
st_fail_errno(ft,ST_EFMT,"File uses shorten compression, can not handle this.\n");
+ free(buf);
return(ST_EOF);
}
#endif
+ free(buf);
return (ST_SUCCESS);
}
--- a/src/vorbis.c
+++ b/src/vorbis.c
@@ -15,6 +15,9 @@
* any purpose. This copyright notice must be maintained.
* Lance Norskog And Sundry Contributors are not responsible for
* the consequences of using this software.
+ *
+ * TODO: When reading in comments, it doesn't understand how to read
+ * more then one comment and doesn't know how to parse KEY=value.
*/
#include "st_i.h"
@@ -39,33 +42,33 @@
/* Private data for Ogg Vorbis file */
typedef struct vorbis_enc {
- ogg_stream_state os;
- ogg_page og;
- ogg_packet op;
-
- vorbis_dsp_state vd;
- vorbis_block vb;
+ ogg_stream_state os;
+ ogg_page og;
+ ogg_packet op;
+
+ vorbis_dsp_state vd;
+ vorbis_block vb;
vorbis_info vi;
} vorbis_enc_t;
typedef struct vorbisstuff {
/* Decoding data */
- OggVorbis_File *vf;
- char *buf;
- int buf_len;
- int start;
- int end; /* Unsent data samples in buf[start] through buf[end-1] */
- int current_section;
- int eof;
+ OggVorbis_File *vf;
+ char *buf;
+ int buf_len;
+ int start;
+ int end; /* Unsent data samples in buf[start] through buf[end-1] */
+ int current_section;
+ int eof;
- vorbis_enc_t *vorbis_enc_data;
+ vorbis_enc_t *vorbis_enc_data;
} *vorbis_t;
/******** Callback functions used in ov_open_callbacks ************/
int myclose (void *datasource)
{
- /* Do nothing so sox can close the file for us */
- return 0;
+ /* Do nothing so sox can close the file for us */
+ return 0;
}
/* Taken from vorbisfile.c in libvorbis source code */
@@ -80,105 +83,105 @@
/*
* Do anything required before you start reading samples.
* Read file header.
- * Find out sampling rate,
- * size and encoding of samples,
- * mono/stereo/quad.
+ * Find out sampling rate,
+ * size and encoding of samples,
+ * mono/stereo/quad.
*/
int st_vorbisstartread(ft_t ft)
{
- vorbis_t vb = (vorbis_t) ft->priv;
- vorbis_info *vi;
- vorbis_comment *vc;
- int comment_size;
- int i, offset;
+ vorbis_t vb = (vorbis_t) ft->priv;
+ vorbis_info *vi;
+ vorbis_comment *vc;
+ int comment_size;
+ int i, offset;
- ov_callbacks callbacks = {
- (size_t (*)(void *, size_t, size_t, void *)) fread,
- (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
- (int (*)(void *)) myclose,
- (long (*)(void *)) ftell
- };
+ ov_callbacks callbacks = {
+ (size_t (*)(void *, size_t, size_t, void *)) fread,
+ (int (*)(void *, ogg_int64_t, int)) _fseek64_wrap,
+ (int (*)(void *)) myclose,
+ (long (*)(void *)) ftell
+ };
-
-
- /* Allocate space for decoding structure */
- vb->vf = malloc(sizeof(OggVorbis_File));
- if (vb->vf == NULL)
- {
- st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
- return (ST_EOF);
- }
+
+
+ /* Allocate space for decoding structure */
+ vb->vf = malloc(sizeof(OggVorbis_File));
+ if (vb->vf == NULL)
+ {
+ st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+ return (ST_EOF);
+ }
- /* Init the decoder */
- if (ov_open_callbacks((void *)ft->fp,vb->vf,NULL,0,callbacks) < 0)
- {
- st_fail_errno(ft,ST_EHDR,
- "Input not an Ogg Vorbis audio stream");
- return (ST_EOF);
- }
+ /* Init the decoder */
+ if (ov_open_callbacks((void *)ft->fp,vb->vf,NULL,0,callbacks) < 0)
+ {
+ st_fail_errno(ft,ST_EHDR,
+ "Input not an Ogg Vorbis audio stream");
+ return (ST_EOF);
+ }
- /* Get info about the Ogg Vorbis stream */
- vi = ov_info(vb->vf, -1);
- vc = ov_comment(vb->vf, -1);
+ /* Get info about the Ogg Vorbis stream */
+ vi = ov_info(vb->vf, -1);
+ vc = ov_comment(vb->vf, -1);
- /* Record audio info */
- ft->info.rate = vi->rate;
- ft->info.size = ST_SIZE_16BIT;
- ft->info.encoding = ST_ENCODING_SIGN2;
- ft->info.channels = vi->channels;
-
- /* Record comments */
- if (vc->comments == 0)
- ft->comment = NULL;
- else
- {
- comment_size = 0;
+ /* Record audio info */
+ ft->info.rate = vi->rate;
+ ft->info.size = ST_SIZE_16BIT;
+ ft->info.encoding = ST_ENCODING_SIGN2;
+ ft->info.channels = vi->channels;
+
+ /* Record comments */
+ if (vc->comments == 0)
+ ft->comment = NULL;
+ else
+ {
+ comment_size = 0;
- for (i = 0; i < vc->comments; i++)
- comment_size += vc->comment_lengths[i] + 1;
+ for (i = 0; i < vc->comments; i++)
+ comment_size += vc->comment_lengths[i] + 1;
- if ( (ft->comment = calloc(comment_size, sizeof(char)))
- == NULL)
- {
- ov_clear(vb->vf);
- free(vb->vf);
+ if ( (ft->comment = calloc(comment_size, sizeof(char)))
+ == NULL)
+ {
+ ov_clear(vb->vf);
+ free(vb->vf);
- st_fail_errno(ft, ST_ENOMEM,
- "Could not allocate memory");
- return (ST_EOF);
- }
-
- offset = 0;
- for (i = 0; i < vc->comments; i++)
- {
- strncpy(ft->comment + offset, vc->user_comments[i],
- vc->comment_lengths[i]);
- offset += vc->comment_lengths[i];
- ft->comment[offset] = '\n';
- offset++;
- }
- /* On last comment, end string by overwriting last \n */
- if (offset > 0)
- offset--;
- ft->comment[offset] = 0;
- }
-
- /* Setup buffer */
- vb->buf_len = DEF_BUF_LEN;
- if ( (vb->buf = calloc(vb->buf_len, sizeof(char))) == NULL )
- {
- ov_clear(vb->vf);
- free(vb->vf);
- st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
- return (ST_EOF);
- }
- vb->start = vb->end = 0;
+ st_fail_errno(ft, ST_ENOMEM,
+ "Could not allocate memory");
+ return (ST_EOF);
+ }
+
+ offset = 0;
+ for (i = 0; i < vc->comments; i++)
+ {
+ strncpy(ft->comment + offset, vc->user_comments[i],
+ vc->comment_lengths[i]);
+ offset += vc->comment_lengths[i];
+ ft->comment[offset] = '\n';
+ offset++;
+ }
+ /* On last comment, end string by overwriting last \n */
+ if (offset > 0)
+ offset--;
+ ft->comment[offset] = 0;
+ }
- /* Fill in other info */
- vb->eof = 0;
- vb->current_section = -1;
+ /* Setup buffer */
+ vb->buf_len = DEF_BUF_LEN;
+ if ( (vb->buf = calloc(vb->buf_len, sizeof(char))) == NULL )
+ {
+ ov_clear(vb->vf);
+ free(vb->vf);
+ st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+ return (ST_EOF);
+ }
+ vb->start = vb->end = 0;
- return (ST_SUCCESS);
+ /* Fill in other info */
+ vb->eof = 0;
+ vb->current_section = -1;
+
+ return (ST_SUCCESS);
}
@@ -187,29 +190,29 @@
BUF_ERROR is something bad happens, and BUF_DATA otherwise */
int refill_buffer (vorbis_t vb)
{
- int num_read;
+ int num_read;
- if (vb->start == vb->end) /* Samples all played */
- vb->start = vb->end = 0;
+ if (vb->start == vb->end) /* Samples all played */
+ vb->start = vb->end = 0;
- while (vb->end < vb->buf_len)
- {
- num_read = ov_read(vb->vf, vb->buf + vb->end,
- vb->buf_len - vb->end, 0, 2, 1,
- &vb->current_section);
-
- if (num_read == 0)
- return (BUF_EOF);
- else if (num_read == OV_HOLE)
- fprintf(stderr, "Warning: hole in stream; probably harmless\n");
- else if (num_read < 0)
- return (BUF_ERROR);
- else
- vb->end += num_read;
-
- }
-
- return (BUF_DATA);
+ while (vb->end < vb->buf_len)
+ {
+ num_read = ov_read(vb->vf, vb->buf + vb->end,
+ vb->buf_len - vb->end, 0, 2, 1,
+ &vb->current_section);
+
+ if (num_read == 0)
+ return (BUF_EOF);
+ else if (num_read == OV_HOLE)
+ st_warn("Warning: hole in stream; probably harmless\n");
+ else if (num_read < 0)
+ return (BUF_ERROR);
+ else
+ vb->end += num_read;
+
+ }
+
+ return (BUF_DATA);
}
@@ -222,33 +225,33 @@
st_ssize_t st_vorbisread(ft_t ft, st_sample_t *buf, st_ssize_t len)
{
- vorbis_t vb = (vorbis_t) ft->priv;
- int i;
- int ret;
- st_sample_t l;
+ vorbis_t vb = (vorbis_t) ft->priv;
+ int i;
+ int ret;
+ st_sample_t l;
- for(i = 0; i < len; i++) {
- if (vb->start == vb->end)
- {
- if (vb->eof)
- break;
- ret = refill_buffer(vb);
- if (ret == BUF_EOF || ret == BUF_ERROR)
- {
- vb->eof = 1;
- if (vb->end == 0)
- break;
- }
- }
+ for(i = 0; i < len; i++) {
+ if (vb->start == vb->end)
+ {
+ if (vb->eof)
+ break;
+ ret = refill_buffer(vb);
+ if (ret == BUF_EOF || ret == BUF_ERROR)
+ {
+ vb->eof = 1;
+ if (vb->end == 0)
+ break;
+ }
+ }
- l = (vb->buf[vb->start+1]<<24)
- | (0xffffff & (vb->buf[vb->start]<<16));
- *(buf + i) = l;
- vb->start += 2;
- }
+ l = (vb->buf[vb->start+1]<<24)
+ | (0xffffff & (vb->buf[vb->start]<<16));
+ *(buf + i) = l;
+ vb->start += 2;
+ }
- return i;
+ return i;
}
/*
@@ -257,12 +260,12 @@
*/
int st_vorbisstopread(ft_t ft)
{
- vorbis_t vb = (vorbis_t) ft->priv;
+ vorbis_t vb = (vorbis_t) ft->priv;
- free(vb->buf);
- ov_clear(vb->vf);
+ free(vb->buf);
+ ov_clear(vb->vf);
- return (ST_SUCCESS);
+ return (ST_SUCCESS);
}
/* Write a page of ogg data to a file. Taken directly from encode.c in
@@ -281,154 +284,167 @@
HEADER_OK otherwise. */
int write_vorbis_header(ft_t ft, vorbis_enc_t *ve)
{
- ogg_packet header_main;
- ogg_packet header_comments;
- ogg_packet header_codebooks;
- vorbis_comment vc;
- int result;
- int ret;
+ ogg_packet header_main;
+ ogg_packet header_comments;
+ ogg_packet header_codebooks;
+ vorbis_comment vc;
+ int result;
+ int ret;
+ char *comment;
- /* Make the comment structure */
- vc.user_comments = calloc(1, sizeof(char *));
- vc.comment_lengths = calloc(1, sizeof(int));
- vc.comments = 1;
+ /* Make the comment structure */
+ vc.user_comments = calloc(1, sizeof(char *));
+ vc.comment_lengths = calloc(1, sizeof(int));
+ vc.comments = 1;
- vc.user_comments[0] = ft->comment;
- vc.comment_lengths[0] = strlen(ft->comment);
+ /* We check if there is a FIELD=value pair already in the comment
+ * if not, add one */
+ if (strchr(ft->comment,'=') == NULL)
+ {
+ comment = calloc(1,strlen(ft->comment)+strlen("COMMENT=")+1);
+ strncpy(comment,"COMMENT=",strlen("COMMENT="));
+ }
+ else
+ comment = calloc(1,strlen(ft->comment)+1);
- /* Build the packets */
- vorbis_analysis_headerout(&ve->vd,&vc,
- &header_main,
- &header_comments,
- &header_codebooks);
-
- /* And stream them out */
- ogg_stream_packetin(&ve->os,&header_main);
- ogg_stream_packetin(&ve->os,&header_comments);
- ogg_stream_packetin(&ve->os,&header_codebooks);
-
- while((result = ogg_stream_flush(&ve->os, &ve->og)))
- {
- if(!result) break;
- ret = oe_write_page(&ve->og, ft->fp);
- if(!ret)
- {
- return HEADER_ERROR;
- }
- }
+ strcat(comment,ft->comment);
- return HEADER_OK;
-}
+ vc.user_comments[0] = comment;
+ vc.comment_lengths[0] = strlen(comment);
+
+ /* Build the packets */
+ vorbis_analysis_headerout(&ve->vd,&vc,
+ &header_main,
+ &header_comments,
+ &header_codebooks);
+
+ /* And stream them out */
+ ogg_stream_packetin(&ve->os,&header_main);
+ ogg_stream_packetin(&ve->os,&header_comments);
+ ogg_stream_packetin(&ve->os,&header_codebooks);
+
+ while((result = ogg_stream_flush(&ve->os, &ve->og)))
+ {
+ if(!result) break;
+ ret = oe_write_page(&ve->og, ft->fp);
+ if(!ret)
+ {
+ free(comment);
+ return HEADER_ERROR;
+ }
+ }
+ free(comment);
+ return HEADER_OK;
+}
+
int st_vorbisstartwrite(ft_t ft)
{
- vorbis_t vb = (vorbis_t) ft->priv;
- vorbis_enc_t *ve;
- long rate;
+ vorbis_t vb = (vorbis_t) ft->priv;
+ vorbis_enc_t *ve;
+ long rate;
- /* Allocate memory for all of the structures */
- ve = vb->vorbis_enc_data = malloc(sizeof(vorbis_enc_t));
- if (ve == NULL)
- {
- st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
- return (ST_EOF);
- }
+ /* Allocate memory for all of the structures */
+ ve = vb->vorbis_enc_data = malloc(sizeof(vorbis_enc_t));
+ if (ve == NULL)
+ {
+ st_fail_errno(ft, ST_ENOMEM, "Could not allocate memory");
+ return (ST_EOF);
+ }
- vorbis_info_init(&ve->vi);
+ vorbis_info_init(&ve->vi);
- /* DEBUG */
- rate = ft->info.rate;
- fprintf(stdout, "Channels: %d Rate: %ld\n", ft->info.channels,
- rate);
+ /* DEBUG */
+ rate = ft->info.rate;
- if (rate)
- {
- st_fail_errno(ft, ST_EHDR, "Error setting up Ogg Vorbis encorder - make sure you've specied a sane rate and number of channels");
- }
+ if (rate)
+ {
+ st_fail_errno(ft, ST_EHDR, "Error setting up Ogg Vorbis encorder - make sure you've specied a sane rate and number of channels");
+ }
- /* Set encoding to average bit rate of 112kbps VBR */
- vorbis_encode_init_vbr(&ve->vi, ft->info.channels, ft->info.rate, 0.3f);
+ /* Set encoding to average bit rate of 112kbps VBR */
+ vorbis_encode_init_vbr(&ve->vi, ft->info.channels, ft->info.rate, 0.3f);
- vorbis_analysis_init(&ve->vd, &ve->vi);
- vorbis_block_init(&ve->vd, &ve->vb);
-
- ogg_stream_init(&ve->os, rand()); /* Random serial number */
-
- if (write_vorbis_header(ft, ve) == HEADER_ERROR)
- {
- st_fail_errno(ft,ST_EHDR,
- "Error writing headre for Ogg Vorbis audio stream");
- return (ST_EOF);
- }
-
- return(ST_SUCCESS);
+ vorbis_analysis_init(&ve->vd, &ve->vi);
+ vorbis_block_init(&ve->vd, &ve->vb);
+
+ ogg_stream_init(&ve->os, rand()); /* Random serial number */
+
+ if (write_vorbis_header(ft, ve) == HEADER_ERROR)
+ {
+ st_fail_errno(ft,ST_EHDR,
+ "Error writing headre for Ogg Vorbis audio stream");
+ return (ST_EOF);
+ }
+
+ return(ST_SUCCESS);
}
st_ssize_t st_vorbiswrite(ft_t ft, st_sample_t *buf, st_ssize_t len)
{
- vorbis_t vb = (vorbis_t) ft->priv;
- vorbis_enc_t *ve = vb->vorbis_enc_data;
- st_ssize_t samples = len / ft->info.channels;
- float **buffer = vorbis_analysis_buffer(&ve->vd, samples);
- st_ssize_t i, j;
- int ret;
- int eos = 0;
+ vorbis_t vb = (vorbis_t) ft->priv;
+ vorbis_enc_t *ve = vb->vorbis_enc_data;
+ st_ssize_t samples = len / ft->info.channels;
+ float **buffer = vorbis_analysis_buffer(&ve->vd, samples);
+ st_ssize_t i, j;
+ int ret;
+ int eos = 0;
- /* Copy samples into vorbis buffer */
- for (i = 0; i < samples; i++)
- for (j = 0; j < ft->info.channels; j++)
- buffer[j][i] = buf[i*ft->info.channels + j]
- / 2147483648.0f;
+ /* Copy samples into vorbis buffer */
+ for (i = 0; i < samples; i++)
+ for (j = 0; j < ft->info.channels; j++)
+ buffer[j][i] = buf[i*ft->info.channels + j]
+ / 2147483648.0f;
- vorbis_analysis_wrote(&ve->vd, samples);
-
- while(vorbis_analysis_blockout(&ve->vd,&ve->vb)==1)
- {
- /* Do the main analysis, creating a packet */
- vorbis_analysis(&ve->vb, &ve->op);
- vorbis_bitrate_addblock(&ve->vb);
+ vorbis_analysis_wrote(&ve->vd, samples);
+
+ while(vorbis_analysis_blockout(&ve->vd,&ve->vb)==1)
+ {
+ /* Do the main analysis, creating a packet */
+ vorbis_analysis(&ve->vb, &ve->op);
+ vorbis_bitrate_addblock(&ve->vb);
- /* Add packet to bitstream */
- while (vorbis_bitrate_flushpacket(&ve->vd, &ve->op))
- {
- ogg_stream_packetin(&ve->os,&ve->op);
-
- /* If we've gone over a page boundary, we can do actual
- * output, so do so (for however many pages are available)
- */
-
- while(!eos)
- {
- int result = ogg_stream_pageout(&ve->os,&ve->og);
- if(!result) break;
-
- ret = oe_write_page(&ve->og, ft->fp);
- if(!ret)
- return (ST_EOF);
-
- if(ogg_page_eos(&ve->og))
- eos = 1;
- }
- }
- }
-
- return (ST_SUCCESS);
-}
+ /* Add packet to bitstream */
+ while (vorbis_bitrate_flushpacket(&ve->vd, &ve->op))
+ {
+ ogg_stream_packetin(&ve->os,&ve->op);
+
+ /* If we've gone over a page boundary, we can do actual
+ * output, so do so (for however many pages are available)
+ */
+
+ while(!eos)
+ {
+ int result = ogg_stream_pageout(&ve->os,&ve->og);
+ if(!result) break;
+
+ ret = oe_write_page(&ve->og, ft->fp);
+ if(!ret)
+ return (ST_EOF);
+
+ if(ogg_page_eos(&ve->og))
+ eos = 1;
+ }
+ }
+ }
+ return (ST_SUCCESS);
+}
+
int st_vorbisstopwrite(ft_t ft)
{
- vorbis_t vb = (vorbis_t) ft->priv;
- vorbis_enc_t *ve = vb->vorbis_enc_data;
+ vorbis_t vb = (vorbis_t) ft->priv;
+ vorbis_enc_t *ve = vb->vorbis_enc_data;
- /* Close out the remaining data */
- st_vorbiswrite(ft, NULL, 0);
+ /* Close out the remaining data */
+ st_vorbiswrite(ft, NULL, 0);
- ogg_stream_clear(&ve->os);
- vorbis_block_clear(&ve->vb);
- vorbis_dsp_clear(&ve->vd);
- vorbis_info_clear(&ve->vi);
+ ogg_stream_clear(&ve->os);
+ vorbis_block_clear(&ve->vb);
+ vorbis_dsp_clear(&ve->vd);
+ vorbis_info_clear(&ve->vi);
- return (ST_SUCCESS);
+ return (ST_SUCCESS);
}
#endif /* HAVE_LIBVORBIS */