[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