- val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2);\r
- if (lpTime->wType == TIME_BYTES)\r
- lpTime->u.cb = MulDiv(lpTime->u.cb, wim->avgSpeedOuter, wim->avgSpeedInner);\r
- if (lpTime->wType == TIME_SAMPLES)\r
- lpTime->u.cb = MulDiv(lpTime->u.cb, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner);\r
- /* other time types don't require conversion */\r
+ memcpy(&timepos, lpTime, sizeof(timepos));\r
+\r
+ /* For TIME_MS, we're going to recalculate using TIME_BYTES */\r
+ if (lpTime->wType == TIME_MS)\r
+ timepos.wType = TIME_BYTES;\r
+\r
+ /* This can change timepos.wType if the requested type is not supported */\r
+ val = waveInGetPosition(wim->u.in.hInnerWave, &timepos, dwParam2);\r
+\r
+ if (timepos.wType == TIME_BYTES)\r
+ {\r
+ DWORD dwInnerSamplesPerOuter = wim->nSamplesPerSecInner / wim->nSamplesPerSecOuter;\r
+ if (dwInnerSamplesPerOuter > 0)\r
+ {\r
+ DWORD dwInnerBytesPerSample = wim->avgSpeedInner / wim->nSamplesPerSecInner;\r
+ DWORD dwInnerBytesPerOuterSample = dwInnerBytesPerSample * dwInnerSamplesPerOuter;\r
+ DWORD remainder = 0;\r
+\r
+ /* If we are up sampling (going from lower sample rate to higher),\r
+ ** we need to make a special accomodation for times when we've\r
+ ** written a partial output sample. This happens frequently\r
+ ** to us because we use msacm to do our up sampling, and it\r
+ ** will up sample on an unaligned basis.\r
+ ** For example, if you convert a 2 byte wide 8,000 'outer'\r
+ ** buffer to a 2 byte wide 48,000 inner device, you would\r
+ ** expect 2 bytes of input to produce 12 bytes of output.\r
+ ** Instead, msacm will produce 8 bytes of output.\r
+ ** But reporting our position as 1 byte of output is\r
+ ** nonsensical; the output buffer position needs to be\r
+ ** aligned on outer sample size, and aggressively rounded up.\r
+ */\r
+ remainder = timepos.u.cb % dwInnerBytesPerOuterSample;\r
+ if (remainder > 0)\r
+ {\r
+ timepos.u.cb -= remainder;\r
+ timepos.u.cb += dwInnerBytesPerOuterSample;\r
+ }\r
+ }\r
+\r
+ lpTime->u.cb = MulDiv(timepos.u.cb, wim->avgSpeedOuter, wim->avgSpeedInner);\r
+\r
+ /* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */\r
+ if (lpTime->wType == TIME_MS)\r
+ lpTime->u.ms = MulDiv(lpTime->u.cb, 1000, wim->avgSpeedOuter);\r
+ else\r
+ lpTime->wType = TIME_BYTES;\r
+ }\r
+ else if (lpTime->wType == TIME_SAMPLES && timepos.wType == TIME_SAMPLES)\r
+ lpTime->u.sample = MulDiv(timepos.u.sample, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner);\r
+ else\r
+ /* other time types don't require conversion */\r
+ lpTime->u = timepos.u;\r
+\r