Commit 7ef99b09 authored by Stan Seibert's avatar Stan Seibert

Finally, we merge my branch onto the head. Duck and cover.

svn path=/trunk/vorbis-tools/; revision=2838
parent 016e0ba3
This diff is collapsed.
......@@ -19,12 +19,6 @@ CFLAGS="$cflags_save"
AM_PROG_LIBTOOL
dnl --------------------------------------------------
dnl Additional arguments
dnl --------------------------------------------------
AC_ARG_WITH(ogg, [ --with-ogg=DIR Set where the Ogg library is located])
AC_ARG_WITH(vorbis, [ --with-vorbis=DIR Set where the Vorbis library is located])
dnl --------------------------------------------------
dnl Set build flags based on environment
......@@ -81,18 +75,6 @@ DEBUG="$DEBUG $cflags_save"
PROFILE="$PROFILE $cflags_save"
LDFLAGS="$LDFLAGS $ldflags_save"
dnl --------------------------------------------------
dnl Check for headers
dnl --------------------------------------------------
dnl none
dnl --------------------------------------------------
dnl Check for typedefs, structures, etc
dnl --------------------------------------------------
dnl none
dnl --------------------------------------------------
dnl Check for libraries
dnl --------------------------------------------------
......@@ -100,17 +82,23 @@ dnl --------------------------------------------------
AM_PATH_OGG(,AC_MSG_ERROR(Ogg needed!))
AM_PATH_VORBIS(,AC_MSG_ERROR(Vorbis needed!))
AM_PATH_AO(,AC_MSG_ERROR(libao needed!))
AM_PATH_CURL(,AC_MSG_ERROR(libcurl needed!))
ACX_PTHREAD(,AC_MSG_ERROR(POSIX threads required!))
SOCKET_LIBS=
AC_CHECK_LIB(socket, socket, SOCKET_LIBS="-lsocket")
AC_CHECK_LIB(nsl, gethostbyname, SOCKET_LIBS="-lnsl $SOCKET_LIBS")
SHARE_LIBS='$(top_srcdir)/share/libutf8.a $(top_srcdir)/share/libgetopt.a'
SHARE_CFLAGS='-I$(top_srcdir)/include'
dnl --------------------------------------------------
dnl Check for library functions
dnl --------------------------------------------------
AM_ICONV
AC_FUNC_SMMAP
AC_CHECK_FUNCS(atexit on_exit)
AM_LANGINFO_CODESET
dnl --------------------------------------------------
......@@ -131,6 +119,9 @@ dnl --------------------------------------------------
AC_SUBST(DEBUG)
AC_SUBST(PROFILE)
AC_SUBST(SOCKET_LIBS)
AC_SUBST(SHARE_CFLAGS)
AC_SUBST(SHARE_LIBS)
AC_SUBST(CURL_CFLAGS)
AC_SUBST(CURL_LIBS)
AC_OUTPUT(Makefile include/Makefile share/Makefile oggenc/Makefile oggenc/man/Makefile ogg123/Makefile vorbiscomment/Makefile vcut/Makefile ogginfo/Makefile debian/Makefile)
......@@ -8,15 +8,20 @@ doc_DATA = ogg123rc-example
mandir = @MANDIR@
man_MANS = ogg123.1
INCLUDES = @OGG_CFLAGS@ @VORBIS_CFLAGS@ @AO_CFLAGS@
INCLUDES = @OGG_CFLAGS@ @VORBIS_CFLAGS@ @AO_CFLAGS@ @CURL_CFLAGS@ \
@PTHREAD_CFLAGS@ @SHARE_CFLAGS@
ogg123_LDADD = @VORBISFILE_LIBS@ @VORBIS_LIBS@ @OGG_LIBS@ @AO_LIBS@ \
@SOCKET_LIBS@ @SHARE_LIBS@
@SOCKET_LIBS@ @SHARE_LIBS@ @CURL_LIBS@ @PTHREAD_CFLAGS@ \
@PTHREAD_LIBS@
ogg123_DEPENDENCIES = @SHARE_LIBS@
ogg123_SOURCES = ogg123.c ao_interface.c buffer.c ogg123.h buffer.h
## Comment the above and uncomment the next line to disable the buffer support
##ogg123_SOURCES = ogg123.c ao_interface.c nullbuffer.c ogg123.h buffer.h
ogg123_SOURCES = audio.c buffer.c callbacks.c \
cfgfile_options.c cmdline_options.c \
file_transport.c format.c http_transport.c \
ogg123.c oggvorbis_format.c status.c transport.c \
audio.h buffer.h callbacks.h compat.h \
cfgfile_options.h cmdline_options.h \
format.h ogg123.h status.h transport.h
EXTRA_DIST = $(man_MANS) $(doc_DATA)
......
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Kenneth C. Arnold <ogg@arnoldnet.net> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: audio.c,v 1.2 2001/12/19 02:52:53 volsung Exp $
********************************************************************/
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include "audio.h"
int audio_format_equal (audio_format_t *a, audio_format_t *b)
{
return
a->big_endian == b->big_endian &&
a->word_size == b->word_size &&
a->signed_sample == b->signed_sample &&
a->rate == b->rate &&
a->channels == b->channels;
}
audio_device_t *append_audio_device(audio_device_t *devices_list,
int driver_id,
ao_option *options, char *filename)
{
audio_device_t *head = devices_list;
if (devices_list != NULL) {
while (devices_list->next_device != NULL)
devices_list = devices_list->next_device;
devices_list = devices_list->next_device =
malloc(sizeof(audio_device_t));
} else {
head = devices_list = (audio_device_t *) malloc(sizeof(audio_device_t));
}
devices_list->driver_id = driver_id;
devices_list->options = options;
devices_list->filename = filename;
devices_list->device = NULL;
devices_list->next_device = NULL;
return devices_list;
}
int audio_devices_write(audio_device_t *d, void *ptr, int nbytes)
{
while (d != NULL) {
if (ao_play(d->device, ptr, nbytes) == 0)
return 0; /* error occurred */
d = d->next_device;
}
return 1;
}
int add_ao_option(ao_option **op_h, const char *optstring)
{
char *key, *value;
int result;
key = strdup(optstring);
if (key == NULL)
return 0;
value = strchr(key, ':');
if (value == NULL) {
free(key);
return 0;
}
/* split by replacing the separator with a null */
*value++ = '\0';
result = ao_append_option(op_h, key, value);
free(key);
return (result);
}
void close_audio_devices (audio_device_t *devices)
{
audio_device_t *current = devices;
while (current != NULL) {
if (current->device)
ao_close(current->device);
current->device = NULL;
current = current->next_device;
}
}
void free_audio_devices (audio_device_t *devices)
{
audio_device_t *current;
while (devices != NULL) {
current = devices->next_device;
free (devices);
devices = current;
}
}
void ao_onexit (void *arg)
{
audio_device_t *devices = (audio_device_t *) arg;
close_audio_devices (devices);
free_audio_devices (devices);
ao_shutdown();
}
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Kenneth C. Arnold <ogg@arnoldnet.net> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: audio.h,v 1.2 2001/12/19 02:52:53 volsung Exp $
********************************************************************/
/* ogg123's audio playback functions */
#ifndef __AUDIO_H__
#define __AUDIO_H__
#include <ao/ao.h>
typedef struct audio_format_t {
int big_endian;
int word_size;
int signed_sample;
int rate;
int channels;
} audio_format_t;
/* For facilitating output to multiple devices */
typedef struct audio_device_t {
int driver_id;
ao_device *device;
ao_option *options;
char *filename;
struct audio_device_t *next_device;
} audio_device_t;
int audio_format_equal (audio_format_t *a, audio_format_t *b);
audio_device_t *append_audio_device(audio_device_t *devices_list,
int driver_id,
ao_option *options, char *filename);
void audio_devices_print_info(audio_device_t *d);
int audio_devices_write(audio_device_t *d, void *ptr, int nbytes);
int add_ao_option(ao_option **op_h, const char *optstring);
void close_audio_devices (audio_device_t *devices);
void free_audio_devices (audio_device_t *devices);
void ao_onexit (void *arg);
#endif /* __AUDIO_H__ */
This diff is collapsed.
/* Common things between reader and writer threads */
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Kenneth C. Arnold <ogg@arnoldnet.net> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: buffer.h,v 1.4 2001/12/19 02:52:53 volsung Exp $
********************************************************************/
#ifndef __BUFFER_H
#define __BUFFER_H
/* A generic circular buffer interface with the ability to buffer
actions (conceptually) between bytes in the buffer.*/
#include "ogg123.h"
#ifndef __BUFFER_H__
#define __BUFFER_H__
/* 4096 is the chunk size we request from libvorbis. */
#define BUFFER_CHUNK_SIZE 4096
#include <stdlib.h>
#include <pthread.h>
#include <ogg/os_types.h>
typedef struct chunk_s
{
long len; /* Length of the chunk (for if we only got partial data) */
char data[BUFFER_CHUNK_SIZE];
} chunk_t;
typedef struct buf_s
struct action_t; /* forward declaration */
/* buffer_write_func(void *data, int nbytes, int eos, void *arg) */
typedef int (*buffer_write_func_t) (void *, int, int, void *);
typedef struct buf_t
{
char status; /* Status. See STAT_* below. */
int fds[2]; /* Pipe file descriptors. */
chunk_t *reader; /* Chunk the reader is busy with */
chunk_t *writer; /* Chunk the writer is busy with */
chunk_t *end; /* Last chunk in the buffer (for convenience) */
chunk_t buffer[1]; /* The buffer itself. It's more than one chunk. */
/* generic buffer interface */
void *write_arg;
buffer_write_func_t write_func;
/* pthread variables */
pthread_t thread;
pthread_mutex_t mutex;
pthread_cond_t playback_cond; /* signalled when playback can continue */
pthread_cond_t write_cond; /* signalled when more data can be written
to the buffer */
/* buffer info (constant) */
int audio_chunk_size; /* write data to audio device in this chunk size,
if possible */
long prebuffer_size; /* number of bytes to prebuffer */
long size; /* buffer size, for reference */
/* ----- Everything after this point is protected by mutex ----- */
/* buffering state variables */
int prebuffering;
int paused;
int eos;
int abort_write;
/* buffer data */
long curfill; /* how much the buffer is currently filled */
long start; /* offset in buffer of start of available data */
ogg_int64_t position; /* How many bytes have we output so far */
ogg_int64_t position_end; /* Position right after end of data */
struct action_t *actions; /* Queue actions to perform */
char buffer[1]; /* The buffer itself. It's more than one byte. */
} buf_t;
buf_t *fork_writer (long size, devices_t *d);
void submit_chunk (buf_t *buf, chunk_t chunk);
void buffer_shutdown (buf_t *buf);
void buffer_flush (buf_t *buf);
#define STAT_FLUSH 1
#define STAT_SHUTDOWN 2
/* action_func(buf_t *buf, void *arg) */
typedef void (*action_func_t) (buf_t *, void *);
typedef struct action_t {
ogg_int64_t position;
action_func_t action_func;
void *arg;
struct action_t *next;
} action_t;
typedef struct buffer_stats_t {
long size;
double fill;
int prebuffering;
int paused;
int eos;
} buffer_stats_t;
/* --- Buffer allocation --- */
buf_t *buffer_create (long size, long prebuffer,
buffer_write_func_t write_func, void *arg,
int audio_chunk_size);
void buffer_reset (buf_t *buf);
void buffer_destroy (buf_t *buf);
/* --- Buffer thread control --- */
int buffer_thread_start (buf_t *buf);
void buffer_thread_pause (buf_t *buf);
void buffer_thread_unpause (buf_t *buf);
void buffer_thread_kill (buf_t *buf);
/* --- Data buffering functions --- */
void buffer_submit_data (buf_t *buf, char *data, long nbytes);
size_t buffer_get_data (buf_t *buf, char *data, long nbytes);
#endif /* !defined (__BUFFER_H) */
void buffer_mark_eos (buf_t *buf);
void buffer_abort_write (buf_t *buf);
/* --- Action buffering functions --- */
void buffer_action_now (buf_t *buf, action_func_t action_func,
void *action_arg);
void buffer_insert_action_at_end (buf_t *buf, action_func_t action_func,
void *action_arg);
void buffer_append_action_at_end (buf_t *buf, action_func_t action_func,
void *action_arg);
void buffer_insert_action_at (buf_t *buf, action_func_t action_func,
void *action_arg, ogg_int64_t position);
void buffer_append_action_at (buf_t *buf, action_func_t action_func,
void *action_arg, ogg_int64_t position);
/* --- Buffer status functions --- */
void buffer_wait_for_empty (buf_t *buf);
long buffer_full (buf_t *buf);
buffer_stats_t *buffer_statistics (buf_t *buf);
#endif /* __BUFFER_H__ */
This diff is collapsed.
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: callbacks.h,v 1.2 2001/12/19 02:52:53 volsung Exp $
********************************************************************/
#ifndef __CALLBACKS_H__
#define __CALLBACKS_H__
#include "audio.h"
#include "buffer.h"
#include "status.h"
#include "format.h"
#include "transport.h"
/* Audio callbacks */
typedef struct audio_play_arg_t {
stat_format_t *stat_format;
audio_device_t *devices;
} audio_play_arg_t;
typedef struct audio_reopen_arg_t {
audio_device_t *devices;
audio_format_t *format;
} audio_reopen_arg_t;
int audio_play_callback (void *ptr, int nbytes, int eos, void *arg);
void audio_reopen_action (buf_t *buf, void *arg);
audio_reopen_arg_t *new_audio_reopen_arg (audio_device_t *devices,
audio_format_t *fmt);
/* Statisitics callbacks */
typedef struct print_statistics_arg_t {
stat_format_t *stat_format;
data_source_stats_t *data_source_statistics;
decoder_stats_t *decoder_statistics;
} print_statistics_arg_t;
void print_statistics_action (buf_t *buf, void *arg);
print_statistics_arg_t *new_print_statistics_arg (
stat_format_t *stat_format,
data_source_stats_t *data_source_statistics,
decoder_stats_t *decoder_statistics);
/* Decoder callbacks */
void decoder_error_callback (void *arg, int severity, char *message, ...);
void decoder_metadata_callback (void *arg, int verbosity, char *message, ...);
void decoder_buffered_error_callback (void *arg, int severity,
char *message, ...);
void decoder_buffered_metadata_callback (void *arg, int verbosity,
char *message, ...);
#endif /* __CALLBACKS_H__ */
This diff is collapsed.
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Kenneth C. Arnold <ogg@arnoldnet.net> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: cfgfile_options.h,v 1.2 2001/12/19 02:52:53 volsung Exp $
********************************************************************/
#ifndef __CFGFILE_OPTIONS_H__
#define __CFGFILE_OPTIONS_H__
#include <stdio.h>
typedef enum {
opt_type_none = 0,
opt_type_bool,
opt_type_char,
opt_type_string,
opt_type_int, /* long int */
opt_type_float,
opt_type_double
} file_option_type_t;
typedef enum {
parse_ok = 0,
parse_syserr,
parse_keynotfound,
parse_nokey,
parse_badvalue,
parse_badtype
} parse_code_t;
typedef struct file_option_t {
char found;
const char *name;
const char *desc;
file_option_type_t type;
void *ptr;
void *dfl;
} file_option_t;
void file_options_init (file_option_t opts[]);
void file_options_describe (file_option_t opts[], FILE *outfile);
parse_code_t parse_line (file_option_t opts[], char *line);
parse_code_t parse_config_file (file_option_t opts[], const char *filename);
const char *parse_error_string (parse_code_t pcode);
void parse_std_configs (file_option_t opts[]);
#endif /* __OPTIONS_H__ */
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
* THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
* PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE Ogg123 SOURCE CODE IS (C) COPYRIGHT 2000-2001 *
* by Stan Seibert <volsung@xiph.org> AND OTHER CONTRIBUTORS *
* http://www.xiph.org/ *
* *
********************************************************************
last mod: $Id: cmdline_options.c,v 1.2 2001/12/19 02:52:53 volsung Exp $
********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ao/ao.h>
#include "getopt.h"
#include "cmdline_options.h"
#include "status.h"
struct option long_options[] = {
/* GNU standard options */
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
/* ogg123-specific options */
{"buffer", required_argument, 0, 'b'},
{"config", optional_argument, 0, 'c'},
{"device", required_argument, 0, 'd'},
{"file", required_argument, 0, 'f'},
{"skip", required_argument, 0, 'k'},
{"delay", required_argument, 0, 'l'},
{"device-option", required_argument, 0, 'o'},
{"prebuffer", required_argument, 0, 'p'},
{"quiet", no_argument, 0, 'q'},
{"verbose", no_argument, 0, 'v'},
{"nth", required_argument, 0, 'x'},
{"ntimes", required_argument, 0, 'y'},
{"shuffle", no_argument, 0, 'z'},
{0, 0, 0, 0}
};
int parse_cmdline_options (int argc, char **argv,
ogg123_options_t *ogg123_opts,
file_option_t *file_opts)
{
int option_index = 1;
ao_option *temp_options = NULL;
ao_option ** current_options = &temp_options;
ao_info *info;
int temp_driver_id = -1;
audio_device_t *current;
int ret;
while (-1 != (ret = getopt_long(argc, argv, "b:c::d:f:hl:k:o:p:qvVx:y:z",
long_options, &option_index))) {
switch (ret) {
case 0:
status_error("Internal error: long option given when none expected.\n");
exit(1);
case 'b':
ogg123_opts->buffer_size = atoi(optarg) * 1024;
break;
case 'c':
if (optarg) {
char *tmp = strdup (optarg);
parse_code_t pcode = parse_line(file_opts, tmp);
if (pcode != parse_ok)
status_error("=== Error \"%s\" while parsing config option from command line.\n"
"=== Option was: %s\n",
parse_error_string(pcode), optarg);
free (tmp);
}
else {
/* not using the status interface here */
fprintf (stdout, "Available options:\n");
file_options_describe(file_opts, stdout);
exit (0);
}
break;
case 'd':
temp_driver_id = ao_driver_id(optarg);
if (temp_driver_id < 0) {
status_error("=== No such device %s.\n", optarg);
exit(1);
}
current = append_audio_device(ogg123_opts->devices,
temp_driver_id,
NULL, NULL);
if(ogg123_opts->devices == NULL)
ogg123_opts->devices = current;
current_options = &current->options;
break;
case 'f':
if (temp_driver_id >= 0) {
info = ao_driver_info(temp_driver_id);
if (info->type == AO_TYPE_FILE) {
free(current->filename);
current->filename = strdup(optarg);
} else {
status_error("=== Driver %s is not a file output driver.\n",
info->short_name);
exit(1);
}
} else {
status_error("=== Cannot specify output file without specifying a driver.\n");
exit (1);
}
break;
case 'k':
ogg123_opts->seekpos = atof(optarg);
break;
case 'l':
ogg123_opts->delay = atoi(optarg);
break;
case 'o':
if (optarg && !add_ao_option(current_options, optarg)) {
status_error("=== Incorrect option format: %s.\n", optarg);
exit(1);
}
break;
case 'h':
cmdline_usage();
exit(0);
break;
case 'p':
ogg123_opts->prebuffer = atof (optarg);
if (ogg123_opts->prebuffer < 0.0f ||
ogg123_opts->prebuffer > 100.0f) {
status_error ("--- Prebuffer value invalid. Range is 0-100.\n");
ogg123_opts->prebuffer =
ogg123_opts->prebuffer < 0.0f ? 0.0f : 100.0f;
}
break;
case 'q':
ogg123_opts->verbosity = 0;
break;
case 'v':
ogg123_opts->verbosity++;
break;
case 'V':
status_error("ogg123 from " PACKAGE " " VERSION "\n");
exit(0);
break;