Commit 36e845ce authored by Jeremy White's avatar Jeremy White Committed by Alexandre Julliard

Aggressively round up to the proper alignment when reporting position

on streams where we are converting up.
parent 21222772
......@@ -418,14 +418,59 @@ static DWORD wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwPara
static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
{
DWORD val;
MMTIME timepos;
TRACE("(%p %p %08lx)\n", wom, lpTime, dwParam2);
val = waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);
if (lpTime->wType == TIME_BYTES)
lpTime->u.cb = MulDiv(lpTime->u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);
if (lpTime->wType == TIME_SAMPLES)
lpTime->u.cb = MulDiv(lpTime->u.cb, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner);
/* other time types don't require conversion */
memcpy(&timepos, lpTime, sizeof(timepos));
/* For TIME_MS, we're going to recalculate using TIME_BYTES */
if (lpTime->wType == TIME_MS)
timepos.wType = TIME_BYTES;
val = waveOutGetPosition(wom->u.out.hInnerWave, &timepos, dwParam2);
if (lpTime->wType == TIME_BYTES || lpTime->wType == TIME_MS)
{
DWORD dwInnerSamplesPerOuter = wom->nSamplesPerSecInner / wom->nSamplesPerSecOuter;
if (dwInnerSamplesPerOuter > 0)
{
DWORD dwInnerBytesPerSample = wom->avgSpeedInner / wom->nSamplesPerSecInner;
DWORD dwInnerBytesPerOuterSample = dwInnerBytesPerSample * dwInnerSamplesPerOuter;
DWORD remainder = 0;
/* If we are up sampling (going from lower sample rate to higher),
** we need to make a special accomodation for times when we've
** written a partial output sample. This happens frequently
** to us because we use msacm to do our up sampling, and it
** will up sample on an unaligned basis.
** For example, if you convert a 2 byte wide 8,000 'outer'
** buffer to a 2 byte wide 48,000 inner device, you would
** expect 2 bytes of input to produce 12 bytes of output.
** Instead, msacm will produce 8 bytes of output.
** But reporting our position as 1 byte of output is
** nonsensical; the output buffer position needs to be
** aligned on outer sample size, and aggressively rounded up.
*/
remainder = timepos.u.cb % dwInnerBytesPerOuterSample;
if (remainder > 0)
{
timepos.u.cb -= remainder;
timepos.u.cb += dwInnerBytesPerOuterSample;
}
}
lpTime->u.cb = MulDiv(timepos.u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);
/* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */
if (lpTime->wType == TIME_MS)
lpTime->u.cb = MulDiv(lpTime->u.cb, 1000, wom->avgSpeedOuter);
}
else if (lpTime->wType == TIME_SAMPLES)
lpTime->u.cb = MulDiv(timepos.u.cb, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner);
else
/* other time types don't require conversion */
lpTime->u = timepos.u;
return val;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment