[alsa-devel] Playback Devices in PREPARED State Throw Off POLLOUT Events?
A question re normal internal operation of ALSA.
I'm using the poll() interface to wait for a audio playback device to ask for more samples. The device is in the PREPARED state, not RUNNING state. At the beginning of my program, _before_ I write any samples to it, I'm getting repeated POLLOUT events, when I do not yet have data available to send. They seem to come frequent enough to load down my CPU, rather than every N ticks, so it seems.
I thought a device was idle in the PREPARED state, and you had to either set the start conditions and write data, or explicitly invoke snd_pcm_start(). In my case, I wanted to use snd_pcm_start() once I had data to send, and also used the start conditions, set at 50%, to cause the audio output to them proceed to the speaker.
The output snd_pcm_status_dump() right after exiting from the very first poll() ever in the program shows the following, and that I have a POLLOUT event pending.
--- Status of Headphones Player ---
state : PREPARED
trigger_time: 0.000000
tstamp : 1176119509.658821000
delay : 0
avail : 2400
avail_max : 0
POLLOUT fired, calling ready_for_write()
I suppose I could force it back to an earlier state like SND_PCM_STATE_OPEN or SND_PCM_STATE_SETUP, but that seems a bit harsh, since the snd_pcm_hw_params() takes it to the SND_PCM_STATE_PREPARED itself.
Thanks for any tips,
-Jeff
At Mon, 09 Apr 2007 07:46:47 -0500, Jeff Rush wrote:
A question re normal internal operation of ALSA.
I'm using the poll() interface to wait for a audio playback device to ask for more samples. The device is in the PREPARED state, not RUNNING state. At the beginning of my program, _before_ I write any samples to it, I'm getting repeated POLLOUT events, when I do not yet have data available to send. They seem to come frequent enough to load down my CPU, rather than every N ticks, so it seems.
I thought a device was idle in the PREPARED state, and you had to either set the start conditions and write data, or explicitly invoke snd_pcm_start(). In my case, I wanted to use snd_pcm_start() once I had data to send, and also used the start conditions, set at 50%, to cause the audio output to them proceed to the speaker.
The output snd_pcm_status_dump() right after exiting from the very first poll() ever in the program shows the following, and that I have a POLLOUT event pending.
--- Status of Headphones Player ---
state : PREPARED
trigger_time: 0.000000
tstamp : 1176119509.658821000
delay : 0
avail : 2400
avail_max : 0
POLLOUT fired, calling ready_for_write()
I suppose I could force it back to an earlier state like SND_PCM_STATE_OPEN or SND_PCM_STATE_SETUP, but that seems a bit harsh, since the snd_pcm_hw_params() takes it to the SND_PCM_STATE_PREPARED itself.
When the playback PCM is in the PREPARED state, it's actually ready for getting data and trigger. Thus poll() returns POLLOUT. Its logic is clear.
I think you should change the program design. The data should have been prepared before poll. Or, if the flow is like: poll -> fetch data -> write data then you need some error control between fetch data and write data, for example, simply wait some time when no data is ready.
Takashi
Takashi Iwai wrote:
At Mon, 09 Apr 2007 07:46:47 -0500, Jeff Rush wrote:
I thought a device was idle in the PREPARED state, and you had to either set the start conditions and write data, or explicitly invoke snd_pcm_start(). In my case, I wanted to use snd_pcm_start() once I had data to send, and also used the start conditions, set at 50%, to cause the audio output to them proceed to the speaker.
When the playback PCM is in the PREPARED state, it's actually ready for getting data and trigger. Thus poll() returns POLLOUT. Its logic is clear.
Is this the purpose of the "tick" value that can be manipulated by the ALSA API - in that every "tick" the poll() function will return with POLLOUT to check for more data to be sent?
I've read the ALSA docs very carefully, and while they document the arguments and have one-liner descriptions, how the start/stop/tick/etc. pieces interact behind the scenes, the semantics as it were, isn't always clear to me.
I think you should change the program design. The data should have been prepared before poll. Or, if the flow is like: poll -> fetch data -> write data then you need some error control between fetch data and write data, for example, simply wait some time when no data is ready.
Thanks, I've got it working now. The application is for screencasting, where I want to grab both the mic input on which I'm speaking, merged with the "monitor" input back from the output of my sound card, and then deliver that to my headphones so I can hear myself, and also save it via a popen() pipe into the "sox" utility and then on to a .wav, mp3, or ogg file.
I get the monitor audio by running the PulseAudio software, which can export an ALSA input device that represents what is being played out the system speakers by other ALSA, OSS or ESD client programs.
However, since this monitor audio isn't running all the time, i.e. there isn't always something making system sounds so there are too few POLLINs, but the microphone -is- always running with silence or voice, I handled the case of POLLOUTs for the headphones by always having at least microphone data to feed it. Essentially the mic POLLINs 'smooth out' the overall timing.
-Jeff
Jeff Rush wrote:
Takashi Iwai wrote:
When the playback PCM is in the PREPARED state, it's actually ready for getting data and trigger. Thus poll() returns POLLOUT. Its logic is clear.
Is this the purpose of the "tick" value that can be manipulated by the ALSA API - in that every "tick" the poll() function will return with POLLOUT to check for more data to be sent?
An output device is ready whenever there is some free space in the device's ring buffer. poll() checks the amount of free space when it's called and when interrupts occur, i.e., at period boundaries.
If by "tick" you meant "period", the answer is yes.
HTH Clemens
Clemens Ladisch wrote:
Jeff Rush wrote:
Takashi Iwai wrote:
When the playback PCM is in the PREPARED state, it's actually ready for getting data and trigger. Thus poll() returns POLLOUT. Its logic is clear.
Is this the purpose of the "tick" value that can be manipulated by the ALSA API - in that every "tick" the poll() function will return with POLLOUT to check for more data to be sent?
An output device is ready whenever there is some free space in the device's ring buffer. poll() checks the amount of free space when it's called and when interrupts occur, i.e., at period boundaries.
If by "tick" you meant "period", the answer is yes.
I apologize for not using actual function names. When I said "tick", I meant these:
int snd_pcm_hw_params_get_tick_time() "Extract tick time from a configuration space."
int snd_pcm_hw_params_get_tick_time_max() "Extract maximum tick time from a configuration space."
int snd_pcm_hw_params_get_tick_time_min() "Extract minimum tick time from a configuration space."
From those descriptions, I've not yet been able to figure out how ticks fit into the overall system. The only longer description I found was:
"Minimal sleep
This parameters means the minimum of ticks to sleep using a standalone timer (usually the system timer). The tick resolution can be obtained via the function snd_pcm_hw_params_get_tick_time(). This function can be used to fine-tune the transfer acknowledge process. It could be useful especially when some hardware does not support small transfer periods."
I interpreted the phrase "to fine-tune the transfer acknowledge process" to mean adjusting the time between poll() returns re POLLOUT (and POLLIN) intervals. Since you've told me that instead that is controlled by the period setting, i.e. snd_pcm_hw_params_set_period_time(), not the tick setting, I'm again wondering what ticks are for, especially since they are not settable, only gettable.
-Jeff
At Fri, 13 Apr 2007 04:29:48 -0500, Jeff Rush wrote:
Clemens Ladisch wrote:
Jeff Rush wrote:
Takashi Iwai wrote:
When the playback PCM is in the PREPARED state, it's actually ready for getting data and trigger. Thus poll() returns POLLOUT. Its logic is clear.
Is this the purpose of the "tick" value that can be manipulated by the ALSA API - in that every "tick" the poll() function will return with POLLOUT to check for more data to be sent?
An output device is ready whenever there is some free space in the device's ring buffer. poll() checks the amount of free space when it's called and when interrupts occur, i.e., at period boundaries.
If by "tick" you meant "period", the answer is yes.
I apologize for not using actual function names. When I said "tick", I meant these:
int snd_pcm_hw_params_get_tick_time() "Extract tick time from a configuration space."
int snd_pcm_hw_params_get_tick_time_max() "Extract maximum tick time from a configuration space."
int snd_pcm_hw_params_get_tick_time_min() "Extract minimum tick time from a configuration space."
From those descriptions, I've not yet been able to figure out how ticks fit into the overall system. The only longer description I found was:
"Minimal sleep This parameters means the minimum of ticks to sleep using a standalone timer (usually the system timer). The tick resolution can be obtained via the function snd_pcm_hw_params_get_tick_time(). This function can be used to fine-tune the transfer acknowledge process. It could be useful especially when some hardware does not support small transfer periods."
I interpreted the phrase "to fine-tune the transfer acknowledge process" to mean adjusting the time between poll() returns re POLLOUT (and POLLIN) intervals. Since you've told me that instead that is controlled by the period setting, i.e. snd_pcm_hw_params_set_period_time(), not the tick setting, I'm again wondering what ticks are for, especially since they are not settable, only gettable.
This tick isn't so useful in practice, so you can forget it. I think we can deprecate this feature in future.
Basically, this can give you more frequent interrupts, especially if the sound hardware cannot have a small period size. Suppose your hardware has minimal period size 32768, which is fairly big. On such a hardware, you'll get irqs less than twice per second with 48kHz. This means that the update of hardware status is done so seldom, because the update function (snd_pcm_period_elapsed()) is called from the irq handler. When the tick is set with small time, e.g. 10ms, then a system timer gives more frequent chance to update _additionally_.
OTOH, the condition that poll returns is defined only via avail_min and timeout settings. The frequent irqs may result in more accurate poll timing, but it doesn't change the semantics.
Takashi
participants (3)
-
Clemens Ladisch
-
Jeff Rush
-
Takashi Iwai