--- pcm.c.old 2007-11-04 17:57:01.000000000 +0300 +++ pcm.c 2007-11-07 21:34:59.000000000 +0300 @@ -6465,19 +6465,35 @@ goto _end; } if ((state == SND_PCM_STATE_RUNNING && - (snd_pcm_uframes_t)avail < pcm->avail_min && size > (snd_pcm_uframes_t)avail) || (size >= pcm->xfer_align && (snd_pcm_uframes_t)avail < pcm->xfer_align)) { + snd_pcm_sframes_t avail_min, orig_avail_min; + snd_pcm_sw_params_t params; if (pcm->mode & SND_PCM_NONBLOCK) { err = -EAGAIN; goto _end; } + avail_min = (size < pcm->period_size ? + size : pcm->period_size); + orig_avail_min = pcm->avail_min; + if (avail_min != pcm->avail_min) { + snd_pcm_sw_params_current(pcm, ¶ms); + params.avail_min = avail_min; + snd_pcm_sw_params(pcm, ¶ms); + } + err = snd_pcm_wait(pcm, -1); if (err < 0) break; + + if (orig_avail_min != pcm->avail_min) { + params.avail_min = orig_avail_min; + snd_pcm_sw_params(pcm, ¶ms); + } + goto _again; } if ((snd_pcm_uframes_t) avail > pcm->xfer_align)