[alsa-devel] snd_pcm_avail_update() needed before snd_pcm_delay() with hda-intel
snd_pcm_avail_update() documentation says: "Using of this function is useless for the standard read/write operations. Use it only for mmap access. See to snd_pcm_delay."
snd_pcm_delay() documentation says: "Note this function does not update the actual r/w pointer for applications. The function snd_pcm_avail_update() have to be called before any begin+commit operation."
My english is far from perfect, and so the problem can be that I missunderstood the docs but: 1- "Using of this function"? Should not be "Use of this function"? 2- Is snd_pcm_avail_update() really useless when not using mmap? I have a SB Live! where snd_pcm_delay() always returns the correct value, without any need for snd_pcm_avail_update(). But the same code in the same machine with an hda-intel AD1988 needs a call to snd_pcm_avail_update() before snd_pcm_delay() to give the correct result. Without it snd_pcm_delay() always returns the value that *was* correct in the last snd_pcm_writei() call.
So should the "application frame position" be always updated, or only in read/write operations? In the first case AD1988 fails, in the second case perhaps SB Live! is making too mucho work ;-)
On Fri, Jun 6, 2008 at 3:54 PM, Christian Morales Vega cmorve69@yahoo.es wrote:
snd_pcm_avail_update() documentation says: "Using of this function is useless for the standard read/write operations. Use it only for mmap access. See to snd_pcm_delay."
snd_pcm_delay() documentation says: "Note this function does not update the actual r/w pointer for applications. The function snd_pcm_avail_update() have to be called before any begin+commit operation."
My english is far from perfect, and so the problem can be that I missunderstood the docs but: 1- "Using of this function"? Should not be "Use of this function"?
I would just say "This function is useless for...".
2- Is snd_pcm_avail_update() really useless when not using mmap?
The pcm.c example referenced right below that comment would indicate otherwise:
http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#g41ca534658...
I have a SB Live! where snd_pcm_delay() always returns the correct value, without any need for snd_pcm_avail_update(). But the same code in the same machine with an hda-intel AD1988 needs a call to snd_pcm_avail_update() before snd_pcm_delay() to give the correct result. Without it snd_pcm_delay() always returns the value that *was* correct in the last snd_pcm_writei() call.
So should the "application frame position" be always updated, or only in read/write operations? In the first case AD1988 fails, in the second case perhaps SB Live! is making too mucho work ;-)
Is this with the latest ALSA HG sources?
The SBLive driver is better working and more mature, so I'd presume it to be correct. Takashi-san?
Lee
2008/6/7 Lee Revell:
2- Is snd_pcm_avail_update() really useless when not using mmap?
The pcm.c example referenced right below that comment would indicate otherwise:
snd_pcm_delay() was added after that example was created?
I have a SB Live! where snd_pcm_delay() always returns the correct value, without any need for snd_pcm_avail_update(). But the same code in the same machine with an hda-intel AD1988 needs a call to snd_pcm_avail_update() before snd_pcm_delay() to give the correct result. Without it snd_pcm_delay() always returns the value that *was* correct in the last snd_pcm_writei() call.
So should the "application frame position" be always updated, or only in read/write operations? In the first case AD1988 fails, in the second case perhaps SB Live! is making too mucho work ;-)
Rereading this... "application frame position" only is updated in read/write operations since is the only moment were it changes :-p The problem would be with the update of the "sound frame position".
Is this with the latest ALSA HG sources?
openSUSE Build Service multimedia:audio packages: - alsa-1.0.16.hg20080510 - libasound2-1.0.16.hg20080510 - alsa-driver-kmp-default-1.0.16.20080606_2.6.22.17_0.1
2008/6/7 Christian Morales Vega cmorve69@yahoo.es:
Is this with the latest ALSA HG sources?
openSUSE Build Service multimedia:audio packages:
- alsa-1.0.16.hg20080510
- libasound2-1.0.16.hg20080510
- alsa-driver-kmp-default-1.0.16.20080606_2.6.22.17_0.1
Since there have been a big update (a month, from 05-10 to 06-10), just note that with - alsa-1.0.17rc1.git20080610-1.1 - libasound2-1.0.17rc1.git20080610-1.2 - alsa-driver-kmp-default-1.0.16.20080611_2.6.22.17_0.1-1.1 that now really is something similar to the latest sources, the behavior is the same.
At Fri, 6 Jun 2008 20:46:12 -0400, Lee Revell wrote:
On Fri, Jun 6, 2008 at 3:54 PM, Christian Morales Vega cmorve69@yahoo.es wrote:
snd_pcm_avail_update() documentation says: "Using of this function is useless for the standard read/write operations. Use it only for mmap access. See to snd_pcm_delay."
snd_pcm_delay() documentation says: "Note this function does not update the actual r/w pointer for applications. The function snd_pcm_avail_update() have to be called before any begin+commit operation."
My english is far from perfect, and so the problem can be that I missunderstood the docs but: 1- "Using of this function"? Should not be "Use of this function"?
I would just say "This function is useless for...".
Patch please ;)
2- Is snd_pcm_avail_update() really useless when not using mmap?
The pcm.c example referenced right below that comment would indicate otherwise:
http://www.alsa-project.org/alsa-doc/alsa-lib/group___p_c_m.html#g41ca534658...
I have a SB Live! where snd_pcm_delay() always returns the correct value, without any need for snd_pcm_avail_update(). But the same code in the same machine with an hda-intel AD1988 needs a call to snd_pcm_avail_update() before snd_pcm_delay() to give the correct result. Without it snd_pcm_delay() always returns the value that *was* correct in the last snd_pcm_writei() call.
So should the "application frame position" be always updated, or only in read/write operations? In the first case AD1988 fails, in the second case perhaps SB Live! is making too mucho work ;-)
Is this with the latest ALSA HG sources?
The SBLive driver is better working and more mature, so I'd presume it to be correct. Takashi-san?
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"?
Takashi
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.
At Thu, 12 Jun 2008 20:32:51 +0200, Christian Morales Vega wrote:
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:
The program looks running fine on my machine with another HD-audio codec. What is expected in the output and how wrong on yours?
Takashi
2008/6/17 Takashi Iwai tiwai@suse.de:
At Thu, 12 Jun 2008 20:32:51 +0200, Christian Morales Vega wrote:
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:
The program looks running fine on my machine with another HD-audio codec. What is expected in the output and how wrong on yours?
I knew I should not put it under the code :-p "The listened effect is that when fails you listen the noise for just buffer_time, and when works the noise never ends."
So the output with the SB Live! is: State: 2 Delay: 0 Passed State: 2 Delay: 882 Passed State: 2 Delay: 1764 Passed State: 2 Delay: 2646 Passed State: 2 Delay: 3528 Passed State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4409 Delay/Goal: 4409/3528
and so until delay reaches 3528, when a new snd_pcm_writei() is done.
With the AD1988 the buffer is fulled one time. After that never again reaches snd_pcm_writei(). The output is: State: 2 Delay: 0 Passed State: 2 Delay: 940 Passed State: 2 Delay: 1880 Passed State: 2 Delay: 2820 Passed State: 2 Delay: 3760 Passed State: 3 Delay: 4700 Delay/Goal: 4700/3764 State: 3 Delay: 4700 Delay/Goal: 4700/3764 State: 3 Delay: 4700 Delay/Goal: 4700/3764
and so. Delay never decreases. But after some time you see. State: 4 Delay: 4700 Delay/Goal: 4700/3764
There has been an underrun even if appl_ptr is 4700 frames ahead of hw_ptr??? If you uncomment snd_pcm_avail_update() delay decreases and everything is ok.
2008/6/17 Christian Morales Vega cmorve69@yahoo.es:
2008/6/17 Takashi Iwai tiwai@suse.de:
At Thu, 12 Jun 2008 20:32:51 +0200, Christian Morales Vega wrote:
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:
The program looks running fine on my machine with another HD-audio codec. What is expected in the output and how wrong on yours?
I knew I should not put it under the code :-p "The listened effect is that when fails you listen the noise for just buffer_time, and when works the noise never ends."
So the output with the SB Live! is: State: 2 Delay: 0 Passed State: 2 Delay: 882 Passed State: 2 Delay: 1764 Passed State: 2 Delay: 2646 Passed State: 2 Delay: 3528 Passed State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4409 Delay/Goal: 4409/3528
and so until delay reaches 3528, when a new snd_pcm_writei() is done.
With the AD1988 the buffer is fulled one time. After that never again reaches snd_pcm_writei(). The output is: State: 2 Delay: 0 Passed State: 2 Delay: 940 Passed State: 2 Delay: 1880 Passed State: 2 Delay: 2820 Passed State: 2 Delay: 3760 Passed State: 3 Delay: 4700 Delay/Goal: 4700/3764 State: 3 Delay: 4700 Delay/Goal: 4700/3764 State: 3 Delay: 4700 Delay/Goal: 4700/3764
and so. Delay never decreases. But after some time you see. State: 4 Delay: 4700 Delay/Goal: 4700/3764
There has been an underrun even if appl_ptr is 4700 frames ahead of hw_ptr??? If you uncomment snd_pcm_avail_update() delay decreases and everything is ok.
I still have the same problem with alsa-1.0.19.git20090122-1.1 and alsa-driver-kmp-default-1.0.19.20090123_2.6.27.7_9.1-3.1 on openSUSE 11.1. Exactly same behavior: works with emu10k1, works with plughw... only doesn't works when using AD1988 and "default:1" device.
Also reading Lennart Poettering discussion about snd_pcm_avail_update, snd_pcm_delay, etc I see bsnes is wrongly using snd_pcm_delay(). But I don't understand the snd_pcm_avail() vs snd_pcm_avail_update(). If snd_pcm_avail_update() doesn't calls hwsync the info it will return will be outdated/unuseful, will not? And how it is a call to snd_pcm_avail_update() fixes the problem I'm having here with snd_pcm_delay()? My problem isn't precisely the lack of a hwsync in snd_pcm_delay()? In snd_pcm_avail_update() doc: "The position is not synced with hardware (driver) position in the sound ring buffer in this function." isn't a contradiction with "Also this function might be called after snd_pcm_delay() or snd_pcm_hwsync() functions to move private ring buffer pointers in alsa-lib (the internal plugin chain)."? Probably I'm missunderstanding something. If snd_pcm_avail_update() isn't updating the same thing that snd_pcm_hwsync(), what it is updating?
2009/1/23 Cristian Morales Vega cmorve69@yahoo.es:
2008/6/17 Christian Morales Vega cmorve69@yahoo.es:
2008/6/17 Takashi Iwai tiwai@suse.de:
At Thu, 12 Jun 2008 20:32:51 +0200, Christian Morales Vega wrote:
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:
The program looks running fine on my machine with another HD-audio codec. What is expected in the output and how wrong on yours?
I knew I should not put it under the code :-p "The listened effect is that when fails you listen the noise for just buffer_time, and when works the noise never ends."
So the output with the SB Live! is: State: 2 Delay: 0 Passed State: 2 Delay: 882 Passed State: 2 Delay: 1764 Passed State: 2 Delay: 2646 Passed State: 2 Delay: 3528 Passed State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4410 Delay/Goal: 4410/3528 State: 3 Delay: 4409 Delay/Goal: 4409/3528
and so until delay reaches 3528, when a new snd_pcm_writei() is done.
With the AD1988 the buffer is fulled one time. After that never again reaches snd_pcm_writei(). The output is: State: 2 Delay: 0 Passed State: 2 Delay: 940 Passed State: 2 Delay: 1880 Passed State: 2 Delay: 2820 Passed State: 2 Delay: 3760 Passed State: 3 Delay: 4700 Delay/Goal: 4700/3764 State: 3 Delay: 4700 Delay/Goal: 4700/3764 State: 3 Delay: 4700 Delay/Goal: 4700/3764
and so. Delay never decreases. But after some time you see. State: 4 Delay: 4700 Delay/Goal: 4700/3764
There has been an underrun even if appl_ptr is 4700 frames ahead of hw_ptr??? If you uncomment snd_pcm_avail_update() delay decreases and everything is ok.
I still have the same problem with alsa-1.0.19.git20090122-1.1 and alsa-driver-kmp-default-1.0.19.20090123_2.6.27.7_9.1-3.1 on openSUSE 11.1. Exactly same behavior: works with emu10k1, works with plughw... only doesn't works when using AD1988 and "default:1" device.
Also reading Lennart Poettering discussion about snd_pcm_avail_update, snd_pcm_delay, etc I see bsnes is wrongly using snd_pcm_delay(). But I don't understand the snd_pcm_avail() vs snd_pcm_avail_update(). If snd_pcm_avail_update() doesn't calls hwsync the info it will return will be outdated/unuseful, will not? And how it is a call to snd_pcm_avail_update() fixes the problem I'm having here with snd_pcm_delay()? My problem isn't precisely the lack of a hwsync in snd_pcm_delay()? In snd_pcm_avail_update() doc: "The position is not synced with hardware (driver) position in the sound ring buffer in this function." isn't a contradiction with "Also this function might be called after snd_pcm_delay() or snd_pcm_hwsync() functions to move private ring buffer pointers in alsa-lib (the internal plugin chain)."? Probably I'm missunderstanding something. If snd_pcm_avail_update() isn't updating the same thing that snd_pcm_hwsync(), what it is updating?
Forget the last part. I suppose I just need to use snd_pcm_avail() instead of snd_pcm_avail_update() if using mmap, true?
Only the "snd_pcm_delay() return value isn't updated" part is important.
participants (4)
-
Christian Morales Vega
-
Cristian Morales Vega
-
Lee Revell
-
Takashi Iwai