[xiph-commits] r16833 - in trunk/ao/src: . plugins/alsa plugins/arts plugins/esd plugins/irix plugins/macosx plugins/nas plugins/oss plugins/pulse

xiphmont at svn.xiph.org xiphmont at svn.xiph.org
Wed Jan 27 01:47:12 PST 2010


Author: xiphmont
Date: 2010-01-27 01:47:12 -0800 (Wed, 27 Jan 2010)
New Revision: 16833

Modified:
   trunk/ao/src/ao_au.c
   trunk/ao/src/audio_out.c
   trunk/ao/src/plugins/alsa/ao_alsa.c
   trunk/ao/src/plugins/arts/ao_arts.c
   trunk/ao/src/plugins/esd/ao_esd.c
   trunk/ao/src/plugins/irix/ao_irix.c
   trunk/ao/src/plugins/macosx/ao_macosx.c
   trunk/ao/src/plugins/nas/ao_nas.c
   trunk/ao/src/plugins/oss/ao_oss.c
   trunk/ao/src/plugins/pulse/ao_pulse.c
Log:
Continue adding mapping support to drivers.  Most importantly, add full 
channel mapping to Pulse driver.



Modified: trunk/ao/src/ao_au.c
===================================================================
--- trunk/ao/src/ao_au.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/ao_au.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -169,7 +169,7 @@
 	}
 
         if(!device->output_matrix){
-          /* set up out matrix such that users are arned about > stereo playback */
+          /* set up out matrix such that users are warned about > stereo playback */
           if(format->channels<=2)
             device->output_matrix=strdup("L,R");
           //else no matrix, which results in a warning

Modified: trunk/ao/src/audio_out.c
===================================================================
--- trunk/ao/src/audio_out.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/audio_out.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -588,7 +588,10 @@
 static char *mnemonics[]={
   "U","X","M",
   "L","C","R","CL","CR","SL","SR","BL","BC","BR","LFE",
-  "A1","A2","A3","A4","A5","A6","A7","A8","A9",NULL
+  "A1","A2","A3","A4","A5","A6","A7","A8","A9","A10",
+  "A11","A12","A13","A14","A15","A16","A17","A18","A19","A20",
+  "A21","A22","A23","A24","A25","A26","A27","A28","A29","A30",
+  "A31","A32",NULL
 };
 
 /* Check the requested maxtrix string for syntax and mnemonics */

Modified: trunk/ao/src/plugins/alsa/ao_alsa.c
===================================================================
--- trunk/ao/src/plugins/alsa/ao_alsa.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/alsa/ao_alsa.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -80,7 +80,7 @@
 	"Advanced Linux Sound Architecture (ALSA) output",
 	"alsa",
 	"Bill Currie <bill at taniwha.org>/Kevin Cody, Jr. <kevinc at wuff.dhs.org>",
-	"Outputs to the Advanced Linux Sound Architecture version 0.9.x/1.x.x.",
+	"Outputs to the Advanced Linux Sound Architecture version 0.9/1.x",
 	AO_FMT_NATIVE,
 	35,
 	ao_alsa_options,

Modified: trunk/ao/src/plugins/arts/ao_arts.c
===================================================================
--- trunk/ao/src/plugins/arts/ao_arts.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/arts/ao_arts.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -21,8 +21,12 @@
  *  along with GNU Make; see the file COPYING.  If not, write to
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- */
+ ********************************************************************
 
+ last mod: $Id$
+
+ ********************************************************************/
+
 #include <stdio.h>
 #include <errno.h>
 
@@ -31,6 +35,7 @@
 #include <ao/plugin.h>
 
 
+static char *ao_arts_options[] = {"matrix","verbose","quiet"};
 static ao_info ao_arts_info =
 {
 	AO_TYPE_LIVE,
@@ -44,8 +49,8 @@
 #else
 	15,
 #endif
-	NULL,
-	0
+	ao_arts_options,
+        3
 };
 
 
@@ -115,6 +120,13 @@
 					    format->bits, 
 					    format->channels, 
 					    "libao stream");
+        if(!device->output_matrix){
+          /* set up out matrix such that users are warned about > stereo playback */
+          if(format->channels<=2)
+            device->output_matrix=strdup("L,R");
+          //else no matrix, which results in a warning
+        }
+
 	return 1;
 }
 

Modified: trunk/ao/src/plugins/esd/ao_esd.c
===================================================================
--- trunk/ao/src/plugins/esd/ao_esd.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/esd/ao_esd.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -21,8 +21,12 @@
  *  along with GNU Make; see the file COPYING.  If not, write to
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- */
+ ********************************************************************
 
+ last mod: $Id$
+
+ ********************************************************************/
+
 #include <stdio.h>
 #include <unistd.h>
 #include <stdlib.h>
@@ -34,7 +38,7 @@
 #include <ao/ao.h>
 #include <ao/plugin.h>
 
-static char *ao_esd_options[] = {"host"};
+static char *ao_esd_options[] = {"host","matrix","verbose","quiet"};
 static ao_info ao_esd_info =
 {
 	AO_TYPE_LIVE,
@@ -45,7 +49,7 @@
 	AO_FMT_NATIVE,
 	40,
 	ao_esd_options,
-	1
+	4
 };
 
 
@@ -61,7 +65,7 @@
 	int sock;
 
 	/* don't wake up the beast while detecting */
-	putenv("ESD_NO_SPAWN=1"); 
+	putenv("ESD_NO_SPAWN=1");
 	sock = esd_open_sound(NULL);
 	if (sock < 0)
 		return 0;
@@ -87,11 +91,11 @@
 
 	internal = (ao_esd_internal *) malloc(sizeof(ao_esd_internal));
 
-	if (internal == NULL)	
+	if (internal == NULL)
 		return 0; /* Could not initialize device memory */
-	
+
 	internal->host = NULL;
-	
+
 	device->internal = internal;
 
 	return 1; /* Memory alloc successful */
@@ -135,21 +139,25 @@
 		 break;
 	default: return 0;
 	}
-	
+
 	esd_format = esd_bits | esd_channels | esd_mode | esd_func;
 
-	internal->sock = esd_play_stream(esd_format, format->rate, 
+	internal->sock = esd_play_stream(esd_format, format->rate,
 					 internal->host,
 					 "libao output");
 	if (internal->sock < 0)
 		return 0; /* Could not contact ESD server */
-	
+
 	device->driver_byte_format = AO_FMT_NATIVE;
 
+        /* ESD restricted to stereo only */
+        if(!device->output_matrix)
+            device->output_matrix=strdup("L,R");
+
 	return 1;
 }
 
-int ao_plugin_play(ao_device *device, const char* output_samples, 
+int ao_plugin_play(ao_device *device, const char* output_samples,
 		uint_32 num_bytes)
 {
 	ao_esd_internal *internal = (ao_esd_internal *) device->internal;

Modified: trunk/ao/src/plugins/irix/ao_irix.c
===================================================================
--- trunk/ao/src/plugins/irix/ao_irix.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/irix/ao_irix.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -23,8 +23,12 @@
  *  along with GNU Make; see the file COPYING.  If not, write to
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- */
+ ********************************************************************
 
+ last mod: $Id$
+
+ ********************************************************************/
+
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -45,6 +49,7 @@
 	int channels;
 } ao_irix_internal;
 
+static char *ao_irix_options[] = {"matrix","verbose","quiet"};
 
 static ao_info ao_irix_info =
 {
@@ -55,8 +60,8 @@
 	"Outputs to the IRIX Audio Library.",
 	AO_FMT_NATIVE,
 	20,
-	NULL,
-	1
+	ao_irix_options,
+	3
 };
 
 int ao_plugin_test(void)
@@ -187,6 +192,14 @@
 
 	device->driver_byte_format = AO_FMT_NATIVE;
 
+        if(!device->output_matrix){
+          /* set up out matrix such that users are warned about > stereo playback */
+          if(format->channels<=2)
+            device->output_matrix=strdup("L,R");
+          //else no matrix, which results in a warning
+        }
+
+
 	return 1;
 }
 

Modified: trunk/ao/src/plugins/macosx/ao_macosx.c
===================================================================
--- trunk/ao/src/plugins/macosx/ao_macosx.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/macosx/ao_macosx.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -21,8 +21,11 @@
  *  along with GNU Make; see the file COPYING.  If not, write to
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- */
+ ********************************************************************
 
+ last mod: $Id$
+
+ ********************************************************************/
 /*
   The MacOS X CoreAudio framework doesn't mesh as simply as some
   simpler frameworks do.  This is due to the fact that CoreAudio pulls
@@ -49,6 +52,8 @@
 #define true  1
 #define false 0
 
+static char *ao_macosx_options[] = {"matrix","verbose","quiet"};
+
 static ao_info ao_macosx_info =
 {
 	AO_TYPE_LIVE,
@@ -58,8 +63,8 @@
 	"",
 	AO_FMT_NATIVE,
 	30,
-	NULL,
-	0
+	ao_macosx_options,
+	3
 };
 
 
@@ -246,6 +251,10 @@
     
     device->driver_byte_format = AO_FMT_NATIVE;
 
+    /* limited to stereo for now */
+    if(!device->output_matrix)
+      device->output_matrix=strdup("L,R");
+
     return 1;
 }
 

Modified: trunk/ao/src/plugins/nas/ao_nas.c
===================================================================
--- trunk/ao/src/plugins/nas/ao_nas.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/nas/ao_nas.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -42,7 +42,10 @@
 
 static char *ao_nas_options[] = {
   "host",    /* NAS server. See nas(1) for format. */
-  "buf_size" /* Buffer size on server */
+  "buf_size", /* Buffer size on server */
+  "quiet",
+  "verbose",
+  "matrix"
 };
 
 static ao_info ao_nas_info =
@@ -55,7 +58,7 @@
 	AO_FMT_NATIVE,
 	10,
 	ao_nas_options,
-	2
+	5
 };
 
 
@@ -95,9 +98,9 @@
 
 	internal = (ao_nas_internal *) malloc(sizeof(ao_nas_internal));
 
-	if (internal == NULL)	
+	if (internal == NULL)
 		return 0; /* Could not initialize device memory */
-	
+
 	internal->host = NULL;
 	internal->buf_size = AO_NAS_BUF_SIZE;
 	internal->buf_free = 0;
@@ -161,8 +164,8 @@
 		(AuDeviceNumTracks(AuServerDevice(internal->aud, i)) ==
 		 format->channels))
 	      break;
-	  
-	  if ((i == AuServerNumDevices(internal->aud)) || 
+
+	  if ((i == AuServerNumDevices(internal->aud)) ||
 	      (!(internal->flow = AuCreateFlow(internal->aud, 0)))) {
 	    /* No physical output device found or flow creation failed. */
 	    AuCloseServer(internal->aud);
@@ -180,12 +183,20 @@
 				  format->rate, AuUnlimitedSamples, 0, 0);
 	AuSetElements(internal->aud, internal->flow, AuTrue, 2, elms, 0);
 	AuStartFlow(internal->aud, internal->flow, 0);
-	
+
 	device->driver_byte_format = AO_FMT_NATIVE;
+
+        if(!device->output_matrix){
+          /* set up out matrix such that users are warned about > stereo playback */
+          if(format->channels<=2)
+            device->output_matrix=strdup("L,R");
+          //else no matrix, which results in a warning
+        }
+
 	return 1;
 }
 
-int ao_plugin_play(ao_device *device, const char* output_samples, 
+int ao_plugin_play(ao_device *device, const char* output_samples,
 		uint_32 num_bytes)
 {
 	ao_nas_internal *internal = (ao_nas_internal *) device->internal;
@@ -223,7 +234,7 @@
 	    break;
 	  }
 	}
-	
+
 	return 1;
 }
 
@@ -244,4 +255,4 @@
 
 	free(internal->host);
 	free(internal);
-}
\ No newline at end of file
+}

Modified: trunk/ao/src/plugins/oss/ao_oss.c
===================================================================
--- trunk/ao/src/plugins/oss/ao_oss.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/oss/ao_oss.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -22,8 +22,12 @@
  *  along with GNU Make; see the file COPYING.  If not, write to
  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- */
+ ********************************************************************
 
+ last mod: $Id$
+
+ ********************************************************************/
+
 #include <stdio.h>
 #include <errno.h>
 #include <string.h>
@@ -41,7 +45,7 @@
 #include "ao/plugin.h"
 
 
-static char *ao_oss_options[] = {"dsp"};
+static char *ao_oss_options[] = {"dsp","verbose","quiet","matrix"};
 static ao_info ao_oss_info =
 {
 	AO_TYPE_LIVE,
@@ -52,7 +56,7 @@
 	AO_FMT_NATIVE,
 	20,
 	ao_oss_options,
-	1
+	4
 };
 
 
@@ -90,7 +94,7 @@
 #endif /* BROKEN_OSS */
 
 	/* then try the original dsp path */
-	if(fd < 0) 
+	if(fd < 0)
 	{
 		/* no? then try the traditional path */
 		err = strdup(strerror(errno));
@@ -117,7 +121,7 @@
 #endif /* BROKEN_OSS */
 
 	/* Deal with error cases */
-	if(fd < 0) 
+	if(fd < 0)
 	{
 	  /*			fprintf(stderr,
 				"libao - error: Could not open either default device:\n"
@@ -143,7 +147,7 @@
 
 	/* OSS emulation in ALSA will by default cause the open() call
 	   to block if the dsp is in use.  This will freeze the default
-	   driver detection unless the O_NONBLOCK flag is passed to 
+	   driver detection unless the O_NONBLOCK flag is passed to
 	   open().  We cannot use this flag when we actually open the
 	   device for writing because then we will overflow the buffer. */
 	if ( (fd = _open_default_oss_device(&dev_path, 0)) < 0 )
@@ -168,11 +172,11 @@
 
 	internal = (ao_oss_internal *) malloc(sizeof(ao_oss_internal));
 
-	if (internal == NULL)	
+	if (internal == NULL)
 		return 0; /* Could not initialize device memory */
-	
+
 	internal->dev = NULL;
-	
+
 	device->internal = internal;
 
 	return 1; /* Memory alloc successful */
@@ -185,7 +189,7 @@
 
 	if (!strcmp(key, "dsp")) {
 		/* Free old string in case "dsp" set twice in options */
-		free(internal->dev); 
+		free(internal->dev);
 		internal->dev = strdup(value);
 	}
 
@@ -202,7 +206,7 @@
 	int tmp;
 
 	/* Open the device driver */
-	
+
 	if (internal->dev != NULL) {
 		/* open the user-specified path */
 		internal->fd = open(internal->dev, O_WRONLY);
@@ -231,10 +235,10 @@
 			format->channels);
 		goto ERR;
 	}
-	
-	if (ioctl(internal->fd,SNDCTL_DSP_STEREO,&tmp) < 0 || 
+
+	if (ioctl(internal->fd,SNDCTL_DSP_STEREO,&tmp) < 0 ||
 			tmp+1 != format->channels) {
-		fprintf(stderr, "libao - OSS cannot set channels to %d\n", 
+		fprintf(stderr, "libao - OSS cannot set channels to %d\n",
 			format->channels);
 		goto ERR;
 	}
@@ -245,7 +249,7 @@
 	{
 	case 8: tmp = AFMT_S8;
 		break;
-        case 16: tmp = device->client_byte_format == AO_FMT_BIG ? 
+        case 16: tmp = device->client_byte_format == AO_FMT_BIG ?
 		   AFMT_S16_BE : AFMT_S16_LE;
 	        device->driver_byte_format = device->client_byte_format;
 	        break;
@@ -266,7 +270,7 @@
 	   of whack. */
 	if (ioctl(internal->fd,SNDCTL_DSP_SPEED, &tmp) < 0
 	    || tmp > 1.02 * format->rate || tmp < 0.98 * format->rate) {
-		fprintf(stderr, "libao - OSS cannot set rate to %d\n", 
+		fprintf(stderr, "libao - OSS cannot set rate to %d\n",
 			format->rate);
 		goto ERR;
 	}
@@ -282,6 +286,10 @@
 		goto ERR;
 	}
 
+        /* limited to stereo */
+        if(!device->output_matrix)
+          device->output_matrix=strdup("L,R");
+
 	return 1; /* Open successful */
 
  ERR:
@@ -292,7 +300,7 @@
 /*
  * play the sample to the already opened file descriptor
  */
-int ao_plugin_play(ao_device *device, const char *output_samples, 
+int ao_plugin_play(ao_device *device, const char *output_samples,
 		uint_32 num_bytes)
 {
 	int ret;

Modified: trunk/ao/src/plugins/pulse/ao_pulse.c
===================================================================
--- trunk/ao/src/plugins/pulse/ao_pulse.c	2010-01-27 07:40:50 UTC (rev 16832)
+++ trunk/ao/src/plugins/pulse/ao_pulse.c	2010-01-27 09:47:12 UTC (rev 16833)
@@ -1,24 +1,28 @@
-/* $Id$ */
-
 /***
   This file is part of libao-pulse.
- 
+
   libao-pulse is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published
   by the Free Software Foundation; either version 2 of the License,
   or (at your option) any later version.
- 
+
   libao-pulse is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   General Public License for more details.
- 
+
   You should have received a copy of the GNU General Public License
   along with libao-pulse; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
   USA.
-***/
 
+ ********************************************************************
+
+ last mod: $Id$
+
+ ********************************************************************/
+
+
 #ifdef HAVE_CONFIG_H
 #include <config.h>
 #endif
@@ -37,7 +41,10 @@
 /* Unfortunately libao doesn't allow "const" for these structures... */
 static char * ao_pulse_options[] = {
     "server",
-    "sink"
+    "sink",
+    "verbose",
+    "quiet",
+    "matrix"
 };
 
 static ao_info ao_pulse_info = {
@@ -49,7 +56,7 @@
     AO_FMT_NATIVE,
     50,
     ao_pulse_options,
-    2
+    5
 };
 
 typedef struct ao_pulse_internal {
@@ -81,7 +88,7 @@
     };
 
     disable_sigpipe();
-    
+
     if (getenv("PULSE_SERVER") || getenv("PULSE_SINK"))
         return 1;
 
@@ -106,15 +113,15 @@
     assert(device);
 
     internal = (ao_pulse_internal *) malloc(sizeof(ao_pulse_internal));
-    
-    if (internal == NULL)	
-        return 0; 
 
+    if (internal == NULL)
+        return 0;
+
     internal->simple = NULL;
     internal->server = NULL;
     internal->sink = NULL;
     device->internal = internal;
-    
+
     return 1;
 }
 
@@ -122,7 +129,7 @@
     ao_pulse_internal *internal;
     assert(device && device->internal && key && value);
     internal = (ao_pulse_internal *) device->internal;
-    
+
     if (!strcmp(key, "server")) {
         free(internal->server);
         internal->server = strdup(value);
@@ -131,15 +138,75 @@
         internal->sink = strdup(value);
     } else
         return 0;
-    
+
     return 1;
 }
 
+pa_channel_position_t default_map[]={
+  PA_CHANNEL_POSITION_FRONT_LEFT,
+  PA_CHANNEL_POSITION_FRONT_RIGHT,
+  PA_CHANNEL_POSITION_REAR_LEFT,
+  PA_CHANNEL_POSITION_REAR_RIGHT,
+  PA_CHANNEL_POSITION_FRONT_CENTER,
+  PA_CHANNEL_POSITION_LFE,
+  PA_CHANNEL_POSITION_SIDE_LEFT,
+  PA_CHANNEL_POSITION_SIDE_RIGHT,
+  PA_CHANNEL_POSITION_AUX0,
+  PA_CHANNEL_POSITION_AUX1,
+  PA_CHANNEL_POSITION_AUX2,
+  PA_CHANNEL_POSITION_AUX3,
+  PA_CHANNEL_POSITION_AUX4,
+  PA_CHANNEL_POSITION_AUX5,
+  PA_CHANNEL_POSITION_AUX6,
+  PA_CHANNEL_POSITION_AUX7,
+  PA_CHANNEL_POSITION_AUX8,
+  PA_CHANNEL_POSITION_AUX9,
+  PA_CHANNEL_POSITION_AUX10,
+  PA_CHANNEL_POSITION_AUX11,
+  PA_CHANNEL_POSITION_AUX12,
+  PA_CHANNEL_POSITION_AUX13,
+  PA_CHANNEL_POSITION_AUX14,
+  PA_CHANNEL_POSITION_AUX15,
+  PA_CHANNEL_POSITION_AUX16,
+  PA_CHANNEL_POSITION_AUX17,
+  PA_CHANNEL_POSITION_AUX18,
+  PA_CHANNEL_POSITION_AUX19,
+  PA_CHANNEL_POSITION_AUX20,
+  PA_CHANNEL_POSITION_AUX21,
+  PA_CHANNEL_POSITION_AUX22,
+  PA_CHANNEL_POSITION_AUX23,
+  PA_CHANNEL_POSITION_AUX23};
+
+typedef struct {
+  char *from;
+  pa_channel_position_t to;
+} translate;
+
+translate trans[]={
+  {"M",PA_CHANNEL_POSITION_MONO},
+  {"L",PA_CHANNEL_POSITION_FRONT_LEFT},
+  {"R",PA_CHANNEL_POSITION_FRONT_RIGHT},
+  {"C",PA_CHANNEL_POSITION_FRONT_CENTER},
+  {"BL",PA_CHANNEL_POSITION_REAR_LEFT},
+  {"BR",PA_CHANNEL_POSITION_REAR_RIGHT},
+  {"BC",PA_CHANNEL_POSITION_REAR_CENTER},
+  {"SL",PA_CHANNEL_POSITION_SIDE_LEFT},
+  {"SR",PA_CHANNEL_POSITION_SIDE_RIGHT},
+  {"LFE",PA_CHANNEL_POSITION_LFE},
+  {"U",PA_CHANNEL_POSITION_INVALID},
+  {"X",PA_CHANNEL_POSITION_INVALID},
+  {"CL",PA_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER},
+  {"CR",PA_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER},
+  {NULL,PA_CHANNEL_POSITION_INVALID}
+};
+
 int ao_plugin_open(ao_device *device, ao_sample_format *format) {
     char p[PATH_MAX], t[256], t2[256];
     const char *fn = NULL;
     ao_pulse_internal *internal;
     struct pa_sample_spec ss;
+    struct pa_channel_map map;
+    int usemap=0;
 
     assert(device && device->internal && format);
 
@@ -152,7 +219,7 @@
     else
         return 0;
 
-    if (format->channels <= 0)
+    if (format->channels <= 0 || format->channels > PA_CHANNELS_MAX)
         return 0;
 
     ss.channels = format->channels;
@@ -165,11 +232,73 @@
         snprintf(t, sizeof(t), "libao[%s]", fn);
         snprintf(t2, sizeof(t2), "libao[%s] playback stream", fn);
     }
-    
-    if (!(internal->simple = pa_simple_new(internal->server, fn ? t : "libao", PA_STREAM_PLAYBACK, internal->sink, fn ? t2 : "libao playback stream", &ss, NULL, NULL, NULL)))
+
+    if(!device->output_matrix){
+      if(format->matrix){
+        /* request a matrix similar/identical to the input format; let
+           Pulse do the conversion work */
+        int i;
+        char *p=format->matrix,*h;
+        char buffer[129]={0};
+        usemap=1;
+        pa_channel_map_init(&map);
+        map.channels=format->channels;
+
+        for(i=0;i<format->channels;i++){
+          int m=0;
+          h=p;
+          while(*h && *h!=',')h++;
+          while(trans[m].from){
+            if(h-p && !strncmp(trans[m].from,p,h-p) &&
+               strlen(trans[m].from)==h-p)
+              break;
+            m++;
+          }
+          if(i)strcat(buffer,",");
+          if(trans[m].from){
+            map.map[i] = trans[m].to;
+            strcat(buffer,trans[m].from);
+          }else{
+            map.map[i] = PA_CHANNEL_POSITION_INVALID;
+            strcat(buffer,"X");
+          }
+
+          p=h;
+          if(*h)p++;
+        }
+
+        device->output_matrix = strdup(buffer);
+
+      }else{
+        if(format->channels <= 32){
+          /* set up a channel mapping similar to ALSA */
+          if(format->channels == 1 ){
+            usemap=1;
+            pa_channel_map_init(&map);
+            map.channels=1;
+            map.map[0] = PA_CHANNEL_POSITION_MONO;
+            device->output_matrix=strdup("M");
+          }else{
+            int i;
+            usemap=1;
+            pa_channel_map_init(&map);
+            map.channels=format->channels;
+            for(i=0;i<format->channels;i++)
+              map.map[i] = default_map[i];
+            device->output_matrix=strdup("L,R,BL,BR,C,LFE,SL,SR,"
+                                  "A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,"
+                                  "A11,A12,A13,A14,A15,A16,A17,A18,A19,A20,"
+                                  "A21,A22,A23,A4");
+          }
+        }
+      }
+    }
+
+    if (!(internal->simple = pa_simple_new(internal->server, fn ? t : "libao", PA_STREAM_PLAYBACK, internal->sink, fn ? t2 : "libao playback stream", &ss, &map, NULL, NULL)))
         return 0;
 
     device->driver_byte_format = AO_FMT_NATIVE;
+
     return 1;
 }
 



More information about the commits mailing list