[xiph-commits] r16817 - in trunk/ao: include/ao src src/plugins/alsa09
xiphmont at svn.xiph.org
xiphmont at svn.xiph.org
Tue Jan 26 01:38:18 PST 2010
Author: xiphmont
Date: 2010-01-26 01:38:18 -0800 (Tue, 26 Jan 2010)
New Revision: 16817
Modified:
trunk/ao/include/ao/ao.h
trunk/ao/src/audio_out.c
trunk/ao/src/plugins/alsa09/ao_alsa09.c
Log:
Add soem smarts to the ALSA default device autoselection, as the device
named 'default' is a plug that will happily accept any number of
channels, but only plays L/R.
Modified: trunk/ao/include/ao/ao.h
===================================================================
--- trunk/ao/include/ao/ao.h 2010-01-26 07:33:24 UTC (rev 16816)
+++ trunk/ao/include/ao/ao.h 2010-01-26 09:38:18 UTC (rev 16817)
@@ -100,7 +100,7 @@
void ao_shutdown(void);
/* device setup/playback/teardown */
-int ao_append_option(ao_option **options, const char *key,
+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,
Modified: trunk/ao/src/audio_out.c
===================================================================
--- trunk/ao/src/audio_out.c 2010-01-26 07:33:24 UTC (rev 16816)
+++ trunk/ao/src/audio_out.c 2010-01-26 09:38:18 UTC (rev 16817)
@@ -580,9 +580,10 @@
}
}
-/* the channel locations we know right now. code below assumes U is in slot 0, M in slot 1 */
+/* the channel locations we know right now. code below assumes U is in slot 0, X in 1, M in 2 */
static char *mnemonics[]={
- "U","M","L","C","R","CL","CR","SL","SR","BL","BC","BR","LFE",
+ "U","X","M",
+ "L","C","R","CL","CR","SL","SR","BL","BC","BR","LFE",
"A1","A2","A3","A4","A5","A6","A7","A8","A9",NULL
};
@@ -608,7 +609,8 @@
while(t>p && isspace(*(t-1)))t--;
while(mnemonics[m]){
- if(t-p && !strncmp(mnemonics[m],p,t-p)){
+ if(t-p && !strncmp(mnemonics[m],p,t-p) &&
+ strlen(mnemonics[m])==t-p){
if(count)strcat(ret,",");
strcat(ret,mnemonics[m]);
break;
@@ -647,7 +649,8 @@
while(*h && *h!=',')h++;
while(mnemonics[m]){
- if(!strncmp(mnemonics[needle],p,h-p))break;
+ if(!strncmp(mnemonics[needle],p,h-p) &&
+ strlen(mnemonics[needle])==h-p)break;
m++;
}
if(mnemonics[m])
@@ -786,8 +789,8 @@
/* find match in input if any */
device->permute_channels[count] = _find_channel(m,sformat.matrix);
if(device->permute_channels[count] == -1 && sformat.channels == 1){
- device->permute_channels[count] = _find_channel(1,sformat.matrix);
- mm=0;
+ device->permute_channels[count] = _find_channel(2,sformat.matrix);
+ mm=2;
}
}else
device->permute_channels[count] = -1;
@@ -799,8 +802,8 @@
count,mnemonics[m],device->permute_channels[count],
mnemonics[mm]);
}else{
- fprintf(stderr,"Output %d (%s)\t <- none\n",
- count,mnemonics[m]);
+ fprintf(stderr,"Output %d (%s)\t <- %s\n",
+ count,mnemonics[m],(m==1?"unavailable":"none"));
}
}
count++;
Modified: trunk/ao/src/plugins/alsa09/ao_alsa09.c
===================================================================
--- trunk/ao/src/plugins/alsa09/ao_alsa09.c 2010-01-26 07:33:24 UTC (rev 16816)
+++ trunk/ao/src/plugins/alsa09/ao_alsa09.c 2010-01-26 09:38:18 UTC (rev 16817)
@@ -107,10 +107,9 @@
int err;
/* Use nonblock flag when testing to avoid getting stuck if the device
- is in use. */
+ is in use. Try several devices, as 'default' usually means 'stereo only'. */
err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK);
-
if (err != 0)
return 0; /* Cannot use this plugin with default parameters */
else {
@@ -132,21 +131,16 @@
{
ao_alsa_internal *internal;
- internal = (ao_alsa_internal *) malloc(sizeof(ao_alsa_internal));
+ internal = (ao_alsa_internal *) calloc(1,sizeof(ao_alsa_internal));
- if (internal == NULL)
+ if (internal == NULL)
return 0;
-
+
internal->buffer_time = AO_ALSA_BUFFER_TIME;
internal->period_time = AO_ALSA_PERIOD_TIME;
internal->writei = AO_ALSA_WRITEI;
internal->access_mask = AO_ALSA_ACCESS_MASK;
- if (!(internal->dev = strdup("default"))) {
- free (internal);
- return 0;
- }
-
device->internal = internal;
return 1;
@@ -364,8 +358,42 @@
/* Open the ALSA device */
internal->cmd = "snd_pcm_open";
- err = snd_pcm_open(&(internal->pcm_handle), internal->dev,
- SND_PCM_STREAM_PLAYBACK, 0);
+ if(!internal->dev){
+ char *tmp=NULL;
+ /* we don't try just 'default' as it's a plug device that
+ will accept any number of channels but usually plays back
+ everything as stereo. */
+ switch(format->channels){
+ default:
+ case 8:
+ case 7:
+ err = snd_pcm_open(&(internal->pcm_handle), tmp="surround71",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if(err==0)break;
+ /* fall through */
+ case 6:
+ case 5:
+ case 4:
+ case 3:
+ err = snd_pcm_open(&(internal->pcm_handle), tmp="surround51",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if(err==0)break;
+ err = snd_pcm_open(&(internal->pcm_handle), tmp="surround40",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if(err==0)break;
+ /* fall through */
+ case 2:
+ case 1:
+ err = snd_pcm_open(&(internal->pcm_handle), tmp="default",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ if(err==0)break;
+ err = snd_pcm_open(&(internal->pcm_handle), tmp="hw:0",
+ SND_PCM_STREAM_PLAYBACK, 0);
+ }
+ if(err==0)internal->dev=strdup(tmp);
+ }else
+ err = snd_pcm_open(&(internal->pcm_handle), internal->dev,
+ SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0) {
internal->pcm_handle = NULL;
goto error;
@@ -385,9 +413,22 @@
if (format->bits > 8)
device->driver_byte_format = device->client_byte_format;
- if(!device->output_matrix)
- device->output_matrix=strdup("L,R,BL,BR,C,LFE,SL,SR");
+ if(device->verbose>0)
+ fprintf(stderr,"Using alsa device '%s'\n", internal->dev);
+ if(!device->output_matrix){
+ if(!strncasecmp(internal->dev,"plug:",5))
+ if(format->channels>2 && device->verbose>=0)
+ fprintf(stderr,"\nWARNING: No way to determine hardware channel mapping of\n"
+ "ALSA 'plug:' devices.\n");
+ if(!strcasecmp(internal->dev,"default")){
+ if(format->channels>2 && device->verbose>=0)
+ fprintf(stderr,"\nWARNING: ALSA 'default' device plays only L,R channels.\n");
+ device->output_matrix=strdup("L,R,X,X,X,X,X,X,X,X,X");
+ }else
+ device->output_matrix=strdup("L,R,BL,BR,C,LFE,SL,SR");
+ }
+
return 1;
error:
More information about the commits
mailing list