[alsa-devel] snd_pcm_avail_update() needed before snd_pcm_delay() with hda-intel

Christian Morales Vega cmorve69 at yahoo.es
Thu Jun 12 20:32:51 CEST 2008


2008/6/12 Takashi Iwai <tiwai at suse.de>:
> It's unlikely a driver issue but an incompatibility of dmix, I guess.
> But still I don't figure out why this happens.  The hwsync is done at
> each snd_pcm_dmix_delay() call (as long as slowptr is set, and it's so
> as default).  So, there shouldn't be any difference...
>
> What happens if you use "hw" or "plughw"?
With both plughw and hw works fine.

If helps, I have simplified the problematic bsnes code into this:
#include <alsa/asoundlib.h>
#include <stdint.h>

int main(){
  snd_pcm_t *handle;

  unsigned length;

  unsigned frequency;
  snd_pcm_uframes_t buffer_size;
  snd_pcm_uframes_t period_size;

  if(snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0) < 0) {
    exit(1);
  }

  if(snd_pcm_set_params(handle, SND_PCM_FORMAT_S16_LE,
SND_PCM_ACCESS_RW_INTERLEAVED,
     2, 44100, 1, 100000) < 0) {
    exit(2);
  }

  if(snd_pcm_get_params(handle, &buffer_size, &period_size) < 0) {
    exit(3);
  }

  snd_output_t *setup;
  if (snd_output_stdio_attach(&setup, stdout, 0) < 0) {
    exit(4);
  }
  snd_pcm_dump_setup(handle, setup);

  uint32_t data[period_size];

  while(1){
    length = period_size;

    printf("State: %d\n", snd_pcm_state(handle));
    snd_pcm_sframes_t delay;
    //snd_pcm_avail_update(handle);
    snd_pcm_delay(handle, &delay);
    printf("Delay: %d\n", delay);
    if(delay < 0){
      snd_pcm_prepare(handle);
    }else if(delay > buffer_size - period_size) {
      printf("Delay/Goal: %d/%u\n", delay, buffer_size - period_size);
      length = 0;
      continue;
    }
    printf("Passed\n");

    uint32_t *buffer_ptr = data;
    do {
      snd_pcm_sframes_t written = snd_pcm_writei(handle, buffer_ptr, length);
      if(written < 0) {
        snd_pcm_recover(handle, written, 1);
      } else if(written < length) {
        //only some samples written
        length -= written;
        buffer_ptr += written;
      } else {
        //all samples written
        length = 0;
      }
    } while(length != 0);
  }
}


The listened effect is that when fails you listen the noise for just
buffer_time, and when works the noise never ends.


More information about the Alsa-devel mailing list