コード例 #1
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;

	/* 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;
}
コード例 #2
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;
}