[xiph-commits] r17007 - in trunk/ao: include/ao src src/plugins/pulse
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Tue Mar 23 19:56:04 PDT 2010
Author: xiphmont
Date: 2010-03-23 19:56:04 -0700 (Tue, 23 Mar 2010)
New Revision: 17007
Modified:
trunk/ao/include/ao/ao.h
trunk/ao/include/ao/ao_private.h
trunk/ao/src/audio_out.c
trunk/ao/src/config.c
trunk/ao/src/plugins/pulse/ao_pulse.c
Log:
Add 'global' options to ao, primarily as a means of allowing debug
output during plugin load/sense.
allow config file loading to set driver options; specified the same
way as on the ogg123 command line, but with '=' instead of ':'
Add debug output to plugin load/test.
Modified: trunk/ao/include/ao/ao.h
===================================================================
--- trunk/ao/include/ao/ao.h 2010-03-24 01:12:20 UTC (rev 17006)
+++ trunk/ao/include/ao/ao.h 2010-03-24 02:56:04 UTC (rev 17007)
@@ -101,26 +101,35 @@
void ao_shutdown(void);
/* device setup/playback/teardown */
-int ao_append_option(ao_option **options, const char *key,
- const char *value);
-void ao_free_options(ao_option *options);
-ao_device* ao_open_live(int driver_id, ao_sample_format *format,
- ao_option *option);
-ao_device* ao_open_file(int driver_id, const char *filename, int overwrite,
- ao_sample_format *format, ao_option *option);
+int ao_append_global_option(const char *key,
+ const char *value);
+int ao_append_option(ao_option **options,
+ const char *key,
+ const char *value);
+void ao_free_options(ao_option *options);
+ao_device* ao_open_live(int driver_id,
+ ao_sample_format *format,
+ ao_option *option);
+ao_device* ao_open_file(int driver_id,
+ const char *filename,
+ int overwrite,
+ ao_sample_format *format,
+ ao_option *option);
-int ao_play(ao_device *device, char *output_samples, uint_32 num_bytes);
-int ao_close(ao_device *device);
+int ao_play(ao_device *device,
+ char *output_samples,
+ uint_32 num_bytes);
+int ao_close(ao_device *device);
/* driver information */
-int ao_driver_id(const char *short_name);
-int ao_default_driver_id(void);
-ao_info *ao_driver_info(int driver_id);
+int ao_driver_id(const char *short_name);
+int ao_default_driver_id(void);
+ao_info *ao_driver_info(int driver_id);
ao_info **ao_driver_info_list(int *driver_count);
-char *ao_file_extension(int driver_id);
+char *ao_file_extension(int driver_id);
/* miscellaneous */
-int ao_is_big_endian(void);
+int ao_is_big_endian(void);
#ifdef __cplusplus
Modified: trunk/ao/include/ao/ao_private.h
===================================================================
--- trunk/ao/include/ao/ao_private.h 2010-03-24 01:12:20 UTC (rev 17006)
+++ trunk/ao/include/ao/ao_private.h 2010-03-24 02:56:04 UTC (rev 17007)
@@ -141,7 +141,11 @@
#define adebug(format, args...) {\
if(device->verbose==2){ \
if(strcmp(format,"\n")){ \
- fprintf(stderr,"ao_%s debug: " format,device->funcs->driver_info()->short_name,## args); \
+ if(device->funcs->driver_info()->short_name){ \
+ fprintf(stderr,"ao_%s debug: " format,device->funcs->driver_info()->short_name,## args); \
+ }else{ \
+ fprintf(stderr,"debug: " format,## args); \
+ } \
}else{ \
fprintf(stderr,"\n"); \
} \
@@ -151,7 +155,11 @@
#define averbose(format, args...) {\
if(device->verbose>0){ \
if(strcmp(format,"\n")){ \
- fprintf(stderr,"ao_%s info: " format,device->funcs->driver_info()->short_name,## args); \
+ if(device->funcs->driver_info()->short_name){ \
+ fprintf(stderr,"ao_%s info: " format,device->funcs->driver_info()->short_name,## args); \
+ }else{ \
+ fprintf(stderr,"info: " format,## args); \
+ } \
}else{ \
fprintf(stderr,"\n"); \
} \
@@ -161,7 +169,11 @@
#define ainfo(format, args...) {\
if(device->verbose>=0){ \
if(strcmp(format,"\n")){ \
- fprintf(stderr,"ao_%s info: " format,device->funcs->driver_info()->short_name,## args); \
+ if(device->funcs->driver_info()->short_name){ \
+ fprintf(stderr,"ao_%s info: " format,device->funcs->driver_info()->short_name,## args); \
+ }else{ \
+ fprintf(stderr,"info: " format,## args); \
+ } \
}else{ \
fprintf(stderr,"\n"); \
} \
@@ -171,7 +183,11 @@
#define awarn(format, args...) {\
if(device->verbose>=0){ \
if(strcmp(format,"\n")){ \
- fprintf(stderr,"ao_%s WARNING: " format,device->funcs->driver_info()->short_name,## args); \
+ if(device->funcs->driver_info()->short_name){ \
+ fprintf(stderr,"ao_%s WARNING: " format,device->funcs->driver_info()->short_name,## args); \
+ }else{ \
+ fprintf(stderr,"WARNING: " format,## args); \
+ } \
}else{ \
fprintf(stderr,"\n"); \
} \
@@ -181,7 +197,11 @@
#define aerror(format, args...) { \
if(device->verbose>=0){ \
if(strcmp(format,"\n")){ \
- fprintf(stderr,"ao_%s ERROR: " format,device->funcs->driver_info()->short_name,## args); \
+ if(device->funcs->driver_info()->short_name){ \
+ fprintf(stderr,"ao_%s ERROR: " format,device->funcs->driver_info()->short_name,## args); \
+ }else{ \
+ fprintf(stderr,"ERROR: " format,## args); \
+ } \
}else{ \
fprintf(stderr,"\n"); \
} \
Modified: trunk/ao/src/audio_out.c
===================================================================
--- trunk/ao/src/audio_out.c 2010-03-24 01:12:20 UTC (rev 17006)
+++ trunk/ao/src/audio_out.c 2010-03-24 02:56:04 UTC (rev 17007)
@@ -106,12 +106,22 @@
static ao_info **info_table = NULL;
static int driver_count = 0;
+/* uses the device messaging and option infrastructure */
+static ao_device *ao_global_dummy;
+static ao_device ao_global_dummy_storage;
+static ao_option *ao_global_options=NULL;
+
/* ---------- Helper functions ---------- */
/* Clear out all of the library configuration options and set them to
defaults. The defaults should match the initializer above. */
static void _clear_config()
{
+ memset(ao_global_dummy,0,sizeof(*ao_global_dummy));
+ ao_global_dummy = NULL;
+ ao_free_options(ao_global_options);
+ ao_global_options = NULL;
+
free(config.default_driver);
config.default_driver = NULL;
}
@@ -121,12 +131,15 @@
struct. */
static driver_list *_get_plugin(char *plugin_file)
{
+ ao_device *device = ao_global_dummy;
driver_list *dt;
void *handle;
+ char *prompt="";
handle = dlopen(plugin_file, DLOPEN_FLAG /* See ao_private.h */);
if (handle) {
+ prompt="calloc() failed";
dt = (driver_list *)calloc(1,sizeof(driver_list));
if (!dt) return NULL;
@@ -138,42 +151,53 @@
return NULL;
}
+ prompt="ao_plugin_test() missing";
dt->functions->test = dlsym(dt->handle, "ao_plugin_test");
if (!(dt->functions->test)) goto failed;
+ prompt="ao_plugin_driver_info() missing";
dt->functions->driver_info =
dlsym(dt->handle, "ao_plugin_driver_info");
if (!(dt->functions->driver_info)) goto failed;
+ prompt="ao_plugin_device_list() missing";
dt->functions->device_init =
dlsym(dt->handle, "ao_plugin_device_init");
if (!(dt->functions->device_init )) goto failed;
+ prompt="ao_plugin_set_option() missing";
dt->functions->set_option =
dlsym(dt->handle, "ao_plugin_set_option");
if (!(dt->functions->set_option)) goto failed;
+ prompt="ao_plugin_open() missing";
dt->functions->open = dlsym(dt->handle, "ao_plugin_open");
if (!(dt->functions->open)) goto failed;
+ prompt="ao_plugin_play() missing";
dt->functions->play = dlsym(dt->handle, "ao_plugin_play");
if (!(dt->functions->play)) goto failed;
+ prompt="ao_plugin_close() missing";
dt->functions->close = dlsym(dt->handle, "ao_plugin_close");
if (!(dt->functions->close)) goto failed;
+ prompt="ao_plugin_clear() missing";
dt->functions->device_clear =
dlsym(dt->handle, "ao_plugin_device_clear");
if (!(dt->functions->device_clear)) goto failed;
} else {
- return NULL;
+ aerror("Failed to load plugin %s => dlopen() failed\n",plugin_file);
+ return NULL;
}
+ adebug("Loaded driver %s\n",dt->functions->driver_info()->short_name);
return dt;
failed:
+ aerror("Failed to load plugin %s => %s\n",plugin_file,prompt);
free(dt->functions);
free(dt);
return NULL;
@@ -187,24 +211,28 @@
int def_id;
int id;
ao_info *info;
- driver_list *driver = driver_head;
+ driver_list *dl = driver_head;
+ ao_device *device = ao_global_dummy;
+ adebug("Testing drivers to find playback default...\n");
if ( name == NULL || (def_id = ao_driver_id(name)) < 0 ) {
/* No default specified. Find one among available drivers. */
def_id = -1;
id = 0;
- while (driver != NULL) {
+ while (dl != NULL) {
- info = driver->functions->driver_info();
+ info = dl->functions->driver_info();
+ adebug("...testing %s\n",info->short_name);
if ( info->type == AO_TYPE_LIVE &&
info->priority > 0 && /* Skip static drivers */
- driver->functions->test() ) {
+ dl->functions->test() ) {
def_id = id; /* Found a usable driver */
+ adebug("OK, using driver %s\n",info->short_name);
break;
}
- driver = driver->next;
+ dl = dl->next;
id++;
}
}
@@ -216,6 +244,7 @@
/* Convert the static drivers table into a linked list of drivers. */
static driver_list* _load_static_drivers(driver_list **end)
{
+ ao_device *device = ao_global_dummy;
driver_list *head;
driver_list *driver;
int i;
@@ -226,6 +255,7 @@
driver->functions = static_drivers[0];
driver->handle = NULL;
driver->next = NULL;
+ adebug("Loaded driver %s\n",driver->functions->driver_info()->short_name);
i = 1;
while (static_drivers[i] != NULL) {
@@ -238,6 +268,7 @@
driver->next->next = NULL;
driver = driver->next;
+ adebug("Loaded driver %s\n",driver->functions->driver_info()->short_name);
i++;
}
}
@@ -845,7 +876,61 @@
return strdup(buffer);
}
+static int ao_global_load_options(ao_option *options){
+ while (options != NULL) {
+ if(!strcmp(options->key,"debug")){
+ ao_global_dummy->verbose=2;
+ }else if(!strcmp(options->key,"verbose")){
+ if(ao_global_dummy->verbose<1)ao_global_dummy->verbose=1;
+ }else if(!strcmp(options->key,"quiet")){
+ ao_global_dummy->verbose=-1;
+ }
+ options = options->next;
+ }
+
+ return 0;
+
+}
+
+static int ao_device_load_options(ao_device *device, ao_option *options){
+
+ while (options != NULL) {
+ if(!strcmp(options->key,"matrix")){
+ /* If a driver has a static channel mapping mechanism
+ (physically constant channel mapping, or at least an
+ unvarying set of constants for mapping channels), the
+ output_matrix is already set. An app/user specified
+ output mapping trumps. */
+ if(device->output_matrix)
+ free(device->output_matrix);
+ /* explicitly set the output matrix to the requested
+ string; devices must not override. */
+ device->output_matrix = _sanitize_matrix(32, options->value, device);
+ if(!device->output_matrix){
+ aerror("Empty or inavlid output matrix\n");
+ return AO_EBADOPTION;
+ }
+ adebug("Sanitized device output matrix: %s\n",device->output_matrix);
+ }else if(!strcmp(options->key,"debug")){
+ device->verbose=2;
+ }else if(!strcmp(options->key,"verbose")){
+ if(device->verbose<1)device->verbose=1;
+ }else if(!strcmp(options->key,"quiet")){
+ device->verbose=-1;
+ }else{
+ if (!device->funcs->set_option(device, options->key, options->value)) {
+ /* Problem setting options */
+ return AO_EOPENDEVICE;
+ }
+ }
+
+ options = options->next;
+ }
+
+ return 0;
+}
+
/* Open a device. If this is a live device, file == NULL. */
static ao_device* _open_device(int driver_id, ao_sample_format *format,
ao_option *options, FILE *file)
@@ -892,41 +977,11 @@
}
/* Load options */
- while (options != NULL) {
- if(!strcmp(options->key,"matrix")){
- /* If a driver has a static channel mapping mechanism
- (physically constant channel mapping, or at least an
- unvarying set of constants for mapping channels), the
- output_matrix is already set. An app/user specified
- output mapping trumps. */
- if(device->output_matrix)
- free(device->output_matrix);
- /* explicitly set the output matrix to the requested
- string; devices must not override. */
- device->output_matrix = _sanitize_matrix(32, options->value, device);
- if(!device->output_matrix){
- aerror("Empty or inavlid output matrix\n");
- errno = AO_EBADOPTION;
- goto error;
- }
- adebug("Sanitized device output matrix: %s\n",device->output_matrix);
- }else if(!strcmp(options->key,"debug")){
- device->verbose=2;
- }else if(!strcmp(options->key,"verbose")){
- if(device->verbose<1)device->verbose=1;
- }else if(!strcmp(options->key,"quiet")){
- device->verbose=-1;
- }else{
- if (!funcs->set_option(device, options->key, options->value)) {
- /* Problem setting options */
- errno = AO_EOPENDEVICE;
- goto error;
- }
- }
+ errno = ao_device_load_options(device,ao_global_options);
+ if(errno) goto error;
+ errno = ao_device_load_options(device,options);
+ if(errno) goto error;
- options = options->next;
- }
-
/* also sanitize the format input channel matrix */
if(format->matrix){
sformat.matrix = _sanitize_matrix(format->channels, format->matrix, device);
@@ -1173,12 +1228,23 @@
/* -- Library Setup/Teardown -- */
+static ao_info ao_dummy_info=
+ { 0,0,0,0,0,0,0,0,0 };
+static ao_info *ao_dummy_driver_info(void){
+ return &ao_dummy_info;
+}
+static ao_functions ao_dummy_funcs=
+ { 0, &ao_dummy_driver_info, 0,0,0,0,0,0,0};
+
void ao_initialize(void)
{
driver_list *end;
+ ao_global_dummy = &ao_global_dummy_storage;
+ ao_global_dummy->funcs = &ao_dummy_funcs;
/* Read config files */
ao_read_config_files(&config);
+ ao_global_load_options(ao_global_options);
if (driver_head == NULL) {
driver_head = _load_static_drivers(&end);
@@ -1189,7 +1255,6 @@
info_table = _make_info_table(&driver_head, &driver_count);
}
-
void ao_shutdown(void)
{
driver_list *driver = driver_head;
@@ -1216,7 +1281,6 @@
/* -- Device Setup/Playback/Teardown -- */
-
int ao_append_option(ao_option **options, const char *key, const char *value)
{
ao_option *op, *list;
@@ -1240,6 +1304,10 @@
return 1;
}
+int ao_append_global_option(const char *key, const char *value)
+{
+ return ao_append_option(&ao_global_options,key,value);
+}
void ao_free_options(ao_option *options)
{
Modified: trunk/ao/src/config.c
===================================================================
--- trunk/ao/src/config.c 2010-03-24 01:12:20 UTC (rev 17006)
+++ trunk/ao/src/config.c 2010-03-24 02:56:04 UTC (rev 17007)
@@ -3,6 +3,7 @@
* config.c
*
* Copyright (C) Stan Seibert - July 2000
+ * Copyright (C) Monty - Mar 2010
*
* This file is part of libao, a cross-platform audio output library. See
* README for a history of this source code.
@@ -36,19 +37,31 @@
#define LINE_LEN 100
+static char *trim(char *p){
+ char *t;
+ while(*p && isspace(*p))p++;
+ if(*p){
+ t=p+strlen(p);
+ while(t>p && isspace(*(t-1))){
+ t--;
+ *t='\0';
+ }
+ }
+ return p;
+}
+
static int ao_read_config_file(ao_config *config, const char *config_file)
{
FILE *fp;
char line[LINE_LEN];
int end;
-
-
+
if ( !(fp = fopen(config_file, "r")) )
return 0; /* Can't open file */
-
+
while (fgets(line, LINE_LEN, fp)) {
/* All options are key=value */
-
+
if (strncmp(line, "default_driver=", 15) == 0) {
free(config->default_driver);
end = strlen(line);
@@ -56,7 +69,20 @@
line[end-1] = 0; /* Remove trailing newline */
config->default_driver = strdup(line+15);
- }
+ }else{
+ /* entries in the config file that don't parse as
+ directives to AO at large are treated as driver
+ options */
+ char *key=trim(line);
+ if(key && *key){
+ char *val=strchr(key,'=');
+ if(val){
+ *val='\0';
+ val++;
+ }
+ ao_append_global_option(key,val);
+ }
+ }
}
fclose(fp);
@@ -71,9 +97,9 @@
/* Read the system-wide config file */
ao_read_config_file(config, AO_SYSTEM_CONFIG);
-
+
/* Read the user config file */
- if ( homedir!=NULL &&
+ if ( homedir!=NULL &&
strlen(homedir) <= FILENAME_MAX - strlen(AO_USER_CONFIG) )
{
strncpy(userfile, homedir, FILENAME_MAX);
Modified: trunk/ao/src/plugins/pulse/ao_pulse.c
===================================================================
--- trunk/ao/src/plugins/pulse/ao_pulse.c 2010-03-24 01:12:20 UTC (rev 17006)
+++ trunk/ao/src/plugins/pulse/ao_pulse.c 2010-03-24 02:56:04 UTC (rev 17007)
@@ -171,7 +171,6 @@
ao_pulse_internal *internal;
struct pa_sample_spec ss;
struct pa_channel_map map;
- int usemap=0;
size_t allocated = 128;
assert(device && device->internal && format);
More information about the commits
mailing list