Let packetsize = arts_stream_get(wwo->play_stream, ARTS_P_PACKET_SIZE),
if an application only write packetsize-1 (or less) bytes of data into the sound driver, these data won't be played, and the position of KDE aRts's play cursor remains 0. What happens in wine aRts then?
1. The application wait for an event after writing the data.
2. wodPlayer_FeedDSP ran out of data and update the wine aRts's play position to write position (packetsize-1).
2. As play position has been updated, wodPlayer_NotifyCompletions may send a notification to the application.
3. But when the application try to retrieve the play position,
wodUpdatePlayedTotal is called and update the play position to 0. Thus, if the application's buffer is less than packetsize, it will detect a buffer underrun problem.
If somebody want to keep wodUpdatePlayedTotal simple, he can just return TRUE, and let wodPlayer_FeedDSP update the play position. :-)
Index: dlls/winmm/winearts/audio.c =================================================================== RCS file: /home/wine/wine/dlls/winmm/winearts/audio.c,v retrieving revision 1.10 diff -u -r1.10 audio.c --- dlls/winmm/winearts/audio.c 23 Jan 2003 22:51:04 -0000 1.10 +++ dlls/winmm/winearts/audio.c 30 Mar 2003 11:07:58 -0000 @@ -475,9 +475,21 @@ static BOOL wodUpdatePlayedTotal(WINE_WAVEOUT* wwo) { /* total played is the bytes written less the bytes to write ;-) */ +#if 0 wwo->dwPlayedTotal = wwo->dwWrittenTotal - (wwo->dwBufferSize - arts_stream_get(wwo->play_stream, ARTS_P_BUFFER_SPACE)); +#else + /* Maybe other functions like wodPlayer_FeedDSP updated dwPlayedTotal, + * and wodPlayer_NotifyCompletions might have already sent a notification + * according to dwPlayedTotal, we can't back play cursor here. */ + DWORD dwPlayed; + dwPlayed = wwo->dwWrittenTotal - + (wwo->dwBufferSize - + arts_stream_get(wwo->play_stream, ARTS_P_BUFFER_SPACE)); + if (wwo->dwPlayedTotal <= dwPlayed) + wwo->dwPlayedTotal = dwPlayed; +#endif return TRUE; }