2008/6/12 Takashi Iwai tiwai@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.