Fix calculation of SMPTE time (round up to full frame).
More accurate ms calculation.

diff --git a/dlls/winmm/winealsa/audio.c b/dlls/winmm/winealsa/audio.c
index 0cc0fe1..f170202 100644
--- a/dlls/winmm/winealsa/audio.c
+++ b/dlls/winmm/winealsa/audio.c
@@ -1831,7 +1831,7 @@
  */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     DWORD		val;
     WINE_WAVEOUT*	wwo;
 
@@ -1864,14 +1864,14 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / (60 * 60 * 1000);
-	time -= lpTime->u.smpte.hour * (60 * 60 * 1000);
-	lpTime->u.smpte.min = time / (60 * 1000);
-	time -= lpTime->u.smpte.min * (60 * 1000);
-	lpTime->u.smpte.sec = time / 1000;
-	time -= lpTime->u.smpte.sec * 1000;
-	lpTime->u.smpte.frame = time * 30 / 1000;
+	time = (double)val / (double)wwo->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -1881,7 +1881,7 @@
 	FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = val * 1000.0 / wwo->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }
@@ -3334,7 +3334,7 @@
  */
 static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     WINE_WAVEIN*	wwi;
 
     FIXME("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
@@ -3365,15 +3365,15 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = wwi->dwTotalRecorded /
-	    (wwi->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / (60 * 60 * 1000);
-	time -= lpTime->u.smpte.hour * (60 * 60 * 1000);
-	lpTime->u.smpte.min = time / (60 * 1000);
-	time -= lpTime->u.smpte.min * (60 * 1000);
-	lpTime->u.smpte.sec = time / 1000;
-	time -= lpTime->u.smpte.sec * 1000;
-	lpTime->u.smpte.frame = time * 30 / 1000;
+	time = (double)wwi->dwTotalRecorded /
+	    (double)wwi->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -3383,8 +3383,8 @@
 	FIXME("format not supported (%u) ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = wwi->dwTotalRecorded /
-	    (wwi->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = wwi->dwTotalRecorded * 1000.0 /
+	    wwi->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }
diff --git a/dlls/winmm/winearts/audio.c b/dlls/winmm/winearts/audio.c
index 48f5c61..5e9a3d8 100644
--- a/dlls/winmm/winearts/audio.c
+++ b/dlls/winmm/winearts/audio.c
@@ -39,6 +39,7 @@
 
 #include "config.h"
 
+#include <math.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <stdio.h>
@@ -1384,7 +1385,7 @@
  */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     DWORD		val;
     WINE_WAVEOUT*	wwo;
 
@@ -1419,14 +1420,14 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / (60 * 60 * 1000);
-	time -= lpTime->u.smpte.hour * (60 * 60 * 1000);
-	lpTime->u.smpte.min = time / (60 * 1000);
-	time -= lpTime->u.smpte.min * (60 * 1000);
-	lpTime->u.smpte.sec = time / 1000;
-	time -= lpTime->u.smpte.sec * 1000;
-	lpTime->u.smpte.frame = time * 30 / 1000;
+	time = (double)val / (double)wwo->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -1436,7 +1437,7 @@
 	FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = val * 1000.0 / wwo->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }
diff --git a/dlls/winmm/wineaudioio/audio.c b/dlls/winmm/wineaudioio/audio.c
index fd55e62..22a63a5 100644
--- a/dlls/winmm/wineaudioio/audio.c
+++ b/dlls/winmm/wineaudioio/audio.c
@@ -1082,7 +1082,7 @@
  */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     DWORD		val;
     WINE_WAVEOUT*	wwo;
 
@@ -1114,14 +1114,14 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / 108000;
-	time -= lpTime->u.smpte.hour * 108000;
-	lpTime->u.smpte.min = time / 1800;
-	time -= lpTime->u.smpte.min * 1800;
-	lpTime->u.smpte.sec = time / 30;
-	time -= lpTime->u.smpte.sec * 30;
-	lpTime->u.smpte.frame = time;
+	time = (double)val / (double)wwo->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -1131,7 +1131,7 @@
 	FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = val * 1000.0 / wwo->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }
@@ -2205,7 +2205,7 @@
  */
 static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     WINE_WAVEIN*	wwi;
 
     TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
@@ -2234,23 +2234,23 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = wwi->dwTotalRecorded /
-	    (wwi->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / 108000;
-	time -= lpTime->u.smpte.hour * 108000;
-	lpTime->u.smpte.min = time / 1800;
-	time -= lpTime->u.smpte.min * 1800;
-	lpTime->u.smpte.sec = time / 30;
-	time -= lpTime->u.smpte.sec * 30;
-	lpTime->u.smpte.frame = time;
+	time = (double)wwi->dwTotalRecorded /
+	    (double)wwi->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour *  (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = celi(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
 	      lpTime->u.smpte.sec, lpTime->u.smpte.frame);
 	break;
     case TIME_MS:
-	lpTime->u.ms = wwi->dwTotalRecorded /
-	    (wwi->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = wwi->dwTotalRecorded * 1000.0 /
+	    wwi->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     default:
diff --git a/dlls/winmm/winejack/audio.c b/dlls/winmm/winejack/audio.c
index aeb54a0..75adba8 100644
--- a/dlls/winmm/winejack/audio.c
+++ b/dlls/winmm/winejack/audio.c
@@ -1542,7 +1542,7 @@
  */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     DWORD		val;
     WINE_WAVEOUT*	wwo;
     DWORD elapsedMS;
@@ -1584,14 +1584,14 @@
       TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
       break;
     case TIME_SMPTE:
-      time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
-      lpTime->u.smpte.hour = time / 108000;
-      time -= lpTime->u.smpte.hour * 108000;
-      lpTime->u.smpte.min = time / 1800;
-      time -= lpTime->u.smpte.min * 1800;
-      lpTime->u.smpte.sec = time / 30;
-      time -= lpTime->u.smpte.sec * 30;
-      lpTime->u.smpte.frame = time;
+      time = (double)val / (double)wwo->format.wf.nAvgBytesPerSec;
+      lpTime->u.smpte.hour = time / (60 * 60);
+      time -= lpTime->u.smpte.hour * (60 * 60);
+      lpTime->u.smpte.min = time / 60;
+      time -= lpTime->u.smpte.min * 60;
+      lpTime->u.smpte.sec = time;
+      time -= lpTime->u.smpte.sec;
+      lpTime->u.smpte.frame = ceil(time * 30);
       lpTime->u.smpte.fps = 30;
       TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
         lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -1601,7 +1601,7 @@
       FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
       lpTime->wType = TIME_MS;
     case TIME_MS:
-      lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
+      lpTime->u.ms = val * 1000.0 / wwo->format.wf.nAvgBytesPerSec;
       TRACE("TIME_MS=%lu\n", lpTime->u.ms);
       break;
     }
diff --git a/dlls/winmm/winenas/audio.c b/dlls/winmm/winenas/audio.c
index 0b92739..a426a2f 100644
--- a/dlls/winmm/winenas/audio.c
+++ b/dlls/winmm/winenas/audio.c
@@ -1122,7 +1122,7 @@
  */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     DWORD		val;
     WINE_WAVEOUT*	wwo;
 
@@ -1158,14 +1158,14 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / 108000;
-	time -= lpTime->u.smpte.hour * 108000;
-	lpTime->u.smpte.min = time / 1800;
-	time -= lpTime->u.smpte.min * 1800;
-	lpTime->u.smpte.sec = time / 30;
-	time -= lpTime->u.smpte.sec * 30;
-	lpTime->u.smpte.frame = time;
+	time = (double)val / (double)wwo->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -1175,7 +1175,7 @@
 	FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = val * 1000.0 / wwo->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }
diff --git a/dlls/winmm/wineoss/audio.c b/dlls/winmm/wineoss/audio.c
index 33b4c22..b56c679 100644
--- a/dlls/winmm/wineoss/audio.c
+++ b/dlls/winmm/wineoss/audio.c
@@ -2018,7 +2018,7 @@
  */
 static DWORD wodGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     DWORD		val;
     WINE_WAVEOUT*	wwo;
 
@@ -2057,14 +2057,14 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / (60 * 60 * 1000);
-	time -= lpTime->u.smpte.hour * (60 * 60 * 1000);
-	lpTime->u.smpte.min = time / (60 * 1000);
-	time -= lpTime->u.smpte.min * (60 * 1000);
-	lpTime->u.smpte.sec = time / 1000;
-	time -= lpTime->u.smpte.sec * 1000;
-	lpTime->u.smpte.frame = time * 30 / 1000;
+	time = (double)val / (double)wwo->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -2074,7 +2074,7 @@
 	FIXME("Format %d not supported ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = val / (wwo->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = val * 1000.0 / wwo->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }
@@ -3807,7 +3807,7 @@
  */
 static DWORD widGetPosition(WORD wDevID, LPMMTIME lpTime, DWORD uSize)
 {
-    int			time;
+    double		time;
     WINE_WAVEIN*	wwi;
 
     TRACE("(%u, %p, %lu);\n", wDevID, lpTime, uSize);
@@ -3845,15 +3845,15 @@
 	TRACE("TIME_SAMPLES=%lu\n", lpTime->u.sample);
 	break;
     case TIME_SMPTE:
-	time = wwi->dwTotalRecorded /
-	    (wwi->format.wf.nAvgBytesPerSec / 1000);
-	lpTime->u.smpte.hour = time / (60 * 60 * 1000);
-	time -= lpTime->u.smpte.hour * (60 * 60 * 1000);
-	lpTime->u.smpte.min = time / (60 * 1000);
-	time -= lpTime->u.smpte.min * (60 * 1000);
-	lpTime->u.smpte.sec = time / 1000;
-	time -= lpTime->u.smpte.sec * 1000;
-	lpTime->u.smpte.frame = time * 30 / 1000;
+	time = (double)wwi->dwTotalRecorded /
+	    (double)wwi->format.wf.nAvgBytesPerSec;
+	lpTime->u.smpte.hour = time / (60 * 60);
+	time -= lpTime->u.smpte.hour * (60 * 60);
+	lpTime->u.smpte.min = time / 60;
+	time -= lpTime->u.smpte.min * 60;
+	lpTime->u.smpte.sec = time;
+	time -= lpTime->u.smpte.sec;
+	lpTime->u.smpte.frame = ceil(time * 30);
 	lpTime->u.smpte.fps = 30;
 	TRACE("TIME_SMPTE=%02u:%02u:%02u:%02u\n",
 	      lpTime->u.smpte.hour, lpTime->u.smpte.min,
@@ -3863,8 +3863,8 @@
 	FIXME("format not supported (%u) ! use TIME_MS !\n", lpTime->wType);
 	lpTime->wType = TIME_MS;
     case TIME_MS:
-	lpTime->u.ms = wwi->dwTotalRecorded /
-	    (wwi->format.wf.nAvgBytesPerSec / 1000);
+	lpTime->u.ms = wwi->dwTotalRecorded * 1000.0 /
+	    wwi->format.wf.nAvgBytesPerSec;
 	TRACE("TIME_MS=%lu\n", lpTime->u.ms);
 	break;
     }