=?UTF-8?Q?J=C3=B6rg=20H=C3=B6hle=20?=: winmm: Fix conversion to MMTIME, avoid floating point arithmetic.

Alexandre Julliard julliard at winehq.org
Thu Jan 5 15:24:43 CST 2012


Module: wine
Branch: master
Commit: 9ef4a0099c95abf458f22d29c73b8421a33546b6
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=9ef4a0099c95abf458f22d29c73b8421a33546b6

Author: Jörg Höhle <hoehle at users.sourceforge.net>
Date:   Wed Jan  4 20:54:48 2012 +0100

winmm: Fix conversion to MMTIME, avoid floating point arithmetic.

---

 dlls/winmm/tests/wave.c |    8 ++++----
 dlls/winmm/waveform.c   |   27 ++++++++++-----------------
 2 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/dlls/winmm/tests/wave.c b/dlls/winmm/tests/wave.c
index 55bd8be..a7614a5 100644
--- a/dlls/winmm/tests/wave.c
+++ b/dlls/winmm/tests/wave.c
@@ -471,10 +471,10 @@ DWORD time_to_bytes(LPMMTIME mmtime, LPWAVEFORMATEX pwfx)
     else if (mmtime->wType == TIME_MS)
         return mmtime->u.ms * pwfx->nAvgBytesPerSec / 1000;
     else if (mmtime->wType == TIME_SMPTE)
-        return ((mmtime->u.smpte.hour * 60.0 * 60.0) +
-                (mmtime->u.smpte.min * 60.0) +
-                (mmtime->u.smpte.sec) +
-                (mmtime->u.smpte.frame / 30.0)) * pwfx->nAvgBytesPerSec;
+        return ((mmtime->u.smpte.hour * 60 * 60) +
+                (mmtime->u.smpte.min * 60) +
+                (mmtime->u.smpte.sec)) * pwfx->nAvgBytesPerSec +
+                mmtime->u.smpte.frame  * pwfx->nAvgBytesPerSec / 30;
 
     trace("FIXME: time_to_bytes() type not supported\n");
     return -1;
diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c
index 041b63f..b940b4f 100644
--- a/dlls/winmm/waveform.c
+++ b/dlls/winmm/waveform.c
@@ -1723,32 +1723,25 @@ static MMRESULT WINMM_FramesToMMTime(MMTIME *time, UINT32 played_frames,
         time->u.sample = played_frames;
         return MMSYSERR_NOERROR;
     case TIME_MS:
-        time->u.ms = (DWORD)((played_frames / (double)sample_rate) * 1000);
+        time->u.ms = (UINT64)played_frames * 1000 / sample_rate;
         return MMSYSERR_NOERROR;
     case TIME_SMPTE:
         time->u.smpte.fps = 30;
-        if(played_frames >= sample_rate){
-            time->u.smpte.sec = played_frames / (double)sample_rate;
-            time->u.smpte.min = time->u.smpte.sec / 60;
-            time->u.smpte.hour = time->u.smpte.min / 60;
-            time->u.smpte.sec %= 60;
-            time->u.smpte.min %= 60;
-            played_frames %= sample_rate;
-        }else{
-            time->u.smpte.sec = 0;
-            time->u.smpte.min = 0;
-            time->u.smpte.hour = 0;
-        }
-        time->u.smpte.frame = (played_frames / (double)sample_rate) * 30;
+        played_frames += sample_rate / time->u.smpte.fps - 1; /* round up */
+        time->u.smpte.frame = (played_frames % sample_rate) * time->u.smpte.fps / sample_rate;
+        played_frames /= sample_rate; /* yields seconds */
+        time->u.smpte.sec = played_frames % 60;
+        played_frames /= 60;
+        time->u.smpte.min = played_frames % 60;
+        time->u.smpte.hour= played_frames / 60;
         return MMSYSERR_NOERROR;
-    case TIME_BYTES:
     default:
         time->wType = TIME_BYTES;
+        /* fall through */
+    case TIME_BYTES:
         time->u.cb = played_frames * bytes_per_frame;
         return MMSYSERR_NOERROR;
     }
-
-    return MMSYSERR_ERROR;
 }
 
 static LRESULT WINMM_GetPosition(HWAVE hwave, MMTIME *time)




More information about the wine-cvs mailing list