[linux-audio-dev] Set rate return zero

From: Huu Phuoc <phuocnh@email-addr-hidden>
Date: Sun Jul 09 2006 - 08:06:59 EEST

Hi everybody!
I am a newbie to alsa programming.
I am trying to follow the article which locates at
http://www.suse.de/~mana/alsa090_howto.html to develop a playback program.
My code here:
     snd_pcm_t*pcm_handle;
     unsigned int rate = 8000;
    // Sample rate returned by
    // snd_pcm_hw_params_set_rate_near
       int exact_rate;
     // exact_rate == rate ----> dir =0
    //exact_rate < rate ----> dir =-1
    //exact_rate > rate ----> dir =1
    int dir = 0;
    // Number of periods
        int periods = 2;
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
    // This structure contains information about the hardware
     //and can be used to specify the configuration to be used for the
PCM stream.
    snd_pcm_hw_params_t *hwparams;
       // Name of the PCM device, like plughw:0,0
    //The first number is the number of the soundcard,
        //the second number is the number of the device.
    char *pcm_name;
    // Init pcm_name. Of course, later you
    //will make this configurable ;-)
        pcm_name = strdup("plughw:0,0");
    printf("Device name:%s\n",pcm_name);
    //Allocate the snd_pcm_hw_params_t structure on the stack.
        snd_pcm_hw_params_alloca(&hwparams);
    // Open PCM. The last parameter of this function is the mode.
        // If this is set to 0, the standard mode is used. Possible
    // other values are SND_PCM_NONBLOCK and SND_PCM_ASYNC.
        // If SND_PCM_NONBLOCK is used, read / write access to the
        // PCM device will return immediately. If SND_PCM_ASYNC is
        // specified, SIGIO will be emitted whenever a period has
        //been completely processed by the soundcard.
        if (snd_pcm_open(&pcm_handle, pcm_name, stream, 0) <
0){//SND_PCM_NONBLOCK
          fprintf(stderr, "Error opening PCM device %s\n", pcm_name);
          return;
        }
     // Init hwparams with full configuration space
        if (snd_pcm_hw_params_any(pcm_handle, hwparams) < 0) {
          fprintf(stderr, "Can not configure this PCM device.\n");
          return;
        }
      // Set access type. This can be either
SND_PCM_ACCESS_RW_INTERLEAVED or
        // SND_PCM_ACCESS_RW_NONINTERLEAVED.There are also access types for
    // MMAPed access, but this is beyond the scope of this introduction.
    if (snd_pcm_hw_params_set_access(pcm_handle, hwparams,
SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
      fprintf(stderr, "Error setting access.\n");
      return;
    }
    //Set sample format
    if (snd_pcm_hw_params_set_format(pcm_handle, hwparams,
SND_PCM_FORMAT_S16_LE) < 0) {
      fprintf(stderr, "Error setting format.\n");
      return;
    }
    // Set sample rate. If the exact rate is not supported by the
hardware, use nearest possible rate.
     exact_rate = snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
&rate, &dir);
    if (exact_rate < 0) {
      fprintf(stderr, "Error setting rate.\n");
      return;
    }
    if (rate != exact_rate) {
      fprintf(stderr, "The rate %d Hz is not supported by your
hardware.\n=> Using %d Hz instead.\n", rate, exact_rate);
    }
    // Set number of channels
    if (snd_pcm_hw_params_set_channels(pcm_handle, hwparams, 2) < 0) {
      fprintf(stderr, "Error setting channels.\n");
      return;
    }
    // Set number of periods. Periods used to be called fragments.
    if (snd_pcm_hw_params_set_periods(pcm_handle, hwparams, periods, 0)
< 0)
   {
      fprintf(stderr, "Error setting periods.\n");
      return;
    }
    // Set buffer size (in frames). The resulting latency is given by
    // latency = periodsize * periods / (rate * bytes_per_frame)
    snd_pcm_uframes_t buffersize = ( snd_pcm_uframes_t )(
number_of_frames * periods );
    if (snd_pcm_hw_params_set_buffer_size_near(pcm_handle, hwparams,
&buffersize) < 0){
      fprintf(stderr, "Error setting buffersize.\n");
      return;
    }
    printf("Buffer size asked for %d, set %d \n",buffersize,exact_rate);
   // Apply HW parameter settings to
    // PCM device and prepare device
    if (snd_pcm_hw_params(pcm_handle, hwparams) < 0) {
      fprintf(stderr, "Error setting HW params.\n");
      return;
    }
  snd_pcm_prepare(pcm_handle);
Unfortunately, exact_rate is zero.The following lines were printed out:
The rate 8000 Hz is not supported by your hardware.
=> Using 0 Hz instead.
If exact_rate > 0 is OK but it is zero.
 I don't know how to solve the problem.
Please help me.
Thanks!
Phuoc Nguyen
Received on Sun Jul 9 08:15:01 2006

This archive was generated by hypermail 2.1.8 : Sun Jul 09 2006 - 08:15:01 EEST