wavemap fix

Eric Pouech eric.pouech at wanadoo.fr
Wed Oct 30 14:45:16 CST 2002


the position returned while playing/recording was boggus when:
- a non PCM wave was played/recorder
- and the position was requested as a BYTES

this patch fixes it
A+
-------------- next part --------------
Name:          wavemap
ChangeLog:     returning correct values for wave(In|Out)GetPosition even if playing non PCM files
License:       X11
GenDate:       2002/10/30 20:43:12 UTC
ModifiedFiles: dlls/winmm/wavemap/wavemap.c
AddedFiles:    
===================================================================
RCS file: /home/cvs/cvsroot/wine/wine/dlls/winmm/wavemap/wavemap.c,v
retrieving revision 1.23
diff -u -u -r1.23 wavemap.c
--- dlls/winmm/wavemap/wavemap.c	30 Oct 2002 20:25:38 -0000	1.23
+++ dlls/winmm/wavemap/wavemap.c	30 Oct 2002 20:42:51 -0000
@@ -56,6 +56,9 @@
     DWORD	dwCallback;
     DWORD	dwClientInstance;
     DWORD	dwFlags;
+    /* ratio to compute position from a PCM playback to any format */
+    DWORD       avgSpeedOuter;
+    DWORD       avgSpeedInner;
 } WAVEMAPDATA;
 
 static	BOOL	WAVEMAP_IsData(WAVEMAPDATA* wm)
@@ -161,6 +164,7 @@
     wom->dwFlags = dwFlags;
     wom->dwClientInstance = lpDesc->dwInstance;
     wom->u.out.hOuterWave = (HWAVEOUT)lpDesc->hWave;
+    wom->avgSpeedOuter = wom->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;
 
     for (i = ndlo; i < ndhi; i++) {
 	/* if no ACM stuff is involved, no need to handle callbacks at this
@@ -181,7 +185,8 @@
         /* try some ACM stuff */
 
 #define	TRY(sps,bps)    wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \
-                        if (wodOpenHelper(wom, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) goto found;
+                        if (wodOpenHelper(wom, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) \
+                        {wom->avgSpeedInner = wfx.nAvgBytesPerSec; goto found;}
 
         for (i = ndlo; i < ndhi; i++) {
             /* first try with same stereo/mono option as source */
@@ -344,9 +349,11 @@
 
 static	DWORD	wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
 {
-    if (wom->hAcmStream)
-	FIXME("No position conversion done for PCM => non-PCM, returning PCM position\n");
-    return waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);
+    DWORD       val = waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);
+    if (lpTime->wType == TIME_BYTES)
+        val = MulDiv(val, wom->avgSpeedOuter, wom->avgSpeedInner);
+    /* other time types don't require conversion */
+    return val;
 }
 
 static	DWORD	wodGetDevCaps(UINT wDevID, WAVEMAPDATA* wom, LPWAVEOUTCAPSA lpWaveCaps, DWORD dwParam2)
@@ -579,6 +586,8 @@
 	ndlo = 0;
     }
 
+    wim->avgSpeedOuter = wim->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec;
+
     for (i = ndlo; i < ndhi; i++) {
 	if (waveInOpen(&wim->u.in.hInnerWave, i, lpDesc->lpFormat, (DWORD)widCallback,
                        (DWORD)wim, (dwFlags & ~CALLBACK_TYPEMASK) | CALLBACK_FUNCTION | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) {
@@ -596,7 +605,8 @@
         /* try some ACM stuff */
         
 #define	TRY(sps,bps)    wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \
-                        if (widOpenHelper(wim, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) goto found;
+                        if (widOpenHelper(wim, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT) == MMSYSERR_NOERROR) \
+                        {wim->avgSpeedInner = wfx.nAvgBytesPerSec; goto found;}
         
         for (i = ndlo; i < ndhi; i++) {
             /* first try with same stereo/mono option as source */
@@ -733,9 +743,11 @@
 
 static	DWORD	widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2)
 {
-    if (wim->hAcmStream)
-	FIXME("No position conversion done for PCM => non-PCM, returning PCM position\n");
-    return waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2);
+    DWORD       val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2);
+    if (lpTime->wType == TIME_BYTES)
+        val = MulDiv(val, wim->avgSpeedOuter, wim->avgSpeedInner);
+    /* other time types don't require conversion */
+    return val;
 }
 
 static	DWORD	widGetDevCaps(UINT wDevID, WAVEMAPDATA* wim, LPWAVEINCAPSA lpWaveCaps, DWORD dwParam2)


More information about the wine-patches mailing list