/* prepare the audio device for playback */ int ao_plugin_open(ao_device *device, ao_sample_format *format) { ao_alsa_internal *internal = (ao_alsa_internal *) device->internal; int err; /* Get the ALSA bitformat first to make sure it's valid */ err = alsa_get_sample_bitformat(format->bits, device->client_byte_format == AO_FMT_BIG); if (err < 0) goto error; internal->bitformat = err; /* Open the ALSA device */ internal->cmd = "snd_pcm_open"; err = snd_pcm_open(&(internal->pcm_handle), internal->dev, SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) { internal->pcm_handle = NULL; goto error; } /* Set up the hardware parameters, ie sample and buffer specs */ err = alsa_set_hwparams(internal, format); if (err < 0) goto error; /* Set up the software parameters, ie de-buffering specs */ err = alsa_set_swparams(internal); if (err < 0) goto error; /* alsa's endinness will be the same as the application's */ if (format->bits > 8) device->driver_byte_format = device->client_byte_format; return 1; error: fprintf(stderr, "ALSA %s error: %s\n", internal->cmd, snd_strerror(err)); if (internal->pcm_handle) { snd_pcm_close(internal->pcm_handle); internal->pcm_handle = NULL; } return 0; }
/* prepare the audio device for playback */ int ao_plugin_open(ao_device *device, ao_sample_format *format) { ao_alsa_internal *internal = (ao_alsa_internal *) device->internal; int err,prebits; /* Get the ALSA bitformat first to make sure it's valid */ err = alsa_get_sample_bitformat(format->bits, device->client_byte_format == AO_FMT_BIG,device); if (err < 0){ aerror("Invalid byte format\n"); return 0; } internal->bitformat = err; /* Alsa can only use padded 24 bit formatting */ if(format->bits>16 && format->bits<=24){ internal->padbuffer = calloc(4096,1); internal->padoutw = 32; }else{ internal->padbuffer = 0; internal->padoutw = 0; } prebits = format->bits; /* Open the ALSA device */ err=0; if(!internal->dev){ if(internal->id<0){ 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(device->output_channels){ default: case 8: case 7: err = alsa_test_open(device, tmp="surround71", format); break; case 4: case 3: err = alsa_test_open(device, tmp="surround40", format); if(err==0)break; case 6: case 5: err = alsa_test_open(device, tmp="surround51", format); break; case 2: err = alsa_test_open(device, tmp="front", format); case 1: break; } if(err){ awarn("Unable to open surround playback. Trying default device...\n"); tmp=NULL; } if(!tmp) err = alsa_test_open(device, tmp="default", format); internal->dev=strdup(tmp); }else{ char tmp[80]; sprintf(tmp,"hw:%d",internal->id); internal->dev=strdup(tmp); err = alsa_test_open(device, internal->dev, format); } }else err = alsa_test_open(device, internal->dev, format); if (err < 0) { aerror("Unable to open ALSA device '%s' for playback => %s\n", internal->dev, snd_strerror(err)); return 0; } if(prebits != format->bits){ internal->padbuffer = calloc(4096,1); internal->padoutw = (format->bits+7)/8; format->bits=prebits; } adebug("Using ALSA device '%s'\n",internal->dev); { snd_pcm_sframes_t sframes; if(snd_pcm_delay (internal->pcm_handle, &sframes)){ internal->static_delay=0; }else{ internal->static_delay=sframes; } } /* save the sample size in bytes for posterity */ internal->sample_size = format->bits * device->output_channels / 8; /* alsa's endinness will be the same as the application's */ if (format->bits > 8) device->driver_byte_format = device->client_byte_format; if(strcasecmp(internal->dev,"default")){ if(strncasecmp(internal->dev,"surround",8)){ if(device->output_channels>2 && device->verbose>=0){ awarn("No way to determine hardware %d channel mapping of\n" "ALSA device '%s'.\n",device->output_channels, internal->dev); if(device->inter_matrix){ free(device->inter_matrix); device->inter_matrix=NULL; } } } } return 1; }