On 10/30/18 14:21, Takashi Iwai wrote:
Yes, and is this correct? Suppose you start a stream at the position one sample before the next period (psize * N + (psize-1)). Then slave_hw_ptr is psize * N. At the next moment, the dpcm->hw.ptr reaches to psize * (N+1), and snd_pcm_dmix_sync_ptr() gets called. Then slave_hw_ptr will be updated to psize * (N+1) although only one sample has been processed?
I have created a spreadsheet to simulate the behavior of dmix (see attachment). I used this sheet to test different corner cases with different implementations. Column B-D describes 3 corner cases with the original implementation. Column E-H describes the corner cases with patch v2 applied and column I-L describes the corner cases with patch v3. With patch v3 I was not able to find a corner case which would fail. All our internal audio test are also passing fine.
The corner cases are described in the form N*period+period-1 (N+1)period+1 (N+2)period+1
The first line describes the value of dmix->spcm->hw.ptr when snd_pcm_dmix_start() will be called. The second line describes the hw_ptr when poll() returns for the first time and the third line describes the hw_ptr when poll() returns for the second time.
In column B is the issue case described when the patch is not applied. snd_pcm_avail() returns 2 frames only (B27) but the buffer only contains 3 frames (B18). Therefore up to 5 frames are available (a buffer size of 8 frames is choosen).
The issue case of patch v2 is shown in column H. snd_pcm_avail() returns 7 frames (H46) but the buffer contains still 3 frames (H37). Therefore there are only 5 frames free to overwrite.
Do you see any corner cases which I missed or any other drawbacks?
Best regards and thanks for your time
Timo