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@codeweavers.com
Make sure we won't get an overflow in check_position() even if we
play longer test tones.
--
Francois Gouget
fgouget@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)) &&