[xiph-cvs] cvs commit: vorbis-tools/ogg123 buffer.c buffer.h curl_interface.c curl_interface.h ogg123.c ogg123.h options.c status.c status.h
Kenneth C. Arnold
kcarnold at xiph.org
Sun Aug 12 17:43:22 PDT 2001
kcarnold 01/08/12 17:43:22
Modified: ogg123 Tag: kcarnold_work buffer.c buffer.h
curl_interface.c curl_interface.h ogg123.c ogg123.h
options.c status.c status.h
Log:
Status interface hooked up. Better definition of EOS. Reader can now
explicitly say it's quitting without WaitForEmpty. Deadlock fixes, bug
fixes, moved Options struct global, output buffer interface rework,
status now reflects output rather than decode, etc.
Should be mainline-ready very soon. Test this please.
Revision Changes Path
No revision
No revision
1.7.2.12 +58 -16 vorbis-tools/ogg123/buffer.c
Index: buffer.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/buffer.c,v
retrieving revision 1.7.2.11
retrieving revision 1.7.2.12
diff -u -r1.7.2.11 -r1.7.2.12
--- buffer.c 2001/08/12 03:59:31 1.7.2.11
+++ buffer.c 2001/08/13 00:43:20 1.7.2.12
@@ -11,7 +11,7 @@
* *
********************************************************************
- last mod: $Id: buffer.c,v 1.7.2.11 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: buffer.c,v 1.7.2.12 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -101,7 +101,7 @@
volatile buf_t *vbuf = (volatile buf_t*) buf; /* optimizers... grr */
size_t WriteThisTime = 0;
chunk *NewWriterPtr;
- char iseos = 0;
+ char EOSApplies = 0, tmpEOS;
DEBUG0("BufferFunc");
sigfillset (&set);
@@ -119,11 +119,8 @@
while (1)
{
- /* don't touch the size unless we ask you to. */
- LOCK_MUTEX (buf->SizeMutex);
-
- /* paused? Remember to signal DataReady when unpaused. */
checkPlaying:
+ LOCK_MUTEX (buf->SizeMutex);
while (!(buf->StatMask & STAT_PLAYING) ||
(buf->StatMask & STAT_PREBUFFERING)) {
DEBUG1 ("waiting on !playing || prebuffering (stat=%d)", buf->StatMask);
@@ -162,12 +159,18 @@
Prebuffer (buf);
if (buf->FlushPending)
goto flushing;
+ UNLOCK_MUTEX (buf->SizeMutex);
+ if (!buf->ReaderActive) {
+ /* if we never reported EOS to the output, now or never... */
+ buf->write_func (buf->writer, 0, 0, buf->data, 1);
+ pthread_exit (NULL);
+ }
DEBUG0 ("waiting on data ready");
pthread_cond_wait (&buf->DataReadyCondition, &buf->SizeMutex);
goto checkPlaying;
}
- iseos = 0;
+ EOSApplies = 0;
if (buf->reader < buf->writer)
{
@@ -185,7 +188,7 @@
NewWriterPtr = buf->buffer;
WriteThisTime = buf->end - buf->writer + 1;
if (buf->reader == buf->buffer)
- iseos = buf->eos;
+ EOSApplies = 1;
}
}
else
@@ -202,16 +205,18 @@
WriteThisTime = buf->OptimalWriteSize;
else {
WriteThisTime = buf->reader - buf->writer;
- iseos = buf->eos;
+ EOSApplies = 1;
}
NewWriterPtr = buf->writer + WriteThisTime;
}
+ tmpEOS = EOSApplies && buf->eos ;
+
DEBUG0("writing chunk to output");
/* unlock while playing sample */
UNLOCK_MUTEX (buf->SizeMutex);
DEBUG1("WriteThisTime=%d", WriteThisTime);
- buf->write_func (buf->writer, WriteThisTime, 1, buf->data, iseos);
+ buf->write_func (buf->writer, WriteThisTime, 1, buf->data, tmpEOS);
DEBUG0("incrementing pointer");
LOCK_MUTEX (buf->SizeMutex);
@@ -224,17 +229,33 @@
UNLOCK_MUTEX (buf->SizeMutex);
pthread_cond_broadcast (&buf->DataReadyCondition);
pthread_cond_broadcast (&buf->UnderflowCondition);
+ LOCK_MUTEX (buf->SizeMutex);
}
else
{
buf->writer = NewWriterPtr;
vbuf->curfill -= WriteThisTime;
- UNLOCK_MUTEX (buf->SizeMutex);
}
+ if (EOSApplies) {
+ if (tmpEOS != buf->eos) {
+ /* EOS was signalled while we were playing, so that sample
+ * didn't get EOS set. Call write_func with no data, just
+ * the right EOS flag. write_func is called here with the
+ * locked; it better not take too long if size == nmemb == 0. */
+ tmpEOS = buf->eos;
+ buf->write_func (buf->writer, 0, 0, buf->data, tmpEOS);
+ }
+ }
+
+ if (tmpEOS)
+ buf->eos = 0;
+
+ UNLOCK_MUTEX (buf->SizeMutex);
+
/* slight abuse of the DataReady condition, but makes sense. */
DEBUG0 ("signalling buffer no longer full");
- if (buf->curfill + WriteThisTime + buf->OptimalWriteSize >= buf->size)
+ if (buf->curfill + WriteThisTime + buf->OptimalWriteSize >= buf->size || tmpEOS)
pthread_cond_signal (&buf->DataReadyCondition);
}
/* should never get here */
@@ -278,6 +299,7 @@
buf->prebuffer = prebuffer;
Prebuffer (buf);
buf->StatMask |= STAT_PLAYING;
+ buf->ReaderActive = buf->WriterActive = 1;
/* pthreads initialization */
pthread_mutex_init (&buf->SizeMutex, NULL);
@@ -298,8 +320,8 @@
PrevSize = buf->curfill;
DUMP_BUFFER_INFO(buf);
- /* wait on buffer overflow */
- while (buf->curfill + size > buf->size) {
+ /* wait on buffer overflow or ack for eos */
+ while (buf->curfill + size > buf->size || buf->eos) {
UnPrebuffer (buf);
pthread_cond_wait (&buf->DataReadyCondition, &buf->SizeMutex);
}
@@ -357,7 +379,7 @@
{
DEBUG0("flush buffer");
buf->FlushPending = 1;
- if (!buf->BufferThread)
+ if (!buf->BufferThread || buf->StatMask & STAT_INACTIVE)
buf->curfill = 0;
DEBUG0("flush buffer done");
}
@@ -376,7 +398,13 @@
DEBUG0("done waiting");
UNLOCK_MUTEX (buf->SizeMutex);
DEBUG0("buffer empty");
- Prebuffer (buf);
+ if (!buf->ReaderActive) {
+ pthread_join (buf->BufferThread, NULL);
+ buf->BufferThread = 0;
+ buf->StatMask |= STAT_INACTIVE;
+ }
+ else
+ Prebuffer (buf);
}
long buffer_full (buf_t* buf) {
@@ -405,11 +433,24 @@
void buffer_MarkEOS (buf_t *buf)
{
+ /* lock the mutex here so the writer can have some knowledge of when
+ * the marker is set */
+ LOCK_MUTEX (buf->SizeMutex);
buf->eos = 1;
+ UNLOCK_MUTEX (buf->SizeMutex);
UnPrebuffer (buf);
pthread_cond_signal (&buf->DataReadyCondition);
}
+/* Inform the writer that the reader is quitting and it won't get any
+ * more data, ever. */
+void buffer_ReaderQuit (buf_t *buf)
+{
+ UnPrebuffer (buf);
+ buf->ReaderActive = 0;
+ SignalAll (buf);
+}
+
void buffer_shutdown (buf_t *buf)
{
DEBUG0("shutdown buffer");
@@ -418,6 +459,7 @@
pthread_cancel (buf->BufferThread);
pthread_join (buf->BufferThread, NULL);
buf->BufferThread = 0;
+ buf->StatMask |= STAT_INACTIVE;
}
DEBUG0("buffer done.");
}
1.2.2.12 +5 -2 vorbis-tools/ogg123/buffer.h
Index: buffer.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/buffer.h,v
retrieving revision 1.2.2.11
retrieving revision 1.2.2.12
diff -u -r1.2.2.11 -r1.2.2.12
--- buffer.h 2001/08/12 03:59:31 1.2.2.11
+++ buffer.h 2001/08/13 00:43:20 1.2.2.12
@@ -11,7 +11,7 @@
* *
********************************************************************
- last mod: $Id: buffer.h,v 1.2.2.11 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: buffer.h,v 1.2.2.12 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -46,6 +46,8 @@
/* the buffer itself */
char StatMask;
char FlushPending; /* must be separate from statmask */
+ char ReaderActive;
+ char WriterActive;
int OptimalWriteSize; /* optimal size to write out in chunks of, if possible. */
long size; /* buffer size, for reference */
long curfill; /* how much the buffer is currently filled */
@@ -59,13 +61,14 @@
#define STAT_PREBUFFERING 1
#define STAT_PLAYING 2
-#define STAT_EMPTYING 4
+#define STAT_INACTIVE 4
buf_t *StartBuffer (long size, long prebuffer, void *data,
pWriteFunc write_func, void *initData,
pInitFunc init_func, int OptimalWriteSize);
void SubmitData (buf_t *buf, chunk *data, size_t size, size_t nmemb);
void buffer_MarkEOS (buf_t *buf);
+void buffer_ReaderQuit (buf_t *buf);
void buffer_shutdown (buf_t *buf);
void buffer_cleanup (buf_t *buf);
void buffer_flush (buf_t *buf);
1.1.2.5 +7 -5 vorbis-tools/ogg123/Attic/curl_interface.c
Index: curl_interface.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/curl_interface.c,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- curl_interface.c 2001/08/12 03:59:31 1.1.2.4
+++ curl_interface.c 2001/08/13 00:43:20 1.1.2.5
@@ -11,7 +11,7 @@
* *
********************************************************************
- last mod: $Id: curl_interface.c,v 1.1.2.4 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: curl_interface.c,v 1.1.2.5 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -22,7 +22,7 @@
#include <string.h> /* for memmove */
#include <signal.h> /* for SIGINT */
-#define DEBUG_CURLINTERFACE
+#undef DEBUG_CURLINTERFACE
#ifdef DEBUG_CURLINTERFACE
#define debug(x, y...) do { fprintf (stderr, x , ## y); } while (0)
@@ -62,7 +62,7 @@
data->CurWritePtr += size;
data->BytesRequested -= size;
pthread_mutex_unlock (&data->ReadDataMutex);
- if (data->BytesRequested == 0)
+ if (data->BytesRequested == 0 || iseos)
pthread_cond_signal (&data->ReadDoneCondition);
}
else
@@ -151,6 +151,7 @@
ret = curl_easy_perform ((CURL *) data->CurlHandle);
debug ("curl done.\n");
buffer_MarkEOS (buf);
+ buffer_ReaderQuit (buf);
curl_easy_cleanup (data->CurlHandle);
data->CurlHandle = 0;
return (void *) ret;
@@ -256,8 +257,8 @@
while (data->BytesRequested > 0 && !data->EOS)
{
- debug ("Waiting for %d bytes of data to be read.\n",
- data->BytesRequested);
+ debug ("Waiting for %d bytes of data to be read, eos=%d.\n",
+ data->BytesRequested, data->EOS);
pthread_cond_wait (&data->ReadDoneCondition, &data->ReadDataMutex);
}
if (data->EOS)
@@ -296,6 +297,7 @@
pthread_kill (data->CurlThread, SIGTERM);
pthread_join (data->CurlThread, NULL);
data->ShuttingDown = 1;
+ data->EOS = 1;
data->BytesRequested = 0;
pthread_cond_signal (&data->ReadRequestedCondition);
memset (data, 0, sizeof(data));
1.1.2.5 +4 -1 vorbis-tools/ogg123/Attic/curl_interface.h
Index: curl_interface.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/curl_interface.h,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -r1.1.2.4 -r1.1.2.5
--- curl_interface.h 2001/08/12 03:59:31 1.1.2.4
+++ curl_interface.h 2001/08/13 00:43:20 1.1.2.5
@@ -11,7 +11,7 @@
* *
********************************************************************
- last mod: $Id: curl_interface.h,v 1.1.2.4 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: curl_interface.h,v 1.1.2.5 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -26,9 +26,12 @@
#include "buffer.h"
typedef struct InputOpts_s {
+ buf_t *buffer;
/* Input buffer options */
long BufferSize;
long Prebuffer;
+ char seekable;
+ double totalTime;
char *SaveStream;
1.39.2.15 +347 -228 vorbis-tools/ogg123/ogg123.c
Index: ogg123.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/ogg123.c,v
retrieving revision 1.39.2.14
retrieving revision 1.39.2.15
diff -u -r1.39.2.14 -r1.39.2.15
--- ogg123.c 2001/08/12 18:34:47 1.39.2.14
+++ ogg123.c 2001/08/13 00:43:20 1.39.2.15
@@ -14,7 +14,7 @@
* *
********************************************************************
- last mod: $Id: ogg123.c,v 1.39.2.14 2001/08/12 18:34:47 kcarnold Exp $
+ last mod: $Id: ogg123.c,v 1.39.2.15 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -39,9 +39,10 @@
#define BUFFER_CHUNK_SIZE 4096
char convbuffer[BUFFER_CHUNK_SIZE];
int convsize = BUFFER_CHUNK_SIZE;
-buf_t * InBuffer = NULL;
-buf_t * OutBuffer = NULL;
+/* take big options structure from the data segment */
+ogg123_options_t Options;
+
static char skipfile_requested;
static char exit_requested;
@@ -96,7 +97,12 @@
}
else
{
- fprintf (stderr, "Parse error: %s on line %d of %s (%s)\n", ParseErr(pcode), lineno, filename, line);
+ int len = 80 + strlen(filename) + strlen(line);
+ char *buf = malloc (len);
+ if (!buf) { perror ("malloc"); return -1; }
+ snprintf (buf, len, "Parse error: %s on line %d of %s (%s)\n", ParseErr(pcode), lineno, filename, line);
+ ShowMessage (0, 0, buf);
+ free(buf);
return 0;
}
}
@@ -122,19 +128,128 @@
}
/* /configuration interface */
+/* status interface */
+/* string temporary data (from the data segment) */
+char TwentyBytes1[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+char TwentyBytes2[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+char TwentyBytes3[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+void InitOgg123Stats (Stat_t stats[])
+{
+ Stat_t *cur;
+
+ cur = &stats[0]; /* currently playing file / stream */
+ cur->prio = 3; cur->enabled = 0; cur->formatstr = "File: %s"; cur->type = stat_stringarg;
+ cur = &stats[1]; /* current playback time (preformatted) */
+ cur->prio = 1; cur->enabled = 1; cur->formatstr = "Time: %s"; cur->type = stat_stringarg; cur->arg.stringarg = TwentyBytes1;
+ cur = &stats[2]; /* remaining playback time (preformatted) */
+ cur->prio = 1; cur->enabled = 0; cur->formatstr = "%s"; cur->type = stat_stringarg; cur->arg.stringarg = TwentyBytes2;
+ cur = &stats[3]; /* total playback time (preformatted) */
+ cur->prio = 1; cur->enabled = 0; cur->formatstr = "of %s"; cur->type = stat_stringarg; cur->arg.stringarg = TwentyBytes3;
+ cur = &stats[4]; /* instantaneous bitrate */
+ cur->prio = 2; cur->enabled = 1; cur->formatstr = "Bitrate: %5.1f"; cur->type = stat_doublearg;
+ cur = &stats[5]; /* average bitrate (not yet implemented) */
+ cur->prio = 2; cur->enabled = 0; cur->formatstr = "Avg bitrate: %5.1f"; cur->type = stat_doublearg;
+ cur = &stats[6]; /* input buffer fill % */
+ cur->prio = 2; cur->enabled = 0; cur->formatstr = " Input Buffer %5.1f%%"; cur->type = stat_doublearg;
+ cur = &stats[7]; /* input buffer status */
+ cur->prio = 3; cur->enabled = 0; cur->formatstr = "(%s)"; cur->type = stat_stringarg; cur->arg.stringarg = NULL;
+ cur = &stats[8]; /* output buffer fill % */
+ cur->prio = 2; cur->enabled = 0; cur->formatstr = " Output Buffer %5.1f%%"; cur->type = stat_doublearg;
+ cur = &stats[9]; /* output buffer status */
+ cur->prio = 3; cur->enabled = 0; cur->formatstr = "%s"; cur->type = stat_stringarg; cur->arg.stringarg = NULL;
+}
+
+void SetTime (Stat_t stats[], ogg_int64_t sample)
+{
+ double time = (double) sample / (double) Options.outputOpts.rate;
+ long c_min = (long) time / (long) 60;
+ double c_sec = time - 60.0f * c_min;
+ long r_min, t_min;
+ double r_sec, t_sec;
+
+ if (stats[2].enabled && Options.inputOpts.seekable) {
+ r_min = (long) (Options.inputOpts.totalTime - time) / (long) 60;
+ r_sec = ((double) Options.inputOpts.totalTime - time) - 60.0f * (double) r_min;
+ sprintf (stats[2].arg.stringarg, "[%02li:%05.2f]", r_min, r_sec);
+ if (stats[3].arg.stringarg[0] == '\0') {
+ t_min = (long) Options.inputOpts.totalTime / (long) 60;
+ t_sec = Options.inputOpts.totalTime - 60.0f * t_min;
+ sprintf (stats[3].arg.stringarg, "of %02li:%05.2f", t_min, t_sec);
+ }
+ }
+ sprintf (stats[1].arg.stringarg, "%02li:%05.2f", c_min, c_sec);
+}
+
+void SetBufferStats (buf_t *buf, char *strbuf)
+{
+ char *cur = strbuf;
+ char *comma = ", ";
+ char *sep = "(";
+
+ if (buf->StatMask & STAT_PREBUFFERING) {
+ cur += sprintf (cur, "%sPrebuffering", sep);
+ sep = comma;
+ }
+ if (!buf->StatMask & STAT_PLAYING) {
+ cur += sprintf (cur, "%sPaused", sep);
+ sep = comma;
+ }
+ if (buf->FlushPending) {
+ cur += sprintf (cur, "%sFlushing", sep);
+ sep = comma;
+ }
+ if (buf->StatMask & STAT_INACTIVE) {
+ cur += sprintf (cur, "%sInactive", sep);
+ sep = comma;
+ }
+ if (cur != strbuf)
+ cur += sprintf (cur, ")");
+}
+
+void SetBuffersStats ()
+{
+ char strbuf[80];
+ Stat_t *stats = Options.statOpts.stats;
+
+ memset (strbuf, 0, 80);
+ if (Options.inputOpts.buffer) {
+ SetBufferStats (Options.inputOpts.buffer, strbuf);
+ stats[6].arg.doublearg = (double) buffer_full(Options.inputOpts.buffer) / (double) Options.inputOpts.buffer->size * 100.0f;
+ }
+ if (stats[7].arg.stringarg)
+ free (stats[7].arg.stringarg);
+ stats[7].arg.stringarg = strdup (strbuf);
+
+ memset (strbuf, 0, 80);
+ if (Options.outputOpts.buffer) {
+ SetBufferStats (Options.outputOpts.buffer, strbuf);
+ stats[8].arg.doublearg = (double) buffer_full(Options.outputOpts.buffer) / (double) Options.outputOpts.buffer->size * 100.0f;
+ }
+ if (stats[9].arg.stringarg)
+ free (stats[9].arg.stringarg);
+ stats[9].arg.stringarg = strdup (strbuf);
+}
+
+/* /status interface */
+
/* buffer interface */
size_t OutBufferWrite(void *ptr, size_t size, size_t nmemb, void *arg, char iseos)
{
static ogg_int64_t cursample = 0;
+
+ SetTime (Options.statOpts.stats, cursample);
+ SetBuffersStats ();
+ UpdateStats (Options.statOpts.stats);
+ cursample += size * nmemb / Options.outputOpts.channels / 2; /* locked to 16-bit */
- /* update status */
- /* update cursample */
if (iseos)
cursample = 0;
- devices_write (ptr, size, nmemb, (devices_t *) arg);
+ return devices_write (ptr, size, nmemb, Options.outputOpts.devices);
}
/* /buffer interface */
+
void usage(void)
{
FILE *o = stderr;
@@ -176,7 +291,6 @@
int main(int argc, char **argv)
{
- ogg123_options_t opt;
int ret;
int option_index = 1;
ao_option *temp_options = NULL;
@@ -196,30 +310,30 @@
/* *INDENT-OFF* */
Option_t opts[] = {
/* found, name, description, type, ptr, default */
- {0, "default_device", "default output device", opt_type_string, &opt.default_device, NULL},
- {0, "shuffle", "shuffle playlist", opt_type_char, &opt.shuffle, &char_n},
- {0, "verbose", "be verbose", opt_type_int, &opt.verbose, &int_0},
- {0, "quiet", "be quiet", opt_type_int, &opt.quiet, &int_0},
- {0, "outbuffer", "out buffer size (kB)", opt_type_int, &opt.outbuffer_size, &int_0},
- {0, "outprebuffer", "out prebuffer (%)", opt_type_float, &opt.outprebuffer, &float_0f},
- {0, "inbuffer", "in buffer size (kB)", opt_type_int, &opt.inputOpts.BufferSize, &int_10000},
- {0, "inprebuffer", "in prebuffer (%)", opt_type_float, &opt.inputOpts.Prebuffer, &float_50f},
- {0, "save_stream", "append stream to file", opt_type_string, &opt.inputOpts.SaveStream, NULL},
- {0, "delay", "skip file delay (sec)", opt_type_int, &opt.delay, &int_1},
+ {0, "default_device", "default output device", opt_type_string, &Options.outputOpts.default_device, NULL},
+ {0, "shuffle", "shuffle playlist", opt_type_char, &Options.playOpts.shuffle, &char_n},
+ {0, "verbose", "be verbose", opt_type_int, &Options.statOpts.verbose, &int_0},
+ {0, "quiet", "be quiet", opt_type_int, &Options.statOpts.quiet, &int_0},
+ {0, "outbuffer", "out buffer size (kB)", opt_type_int, &Options.outputOpts.BufferSize, &int_0},
+ {0, "outprebuffer", "out prebuffer (%)", opt_type_float, &Options.outputOpts.Prebuffer, &float_0f},
+ {0, "inbuffer", "in buffer size (kB)", opt_type_int, &Options.inputOpts.BufferSize, &int_10000},
+ {0, "inprebuffer", "in prebuffer (%)", opt_type_float, &Options.inputOpts.Prebuffer, &float_50f},
+ {0, "save_stream", "append stream to file", opt_type_string, &Options.inputOpts.SaveStream, NULL},
+ {0, "delay", "skip file delay (sec)", opt_type_int, &Options.playOpts.delay, &int_1},
{0, NULL, NULL, 0, NULL, NULL}
};
/* *INDENT-ON* */
- memset (&opt, 0, sizeof(opt));
-
- opt.delay = 1;
- opt.nth = 1;
- opt.ntimes = 1;
+ Options.playOpts.delay = 1;
+ Options.playOpts.nth = 1;
+ Options.playOpts.ntimes = 1;
- on_exit (ogg123_onexit, &opt);
+ on_exit (ogg123_onexit, &Options);
signal (SIGINT, signal_quit);
ao_initialize();
+ InitOgg123Stats (Options.statOpts.stats);
+
InitOpts(opts);
ReadStdConfigs (opts);
@@ -231,7 +345,7 @@
"Internal error: long option given when none expected.\n");
exit(1);
case 'b':
- opt.outbuffer_size = atoi(optarg);
+ Options.outputOpts.BufferSize = atoi(optarg);
break;
case 'c':
if (optarg)
@@ -257,10 +371,10 @@
fprintf(stderr, "No such device %s.\n", optarg);
exit(1);
}
- current = append_device(opt.outdevices, temp_driver_id,
+ current = append_device(Options.outputOpts.devices, temp_driver_id,
NULL, NULL);
- if(opt.outdevices == NULL)
- opt.outdevices = current;
+ if(Options.outputOpts.devices == NULL)
+ Options.outputOpts.devices = current;
current_options = ¤t->options;
break;
case 'f':
@@ -280,10 +394,10 @@
}
break;
case 'k':
- opt.seekpos = atof(optarg);
+ Options.playOpts.seekpos = atof(optarg);
break;
case 'l':
- opt.delay = atoi(optarg);
+ Options.playOpts.delay = atoi(optarg);
break;
case 'o':
if (optarg && !add_option(current_options, optarg)) {
@@ -295,30 +409,30 @@
usage();
exit(0);
case 'p':
- opt.outprebuffer = atof (optarg);
- if (opt.outprebuffer < 0.0f || opt.outprebuffer > 100.0f)
+ Options.outputOpts.Prebuffer = atof (optarg);
+ if (Options.outputOpts.Prebuffer < 0.0f || Options.outputOpts.Prebuffer > 100.0f)
{
fprintf (stderr, "Prebuffer value invalid. Range is 0-100, using nearest value.\n");
- opt.outprebuffer = opt.outprebuffer < 0.0f ? 0.0f : 100.0f;
+ Options.outputOpts.Prebuffer = Options.outputOpts.Prebuffer < 0.0f ? 0.0f : 100.0f;
}
break;
case 'q':
- opt.quiet++;
+ Options.statOpts.quiet++;
break;
case 'v':
- opt.verbose++;
+ Options.statOpts.verbose++;
break;
case 'V':
fprintf(stderr, "Ogg123 from " PACKAGE " " VERSION "\n");
exit(0);
case 'x':
- opt.nth = atoi (optarg);
+ Options.playOpts.nth = atoi (optarg);
break;
case 'y':
- opt.ntimes = atoi (optarg);
+ Options.playOpts.ntimes = atoi (optarg);
break;
case 'z':
- opt.shuffle = 1;
+ Options.playOpts.shuffle = 1;
break;
case '?':
break;
@@ -333,12 +447,14 @@
exit(1);
}
+ SetPriority (Options.statOpts.verbose);
+
/* Add last device to device list or use the default device */
if (temp_driver_id < 0) {
- if (opt.default_device) {
- temp_driver_id = ao_driver_id (opt.default_device);
- if (temp_driver_id < 0 && opt.quiet < 2)
- fprintf (stderr, "Warning: driver %s specified in configuration file invalid.\n", opt.default_device);
+ if (Options.outputOpts.default_device) {
+ temp_driver_id = ao_driver_id (Options.outputOpts.default_device);
+ if (temp_driver_id < 0 && Options.statOpts.quiet < 2)
+ fprintf (stderr, "Warning: driver %s specified in configuration file invalid.\n", Options.outputOpts.default_device);
}
}
@@ -352,26 +468,28 @@
exit(1);
}
- opt.outdevices = append_device(opt.outdevices, temp_driver_id,
+ Options.outputOpts.devices = append_device(Options.outputOpts.devices, temp_driver_id,
temp_options, NULL);
- opt.inputOpts.BufferSize *= 1024;
+ Options.inputOpts.BufferSize *= 1024;
- if (opt.outbuffer_size)
+ if (Options.outputOpts.BufferSize)
{
- opt.outbuffer_size *= 1024;
- opt.outprebuffer = (opt.outprebuffer * (float) opt.outbuffer_size / 100.0f);
- OutBuffer = StartBuffer (opt.outbuffer_size, (int) opt.outprebuffer,
- opt.outdevices, (pWriteFunc) OutBufferWrite,
- NULL, NULL, 4096);
+ Options.outputOpts.BufferSize *= 1024;
+ Options.outputOpts.Prebuffer = (Options.outputOpts.Prebuffer * (float) Options.outputOpts.BufferSize / 100.0f);
+ Options.outputOpts.buffer = StartBuffer (Options.outputOpts.BufferSize, (int) Options.outputOpts.Prebuffer,
+ NULL, (pWriteFunc) OutBufferWrite,
+ NULL, NULL, 4096);
+ Options.statOpts.stats[8].enabled = 1;
+ Options.statOpts.stats[9].enabled = 1;
}
- if (opt.shuffle == 'n' || opt.shuffle == 'N')
- opt.shuffle = 0;
- else if (opt.shuffle == 'y' || opt.shuffle == 'Y')
- opt.shuffle = 1;
+ if (Options.playOpts.shuffle == 'n' || Options.playOpts.shuffle == 'N')
+ Options.playOpts.shuffle = 0;
+ else if (Options.playOpts.shuffle == 'y' || Options.playOpts.shuffle == 'Y')
+ Options.playOpts.shuffle = 1;
- if (opt.shuffle) {
+ if (Options.playOpts.shuffle) {
int i;
int range = argc - optind;
@@ -386,13 +504,13 @@
}
while (optind < argc) {
- opt.read_file = argv[optind];
- play_file(&opt);
+ Options.playOpts.read_file = argv[optind];
+ play_file();
optind++;
}
- if (OutBuffer != NULL) {
- buffer_WaitForEmpty (OutBuffer);
+ if (Options.outputOpts.buffer != NULL) {
+ buffer_WaitForEmpty (Options.outputOpts.buffer);
}
exit (0);
@@ -426,8 +544,8 @@
void signal_quit(int ignored)
{
exit_requested = 1;
- if (OutBuffer)
- buffer_flush (OutBuffer);
+ if (Options.outputOpts.buffer)
+ buffer_flush (Options.outputOpts.buffer);
}
#if 0
@@ -439,64 +557,63 @@
}
#endif
-void play_file(ogg123_options_t *opt)
+void play_file()
{
OggVorbis_File vf;
int current_section = -1, eof = 0, eos = 0, ret;
int old_section = -1;
- long t_min = 0, c_min = 0, r_min = 0;
- double t_sec = 0, c_sec = 0, r_sec = 0;
int is_big_endian = ao_is_big_endian();
- double realseekpos = opt->seekpos;
+ double realseekpos = Options.playOpts.seekpos;
int nthc = 0, ntimesc = 0;
- double u_time, u_pos;
int tmp;
ov_callbacks VorbisfileCallbacks;
- tmp = strchr(opt->read_file, ':') - opt->read_file;
- if (tmp < 10 && tmp + 2 < strlen(opt->read_file) && !strncmp(opt->read_file + tmp, "://", 3))
+ tmp = strchr(Options.playOpts.read_file, ':') - Options.playOpts.read_file;
+ if (tmp < 10 && tmp + 2 < strlen(Options.playOpts.read_file) && !strncmp(Options.playOpts.read_file + tmp, "://", 3))
{
/* let's call this a URL. */
- if (opt->quiet < 1)
- fprintf (stderr, "Playing from stream %s\n", opt->read_file);
+ if (Options.statOpts.quiet < 1)
+ fprintf (stderr, "Playing from stream %s\n", Options.playOpts.read_file);
VorbisfileCallbacks.read_func = StreamBufferRead;
VorbisfileCallbacks.seek_func = StreamBufferSeek;
VorbisfileCallbacks.close_func = StreamBufferClose;
VorbisfileCallbacks.tell_func = StreamBufferTell;
- opt->inputOpts.URL = opt->read_file;
- InBuffer = InitStream (opt->inputOpts);
- if ((ov_open_callbacks (InBuffer->data, &vf, NULL, 0, VorbisfileCallbacks)) < 0) {
+ Options.inputOpts.URL = Options.playOpts.read_file;
+ Options.inputOpts.buffer = InitStream (Options.inputOpts);
+ if ((ov_open_callbacks (Options.inputOpts.buffer->data, &vf, NULL, 0, VorbisfileCallbacks)) < 0) {
fprintf(stderr, "Error: input not an Ogg Vorbis audio stream.\n");
return;
}
-
+ Options.statOpts.stats[6].enabled = 1;
+ Options.statOpts.stats[7].enabled = 1;
}
else
{
+ FILE *InStream;
#if 0
VorbisfileCallbacks.read_func = fread;
VorbisfileCallbacks.seek_func = _fseek64_wrap;
VorbisfileCallbacks.close_func = fclose;
VorbisfileCallbacks.tell_func = ftell;
#endif
- if (strcmp(opt->read_file, "-"))
+ if (strcmp(Options.playOpts.read_file, "-"))
{
- if (opt->quiet < 1)
- fprintf(stderr, "Playing from file %s.\n", opt->read_file);
+ if (Options.statOpts.quiet < 1)
+ fprintf(stderr, "Playing from file %s.\n", Options.playOpts.read_file);
/* Open the file. */
- if ((opt->instream = fopen(opt->read_file, "rb")) == NULL) {
+ if ((InStream = fopen(Options.playOpts.read_file, "rb")) == NULL) {
fprintf(stderr, "Error opening input file.\n");
exit(1);
}
}
else
{
- if (opt->quiet < 1)
+ if (Options.statOpts.quiet < 1)
fprintf(stderr, "Playing from standard input.\n");
- opt->instream = stdin;
+ InStream = stdin;
}
- if ((ov_open (opt->instream, &vf, NULL, 0)) < 0) {
+ if ((ov_open (InStream, &vf, NULL, 0)) < 0) {
fprintf(stderr, "Error: input not an Ogg Vorbis audio stream.\n");
return;
}
@@ -506,10 +623,10 @@
* interrupts the program, but after the first second, skips
* the song. This functionality is similar to mpg123's abilities. */
- if (opt->delay > 0) {
+ if (Options.playOpts.delay > 0) {
skipfile_requested = 0;
signal(SIGALRM,signal_activate_skipfile);
- alarm(opt->delay);
+ alarm(Options.playOpts.delay);
}
exit_requested = 0;
@@ -519,132 +636,140 @@
vorbis_comment *vc = ov_comment(&vf, -1);
vorbis_info *vi = ov_info(&vf, -1);
- if(open_audio_devices(opt, vi->rate, vi->channels) < 0)
+ Options.outputOpts.rate = vi->rate;
+ Options.outputOpts.channels = vi->channels;
+ if(open_audio_devices() < 0)
exit(1);
-
- if (opt->quiet < 1) {
- if (eos && opt->verbose) fprintf (stderr, "\r \r\n");
- for (i = 0; i < vc->comments; i++) {
- char *cc = vc->user_comments[i]; /* current comment */
- int i;
-
- for (i = 0; ogg_comment_keys[i].key != NULL; i++)
- if (!strncasecmp
- (ogg_comment_keys[i].key, cc,
- strlen(ogg_comment_keys[i].key))) {
- fprintf(stderr, ogg_comment_keys[i].formatstr,
- cc + strlen(ogg_comment_keys[i].key));
- break;
- }
- if (ogg_comment_keys[i].key == NULL)
- fprintf(stderr, "Unrecognized comment: '%s'\n", cc);
+
+ if (Options.statOpts.quiet < 1) {
+ if (eos && Options.statOpts.verbose) fprintf (stderr, "\r \r\n");
+ for (i = 0; i < vc->comments; i++) {
+ char *cc = vc->user_comments[i]; /* current comment */
+ int i;
+
+ for (i = 0; ogg_comment_keys[i].key != NULL; i++)
+ if (!strncasecmp
+ (ogg_comment_keys[i].key, cc,
+ strlen(ogg_comment_keys[i].key))) {
+ fprintf(stderr, ogg_comment_keys[i].formatstr,
+ cc + strlen(ogg_comment_keys[i].key));
+ break;
}
-
- fprintf(stderr, "\nBitstream is %d channel, %ldHz\n",
- vi->channels, vi->rate);
- if (opt->verbose > 1)
- fprintf(stderr, "Encoded by: %s\n\n", vc->vendor);
- }
-
- if (opt->verbose > 0 && ov_seekable(&vf)) {
- /* Seconds with double precision */
- u_time = ov_time_total(&vf, -1);
- t_min = (long) u_time / (long) 60;
- t_sec = u_time - 60 * t_min;
+ if (ogg_comment_keys[i].key == NULL)
+ fprintf(stderr, "Unrecognized comment: '%s'\n", cc);
}
-
+
+ fprintf(stderr, "\nBitstream is %d channel, %ldHz\n",
+ vi->channels, vi->rate);
+ if (Options.statOpts.verbose > 1)
+ fprintf(stderr, "Encoded by: %s\n\n", vc->vendor);
+ }
+
+ if (ov_seekable (&vf)) {
if ((realseekpos > ov_time_total(&vf, -1)) || (realseekpos < 0))
- /* If we're out of range set it to right before the end. If we set it
- * right to the end when we seek it will go to the beginning of the song */
- realseekpos = ov_time_total(&vf, -1) - 0.01;
-
+ /* If we're out of range set it to right before the end. If we set it
+ * right to the end when we seek it will go to the beginning of the song */
+ realseekpos = ov_time_total(&vf, -1) - 0.01;
+
+ Options.inputOpts.seekable = 1;
+ Options.inputOpts.totalTime = ov_time_total(&vf, -1);
+ Options.statOpts.stats[2].enabled = 1;
+ Options.statOpts.stats[3].enabled = 1;
+ if (Options.statOpts.verbose > 0)
+ SetTime (Options.statOpts.stats, realseekpos / vi->rate);
+
if (realseekpos > 0)
- ov_time_seek(&vf, realseekpos);
-
- eos = 0;
-
- while (!eos && !exit_requested) {
-
- if (skipfile_requested) {
- eof = eos = 1;
- skipfile_requested = 0;
- signal(SIGALRM,signal_activate_skipfile);
- alarm(opt->delay);
- if (OutBuffer)
- buffer_flush (OutBuffer);
- break;
- }
+ ov_time_seek(&vf, realseekpos);
+ }
+ else
+ Options.inputOpts.seekable = 0;
- old_section = current_section;
- ret =
- ov_read(&vf, convbuffer, sizeof(convbuffer), is_big_endian,
- 2, 1, ¤t_section);
- if (ret == 0) {
- /* End of file */
- eof = eos = 1;
- } else if (ret == OV_HOLE) {
- if (opt->verbose > 1)
- /* we should be able to resync silently; if not there are
- bigger problems. */
- fprintf (stderr, "Warning: hole in the stream; probably harmless\n");
- } else if (ret < 0) {
- /* Stream error */
- fprintf(stderr, "Error: libvorbis reported a stream error.\n");
- } else {
- /* did we enter a new logical bitstream */
- if (old_section != current_section && old_section != -1)
- eos = 1;
-
- do {
- if (nthc-- == 0) {
- if (OutBuffer)
- SubmitData (OutBuffer, convbuffer, ret, 1);
- else
- devices_write(convbuffer, ret, 1, opt->outdevices);
- nthc = opt->nth - 1;
- }
- } while (++ntimesc < opt->ntimes);
- ntimesc = 0;
-
- if (opt->verbose > 0) {
- if (ov_seekable (&vf)) {
- u_pos = ov_time_tell(&vf);
- c_min = (long) u_pos / (long) 60;
- c_sec = u_pos - 60 * c_min;
- r_min = (long) (u_time - u_pos) / (long) 60;
- r_sec = (u_time - u_pos) - 60 * r_min;
- if (OutBuffer)
- fprintf(stderr,
- "\rTime: %02li:%05.2f [%02li:%05.2f] of %02li:%05.2f, Bitrate: %5.1f, Buffer fill: %3.0f%% \r",
- c_min, c_sec, r_min, r_sec, t_min, t_sec,
- (double) ov_bitrate_instant(&vf) / 1000.0F,
- (double) buffer_full(OutBuffer) / (double) OutBuffer->size * 100.0F);
- else
- fprintf(stderr,
- "\rTime: %02li:%05.2f [%02li:%05.2f] of %02li:%05.2f, Bitrate: %5.1f \r",
- c_min, c_sec, r_min, r_sec, t_min, t_sec,
- (double) ov_bitrate_instant(&vf) / 1000.0F);
- } else {
- /* working around a bug in vorbisfile */
- /* I don't think that bug is there anymore -ken */
- u_pos = (double) ov_pcm_tell(&vf) / (double) vi->rate;
- c_min = (long) u_pos / (long) 60;
- c_sec = u_pos - 60 * c_min;
- if (OutBuffer)
- fprintf(stderr,
- "\rTime: %02li:%05.2f, Bitrate: %5.1f, Buffer fill: %3.0f%% \r",
- c_min, c_sec,
- (float) ov_bitrate_instant (&vf) / 1000.0F,
- (double) buffer_full(OutBuffer) / (double) OutBuffer->size * 100.0F);
- else
- fprintf(stderr,
- "\rTime: %02li:%05.2f, Bitrate: %5.1f \r",
- c_min, c_sec,
- (float) ov_bitrate_instant (&vf) / 1000.0F);
- }
- }
+ eos = 0;
+
+ while (!eos && !exit_requested) {
+
+ if (skipfile_requested) {
+ eof = eos = 1;
+ skipfile_requested = 0;
+ signal(SIGALRM,signal_activate_skipfile);
+ alarm(Options.playOpts.delay);
+ if (Options.outputOpts.buffer)
+ buffer_flush (Options.outputOpts.buffer);
+ break;
+ }
+
+ old_section = current_section;
+ ret =
+ ov_read(&vf, convbuffer, sizeof(convbuffer), is_big_endian,
+ 2, 1, ¤t_section);
+ if (ret == 0) {
+ /* End of file */
+ eof = eos = 1;
+ } else if (ret == OV_HOLE) {
+ if (Options.statOpts.verbose > 1)
+ /* we should be able to resync silently; if not there are
+ bigger problems. */
+ fprintf (stderr, "Warning: hole in the stream; probably harmless\n");
+ } else if (ret < 0) {
+ /* Stream error */
+ fprintf(stderr, "Error: libvorbis reported a stream error.\n");
+ } else {
+ /* did we enter a new logical bitstream */
+ if (old_section != current_section && old_section != -1)
+ eos = 1;
+
+ Options.statOpts.stats[4].arg.doublearg = (double) ov_bitrate_instant (&vf) / 1000.0f;
+
+ do {
+ if (nthc-- == 0) {
+ if (Options.outputOpts.buffer)
+ SubmitData (Options.outputOpts.buffer, convbuffer, ret, 1);
+ else
+ OutBufferWrite (convbuffer, ret, 1, &Options, 0);
+ nthc = Options.playOpts.nth - 1;
}
+ } while (++ntimesc < Options.playOpts.ntimes);
+ ntimesc = 0;
+
+#if 0
+ /* old status code */
+ if (ov_seekable (&vf)) {
+ u_pos = ov_time_tell(&vf);
+ c_min = (long) u_pos / (long) 60;
+ c_sec = u_pos - 60 * c_min;
+ r_min = (long) (u_time - u_pos) / (long) 60;
+ r_sec = (u_time - u_pos) - 60 * r_min;
+ if (Options.outputOpts.buffer)
+ fprintf(stderr,
+ "\rTime: %02li:%05.2f [%02li:%05.2f] of %02li:%05.2f, Bitrate: %5.1f, Buffer fill: %3.0f%% \r",
+ c_min, c_sec, r_min, r_sec, t_min, t_sec,
+ (double) ov_bitrate_instant(&vf) / 1000.0F,
+ (double) buffer_full(Options.outputOpts.buffer) / (double) Options.outputOpts.buffer->size * 100.0F);
+ else
+ fprintf(stderr,
+ "\rTime: %02li:%05.2f [%02li:%05.2f] of %02li:%05.2f, Bitrate: %5.1f \r",
+ c_min, c_sec, r_min, r_sec, t_min, t_sec,
+ (double) ov_bitrate_instant(&vf) / 1000.0F);
+ } else {
+ /* working around a bug in vorbisfile */
+ u_pos = (double) ov_pcm_tell(&vf) / (double) vi->rate;
+ c_min = (long) u_pos / (long) 60;
+ c_sec = u_pos - 60 * c_min;
+ if (Options.outputOpts.buffer)
+ fprintf(stderr,
+ "\rTime: %02li:%05.2f, Bitrate: %5.1f, Buffer fill: %3.0f%% \r",
+ c_min, c_sec,
+ (float) ov_bitrate_instant (&vf) / 1000.0F,
+ (double) buffer_full(Options.outputOpts.buffer) / (double) Options.outputOpts.buffer->size * 100.0F);
+ else
+ fprintf(stderr,
+ "\rTime: %02li:%05.2f, Bitrate: %5.1f \r",
+ c_min, c_sec,
+ (float) ov_bitrate_instant (&vf) / 1000.0F);
+ }
+#endif
}
+ }
}
alarm(0);
@@ -652,45 +777,41 @@
signal(SIGINT,signal_quit);
ov_clear(&vf);
-
- if (opt->quiet < 1)
- fprintf(stderr, "\nDone.\n");
-
+
+ if (Options.statOpts.quiet < 1)
+ fprintf(stderr, "\nDone.\n");
+
if (exit_requested)
- {
- exit (0);
- }
+ exit (0);
}
-/* if not for the two lines involving the buffer, this would go in
- * ao_interface.c. */
-int open_audio_devices(ogg123_options_t *opt, int rate, int channels)
+int open_audio_devices()
{
static int prevrate=0, prevchan=0;
devices_t *current;
ao_sample_format format;
- if(prevrate == rate && prevchan == channels)
+ if(prevrate == Options.outputOpts.rate && prevchan == Options.outputOpts.channels)
return 0;
if(prevrate !=0 && prevchan!=0)
{
- if (OutBuffer)
- buffer_WaitForEmpty (OutBuffer);
+ if (Options.outputOpts.buffer)
+ buffer_WaitForEmpty (Options.outputOpts.buffer);
- close_audio_devices (opt->outdevices);
+ close_audio_devices (Options.outputOpts.devices);
}
- format.rate = prevrate = rate;
- format.channels = prevchan = channels;
+ format.rate = prevrate = Options.outputOpts.rate;
+ format.channels = prevchan = Options.outputOpts.channels;
format.bits = 16;
format.byte_format = AO_FMT_NATIVE;
- current = opt->outdevices;
+ current = Options.outputOpts.devices;
while (current != NULL) {
ao_info *info = ao_driver_info(current->driver_id);
- if (opt->verbose > 0) {
+ if (Options.statOpts.verbose > 0) {
fprintf(stderr, "Device: %s\n", info->name);
fprintf(stderr, "Author: %s\n", info->author);
fprintf(stderr, "Comments: %s\n", info->comment);
@@ -748,17 +869,15 @@
void ogg123_onexit (int exitcode, void *arg)
{
- ogg123_options_t *opt = (ogg123_options_t*) arg;
-
- if (InBuffer) {
- StreamInputCleanup (InBuffer);
- InBuffer = NULL;
+ if (Options.inputOpts.buffer) {
+ StreamInputCleanup (Options.inputOpts.buffer);
+ Options.inputOpts.buffer = NULL;
}
- if (OutBuffer) {
- buffer_cleanup (OutBuffer);
- OutBuffer = NULL;
+ if (Options.outputOpts.buffer) {
+ buffer_cleanup (Options.outputOpts.buffer);
+ Options.outputOpts.buffer = NULL;
}
- ao_onexit (exitcode, opt->outdevices);
+ ao_onexit (exitcode, Options.outputOpts.devices);
}
1.7.2.9 +38 -17 vorbis-tools/ogg123/ogg123.h
Index: ogg123.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/ogg123.h,v
retrieving revision 1.7.2.8
retrieving revision 1.7.2.9
diff -u -r1.7.2.8 -r1.7.2.9
--- ogg123.h 2001/08/12 03:59:31 1.7.2.8
+++ ogg123.h 2001/08/13 00:43:20 1.7.2.9
@@ -11,7 +11,7 @@
* *
********************************************************************
- last mod: $Id: ogg123.h,v 1.7.2.8 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: ogg123.h,v 1.7.2.9 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -30,28 +30,49 @@
#include "ao_interface.h"
#include "curl_interface.h"
+#include "status.h"
typedef struct ogg123_options_s {
- char *read_file; /* File to decode */
- char shuffle; /* Should we shuffle playing? */
- long int verbose; /* Verbose output if > 0, quiet if < 0 */
- long int quiet; /* Be quiet (no title) */
- double seekpos; /* Amount to seek by */
- FILE *instream; /* Stream to read from. */
- char *default_device; /* default device for playback */
- devices_t *outdevices; /* Streams to write to. */
- long outbuffer_size; /* Size of the buffer in chunks. */
- float outprebuffer; /* number of chunks to prebuffer */
- int rate, channels; /* playback params for opening audio devices */
- int delay; /* delay for skip to next song */
- int nth; /* Play every nth chunk */
- int ntimes; /* Play every chunk n times */
+ struct {
+ char *read_file; /* File to decode */
+ char shuffle; /* Should we shuffle playing? */
+ double seekpos; /* Amount to seek by */
+ int delay; /* delay for skip to next song */
+ int nth; /* Play every nth chunk */
+ int ntimes; /* Play every chunk n times */
+ } playOpts;
+ struct {
+ long int verbose; /* Verbose output if > 0, quiet if < 0 */
+ long int quiet; /* Be quiet (no title) */
+
+ /* Status options:
+ * stats[0] - currently playing file / stream
+ * stats[1] - current playback time
+ * stats[2] - remaining playback time
+ * stats[3] - total playback time
+ * stats[4] - instantaneous bitrate
+ * stats[5] - average bitrate (not yet implemented)
+ * stats[6] - input buffer fill %
+ * stats[7] - input buffer status
+ * stats[8] - output buffer fill %
+ * stats[9] - output buffer status
+ */
+ Stat_t stats[10];
+ } statOpts;
InputOpts_t inputOpts;
+ struct {
+ buf_t *buffer;
+ long BufferSize;
+ float Prebuffer;
+ int rate, channels; /* playback params for opening audio devices */
+ devices_t *devices;
+ char *default_device;
+ } outputOpts;
} ogg123_options_t;
void usage(void);
-void play_file(ogg123_options_t *opt);
-int open_audio_devices(ogg123_options_t *opt, int rate, int channels);
+void play_file();
+int open_audio_devices();
void signal_quit (int ignored);
void ogg123_onexit (int exitcode, void *arg);
1.1.2.2 +37 -30 vorbis-tools/ogg123/Attic/options.c
Index: options.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/options.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- options.c 2001/08/12 03:59:31 1.1.2.1
+++ options.c 2001/08/13 00:43:20 1.1.2.2
@@ -11,12 +11,16 @@
* *
********************************************************************
- last mod: $Id: options.c,v 1.1.2.1 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: options.c,v 1.1.2.2 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
#define _GNU_SOURCE
+/* if strcasecmp is giving you problems, switch to strcmp or the appropriate
+ * function for your platform / compiler.
+ */
+
#include "options.h"
#include <stdlib.h>
@@ -31,32 +35,35 @@
{
while (opts && opts->name)
{
- switch (opts->type) {
- case opt_type_none:
- /* do nothing */
- break;
-
- case opt_type_char:
- *(char *) opts->ptr = *(char*) opts->dfl;
- break;
-
- case opt_type_string:
- *(char **) opts->ptr = (char *) opts->dfl;
- break;
-
- case opt_type_int:
- *(long int *) opts->ptr = *(int *) opts->dfl;
- break;
-
- case opt_type_float:
- *(float *) opts->ptr = *(float *) opts->dfl;
- break;
-
- case opt_type_double:
+ opts->found = 0;
+ if (opts->dfl) {
+ switch (opts->type) {
+ case opt_type_none:
+ /* do nothing */
+ break;
+
+ case opt_type_char:
+ *(char *) opts->ptr = *(char*) opts->dfl;
+ break;
+
+ case opt_type_string:
+ *(char **) opts->ptr = (char *) opts->dfl;
+ break;
+
+ case opt_type_int:
+ *(long int *) opts->ptr = *(int *) opts->dfl;
+ break;
+
+ case opt_type_float:
+ *(float *) opts->ptr = *(float *) opts->dfl;
+ break;
+
+ case opt_type_double:
*(double *) opts->ptr = *(double *) opts->dfl;
break;
-
- default:
+
+ default:
+ }
}
opts++;
}
@@ -114,7 +121,7 @@
/* now key is in line and value is in value. Search for a matching option. */
opt = opts;
while (opt->name) {
- if (!strcmp (opt->name, line)) {
+ if (!strcasecmp (opt->name, line)) {
long tmpl;
char **endptr;
@@ -276,7 +283,7 @@
void DescribeOptions (Option_t opts[], FILE *f)
{
/* name | description | type | default */
- int colWidths[] = {0, 0, 7};
+ int colWidths[] = {0, 0, 7, 7};
int totalWidth = 0;
Option_t *opt = opts;
@@ -304,15 +311,15 @@
/* Description */
totalWidth += fprintf (f, "Description");
- totalWidth += PrintSpace (f, (colWidths[0] - 11), ' ');
+ totalWidth += PrintSpace (f, (colWidths[1] - 11), ' ');
/* Type */
totalWidth += fprintf (f, "Type");
- totalWidth += PrintSpace (f, (colWidths[0] - 4), ' ');
+ totalWidth += PrintSpace (f, (colWidths[2] - 4), ' ');
/* Default */
totalWidth += fprintf (f, "Default");
- totalWidth += PrintSpace (f, (colWidths[0] - 7), ' ');
+ totalWidth += PrintSpace (f, (colWidths[3] - 7), ' ');
fputc ('\n', f);
1.1.2.2 +10 -4 vorbis-tools/ogg123/Attic/status.c
Index: status.c
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/status.c,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- status.c 2001/08/12 03:59:31 1.1.2.1
+++ status.c 2001/08/13 00:43:20 1.1.2.2
@@ -11,7 +11,7 @@
* *
********************************************************************
- last mod: $Id: status.c,v 1.1.2.1 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: status.c,v 1.1.2.2 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
@@ -40,8 +40,10 @@
ClearLine();
while (stats->formatstr != NULL)
{
- if (stats->prio > MaxPrio)
+ if (stats->prio > MaxPrio || !stats->enabled) {
+ stats++;
continue;
+ }
if (len != 0)
len += fprintf (stderr, " ");
switch (stats->type) {
@@ -68,11 +70,15 @@
}
/* msg has no final \n and no formatting */
-void ShowMessage (int prio, char *msg)
+void ShowMessage (int prio, char keepLastLine, char *msg)
{
if (prio > MaxPrio)
return;
- ClearLine();
+ if (!keepLastLine)
+ ClearLine();
+ else
+ if (LastLineLen)
+ fputc ('\n', stderr);
fprintf (stderr, msg);
fputc ('\n', stderr);
LastLineLen = 0;
1.1.2.2 +8 -2 vorbis-tools/ogg123/Attic/status.h
Index: status.h
===================================================================
RCS file: /usr/local/cvsroot/vorbis-tools/ogg123/Attic/status.h,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -u -r1.1.2.1 -r1.1.2.2
--- status.h 2001/08/12 03:59:31 1.1.2.1
+++ status.h 2001/08/13 00:43:20 1.1.2.2
@@ -11,14 +11,18 @@
* *
********************************************************************
- last mod: $Id: status.h,v 1.1.2.1 2001/08/12 03:59:31 kcarnold Exp $
+ last mod: $Id: status.h,v 1.1.2.2 2001/08/13 00:43:20 kcarnold Exp $
********************************************************************/
+#ifndef __STATUS_H
+#define __STATUS_H
+
/* status interface */
typedef struct {
int prio;
+ char enabled;
char *formatstr;
enum {
stat_noarg = 0,
@@ -36,5 +40,7 @@
} Stat_t;
void UpdateStats (Stat_t stats[]);
-void ShowMessage (int prio, char *msg);
+void ShowMessage (int prio, char keepStatusLine, char *msg);
void SetPriority (int prio);
+
+#endif /* __STATUS_H */
--- >8 ----
List archives: http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body. No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.
More information about the commits
mailing list