[PATCH 1/3] msacm32: Rewrite PCM conversion functions.

Zebediah Figura z.figura12 at gmail.com
Tue Jun 13 12:19:59 CDT 2017


This should be much more readable (and shorter), and work
much more closely to the native Windows PCM converter.

Also fixes a clicking issue mentioned in bug #26388.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/msacm32/pcmconverter.c | 514 +++++++++++---------------------------------
 1 file changed, 120 insertions(+), 394 deletions(-)

diff --git a/dlls/msacm32/pcmconverter.c b/dlls/msacm32/pcmconverter.c
index 70ec62fd2fd..0f6d79f56b6 100644
--- a/dlls/msacm32/pcmconverter.c
+++ b/dlls/msacm32/pcmconverter.c
@@ -543,395 +543,125 @@ static const PCM_CONVERT_KEEP_RATE PCM_ConvertKeepRate[] = {
  * <M> is the number of bits of output channel (8 or 16)
  *
  */
-static	void cvtSS88C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		      DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = *src;
-        *dst++ = *src;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSM88C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		      DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = M8(src[0], src[1]);
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMS88C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		      DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = *src;
-        *dst++ = *src;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src++;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMM88C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		      DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = *src;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src++;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSS816C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-	W16(dst, C816(src[0]));	dst += 2;
-	W16(dst, C816(src[1]));	dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSM816C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W16(dst, M16(C816(src[0]), C816(src[1]))); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMS816C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W16(dst, C816(*src)); dst += 2;
-        W16(dst, C816(*src)); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src++;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMM816C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W16(dst, C816(*src)); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src++;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSS168C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = C168(R16(src));
-        *dst++ = C168(R16(src + 2));
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 4;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSM168C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-	*dst++ = C168(M16(R16(src), R16(src + 2)));
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 4;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMS168C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = C168(R16(src));
-        *dst++ = C168(R16(src));
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc==0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMM168C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-		       DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        *dst++ = C168(R16(src));
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSS1616C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W16(dst, R16(src)); dst += 2;
-        W16(dst, R16(src)); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 4;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSM1616C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W16(dst, M16(R16(src), R16(src + 2))); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 4;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMS1616C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while((*ndst)--) {
-        W16(dst, R16(src)); dst += 2;
-        W16(dst, R16(src)); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
 
-static	void cvtMM1616C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W16(dst, R16(src)); dst += 2;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 2;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSS2424C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W24(dst, R24(src)); dst += 3;
-        W24(dst, R24(src)); dst += 3;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 6;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtSM2424C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W24(dst, M24(R24(src), R24(src + 3))); dst += 3;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 6;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMS2424C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while((*ndst)--) {
-        W24(dst, R24(src)); dst += 3;
-        W24(dst, R24(src)); dst += 3;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 3;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
-
-static	void cvtMM2424C(DWORD srcRate, const unsigned char* src, LPDWORD nsrc,
-			DWORD dstRate, unsigned char* dst, LPDWORD ndst)
-{
-    DWORD error = dstRate / 2;
-    TRACE("(%d, %p, %p, %d, %p, %p)\n", srcRate, src, nsrc, dstRate, dst, ndst);
-
-    while ((*ndst)--) {
-        W24(dst, R24(src)); dst += 3;
-        error = error + srcRate;
-        while (error > dstRate) {
-            src += 3;
-            (*nsrc)--;
-            if (*nsrc == 0)
-                return;
-            error = error - dstRate;
-        }
-    }
-}
+#define PCM_CVT_CHANGE_FUNC(name)	static void name(DWORD srcRate, const unsigned char *src, DWORD *nsrc, \
+							 DWORD dstRate, unsigned char *dst, DWORD *ndst) \
+    { \
+    DWORD error = srcRate / 2; \
+    DWORD srcUsed = 0, dstUsed = 0; \
+    for (srcUsed = 0; srcUsed < *nsrc; srcUsed++) { \
+        error += dstRate; \
+        while (error > srcRate) { \
+            if (dstUsed == *ndst) { \
+                *nsrc = srcUsed; \
+                *ndst = dstUsed; \
+                return; \
+            }
+
+            /* conversion is done here */
+
+#define PCM_CVT_CHANGE_FUNC_END(offset)	\
+            dstUsed++; \
+            error -= srcRate; \
+        } \
+        src += offset; \
+    } \
+    *nsrc = srcUsed; \
+    *ndst = dstUsed; \
+}
+
+PCM_CVT_CHANGE_FUNC(cvtSS88C)
+    *dst++ = src[0];
+    *dst++ = src[1];
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtSM88C)
+    *dst++ = M8(src[0], src[1]);
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtMS88C)
+    *dst++ = src[0];
+    *dst++ = src[0];
+PCM_CVT_CHANGE_FUNC_END(1)
+
+PCM_CVT_CHANGE_FUNC(cvtMM88C)
+    *dst++ = src[0];
+PCM_CVT_CHANGE_FUNC_END(1)
+
+PCM_CVT_CHANGE_FUNC(cvtSS816C)
+    W16(dst, C816(src[0])); dst += 2;
+    W16(dst, C816(src[1])); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtSM816C)
+    W16(dst, M16(C816(src[0]), C816(src[1]))); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtMS816C)
+    W16(dst, C816(src[0])); dst += 2;
+    W16(dst, C816(src[0])); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(1)
+
+PCM_CVT_CHANGE_FUNC(cvtMM816C)
+    W16(dst, C816(src[0])); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(1)
+
+PCM_CVT_CHANGE_FUNC(cvtSS168C)
+    *dst++ = C168(R16(src));
+    *dst++ = C168(R16(src + 2));
+PCM_CVT_CHANGE_FUNC_END(4)
+
+PCM_CVT_CHANGE_FUNC(cvtSM168C)
+    *dst++ = C168(M16(R16(src), R16(src + 2)));
+PCM_CVT_CHANGE_FUNC_END(4)
+
+PCM_CVT_CHANGE_FUNC(cvtMS168C)
+    *dst++ = C168(R16(src));
+    *dst++ = C168(R16(src));
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtMM168C)
+    *dst++ = C168(R16(src));
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtSS1616C)
+    W16(dst, R16(src)); dst += 2;
+    W16(dst, R16(src + 2)); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(4)
+
+PCM_CVT_CHANGE_FUNC(cvtSM1616C)
+    W16(dst, M16(R16(src), R16(src + 2))); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(4)
+
+PCM_CVT_CHANGE_FUNC(cvtMS1616C)
+    W16(dst, R16(src)); dst += 2;
+    W16(dst, R16(src)); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtMM1616C)
+    W16(dst, R16(src)); dst += 2;
+PCM_CVT_CHANGE_FUNC_END(2)
+
+PCM_CVT_CHANGE_FUNC(cvtSS2424C)
+    W24(dst, R24(src)); dst += 3;
+    W24(dst, R24(src + 3)); dst += 3;
+PCM_CVT_CHANGE_FUNC_END(6)
+
+PCM_CVT_CHANGE_FUNC(cvtSM2424C)
+    W24(dst, M24(R24(src), R24(src + 3))); dst += 3;
+PCM_CVT_CHANGE_FUNC_END(6)
+
+PCM_CVT_CHANGE_FUNC(cvtMS2424C)
+    W24(dst, R24(src)); dst += 3;
+    W24(dst, R24(src)); dst += 3;
+PCM_CVT_CHANGE_FUNC_END(3)
+
+PCM_CVT_CHANGE_FUNC(cvtMM2424C)
+    W24(dst, R24(src)); dst += 3;
+PCM_CVT_CHANGE_FUNC_END(3)
+
+#undef PCM_CVT_CHANGE_FUNC
+#undef PCM_CVT_CHANGE_FUNC_END
 
 typedef void (*PCM_CONVERT_CHANGE_RATE)(DWORD, const unsigned char*, LPDWORD, DWORD, unsigned char*, LPDWORD);
 
@@ -1287,12 +1017,8 @@ static LRESULT PCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER
 
     /* do the job */
     if (adsi->fdwDriver & PCM_RESAMPLE) {
-	DWORD	nsrc2 = nsrc;
-	DWORD	ndst2 = ndst;
-	apd->cvt.cvtChangeRate(adsi->pwfxSrc->nSamplesPerSec, adsh->pbSrc, &nsrc2,
-			       adsi->pwfxDst->nSamplesPerSec, adsh->pbDst, &ndst2);
-	nsrc -= nsrc2;
-	ndst -= ndst2;
+        apd->cvt.cvtChangeRate(adsi->pwfxSrc->nSamplesPerSec, adsh->pbSrc, &nsrc,
+                               adsi->pwfxDst->nSamplesPerSec, adsh->pbDst, &ndst);
     } else {
 	if (nsrc < ndst) ndst = nsrc; else nsrc = ndst;
 
-- 
2.13.0




More information about the wine-patches mailing list