[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