Robert Reif wrote:
I would just revert the patch and recalculate duration based on the fragment size. You need to keep the double because of integer overflow in the MS calculation
Well, it won't overflow for the tones we play because they just last a few seconds. But it will start overflowing when we reach 11 seconds so you're right, we should try to avoid that. Rewriting the way we compute samples will fix the first place where we could get an integer overflow: samples=bytes/(pwfx->wBitsPerSample/8*pwfx->nChannels); And since both TIME_MS and TIME_SMPTE essentially use the duration, I added a calculation of the duration, as a double obviously, near the top of check_position(). This fixes the second place where we could potentially get an overflow.
and integer underflow in the SMPTE calculation.
The SMPTE calculation is float-based so I don't see how we can get an 'integer underflow'.
We need to add a ceil to the frame calculation to round up partial frames.
That's done already. Changelog: * dlls/winmm/tests/wave.c Francois Gouget <fgouget(a)codeweavers.com> Make sure we won't get an overflow in check_position() even if we play longer test tones. -- Francois Gouget fgouget(a)codeweavers.com Index: dlls/winmm/tests/wave.c =================================================================== RCS file: /var/cvs/wine/dlls/winmm/tests/wave.c,v retrieving revision 1.34 diff -u -r1.34 wave.c --- dlls/winmm/tests/wave.c 20 Jul 2004 22:09:53 -0000 1.34 +++ dlls/winmm/tests/wave.c 20 Jul 2004 22:53:55 -0000 @@ -215,9 +230,11 @@ { MMTIME mmtime; DWORD samples; + double duration; MMRESULT rc; - samples=bytes*8/pwfx->wBitsPerSample/pwfx->nChannels; + samples=bytes/(pwfx->wBitsPerSample/8*pwfx->nChannels); + duration=((double)samples)/pwfx->nSamplesPerSec; mmtime.wType = TIME_BYTES; rc=waveOutGetPosition(wout, &mmtime, sizeof(mmtime)); @@ -246,9 +263,9 @@ ok(rc==MMSYSERR_NOERROR, "waveOutGetPosition: device=%s rc=%s\n",dev_name(device),wave_out_error(rc)); if (mmtime.wType == TIME_MS) - ok(mmtime.u.ms==samples*1000/pwfx->nSamplesPerSec, + ok(mmtime.u.ms==floor(duration*1000.0), "waveOutGetPosition returned %ld ms, should be %ld\n", - mmtime.u.ms, samples*1000/pwfx->nSamplesPerSec); + mmtime.u.ms, floor(duration*1000.0)); else trace("TIME_MS not supported, returned %s\n",wave_time_format(mmtime.wType)); @@ -258,7 +275,6 @@ "waveOutGetPosition: device=%s rc=%s\n",dev_name(device),wave_out_error(rc)); if (mmtime.wType == TIME_SMPTE) { - double duration=((double)samples)/pwfx->nSamplesPerSec; BYTE frames=ceil(fmod(duration*mmtime.u.smpte.fps, mmtime.u.smpte.fps)); ok(mmtime.u.smpte.hour==(BYTE)(floor(duration/(60*60))) && mmtime.u.smpte.min==(BYTE)(fmod(floor(duration/60), 60)) &&