At Fri, 14 Dec 2007 12:40:04 -0500, Dave Dillow wrote: > > On Fri, Dec 14, 2007 at 04:39:37PM +0100, Takashi Iwai wrote: > > At Sat, 08 Dec 2007 15:58:40 -0500, > > Dave Dillow wrote: > > > > > > While working with Fernando to get the sis7019 driver working in his > > > buildroot setup, we kept running into a lockup of the PCM stream when > > > using speaker-test. aplay was fine, as was other I finally tracked it > > > down to a combination of uclibc not doing block reads, which led to > > > XRUNs, and what I thought was issue in snd_pcm_lib_write1() when trying > > > to fill up the tail of the PCM buffer with a large write, when there was > > > an intervening small write. > > > > > > As it turns out, the lockup problem may simply be in speaker-write's > > > sw_params settings -- it calls snd_pcm_sw_params_set_avail_min() to set > > > the minium write to the period size, and > > > snd_pcm_sw_params_set_start_threshold() to start once the buffer has > > > been filled. This doesn't account for odd wave file lengths and XRUNs. > > > > > > The problem arises when the wave data is not a multiple of the period > > > size, and you get an XRUN when there is less than buffer_size samples > > > remaining in the current loop. > > > > Hm, it sounds weird. Basically XRUN means that you have *no* data in > > the buffer while the stream is running. So, when you get XRUN, the > > data must be empty, no matter which buffer or period size is. > > Right, the buffer empties, and then the loop in speaker-test::write_buffer() > starts filling the buffer again, as expected. > > However, the sample data in the wave file is not a multiple of the buffer > size, so it does a small write (ie, not period sized) to finish out the file, > and the main routine calls back in to do the next loop. > > So, you get a pattern (buffer_size is 32768): > > write len buffer available before write > XRUN happens N/A > 8192 32768 > 8192 24576 > 5506 16384 > 8192 10878 > 8192 2686 > > Because speaker-test sets avail_min to 8192, and the start threshold to > 32768, snd_pcm_lib_write1() will loop forever waiting for 8192 bytes to > become available in the buffer. That will never happen, because the XRUN > stopped the channel, and we cannot reach the start threshold, as this last > write that would do it is the one that blocked. OK, point taken. It's a problem in the PCM core indeed. The patch below should solve the problem, but it's ad hoc. Takashi diff -r 6f193b381db3 core/pcm_lib.c --- a/core/pcm_lib.c Wed Dec 19 12:13:44 2007 +0100 +++ b/core/pcm_lib.c Wed Dec 19 14:36:04 2007 +0100 @@ -1655,8 +1655,11 @@ static snd_pcm_sframes_t snd_pcm_lib_wri if (runtime->sleep_min == 0 && runtime->status->state == SNDRV_PCM_STATE_RUNNING) snd_pcm_update_hw_ptr(substream); avail = snd_pcm_playback_avail(runtime); - if (((avail < runtime->control->avail_min && size > avail) || - (size >= runtime->xfer_align && avail < runtime->xfer_align))) { + if (!avail || + (snd_pcm_running(substream) && + ((avail < runtime->control->avail_min && size > avail) || + (size >= runtime->xfer_align && + avail < runtime->xfer_align)))) { wait_queue_t wait; enum { READY, SIGNALED, ERROR, SUSPENDED, EXPIRED, DROPPED } state; long tout; _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel