Aggressively round up to the proper alignment when reporting position
on streams where we are converting up.
This commit is contained in:
parent
2122277284
commit
36e845ce05
|
@ -418,14 +418,59 @@ static DWORD wodUnprepare(WAVEMAPDATA* wom, LPWAVEHDR lpWaveHdrSrc, DWORD dwPara
|
||||||
static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
|
static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
|
||||||
{
|
{
|
||||||
DWORD val;
|
DWORD val;
|
||||||
|
MMTIME timepos;
|
||||||
TRACE("(%p %p %08lx)\n", wom, lpTime, dwParam2);
|
TRACE("(%p %p %08lx)\n", wom, lpTime, dwParam2);
|
||||||
|
|
||||||
val = waveOutGetPosition(wom->u.out.hInnerWave, lpTime, dwParam2);
|
memcpy(&timepos, lpTime, sizeof(timepos));
|
||||||
if (lpTime->wType == TIME_BYTES)
|
|
||||||
lpTime->u.cb = MulDiv(lpTime->u.cb, wom->avgSpeedOuter, wom->avgSpeedInner);
|
/* For TIME_MS, we're going to recalculate using TIME_BYTES */
|
||||||
if (lpTime->wType == TIME_SAMPLES)
|
if (lpTime->wType == TIME_MS)
|
||||||
lpTime->u.cb = MulDiv(lpTime->u.cb, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner);
|
timepos.wType = TIME_BYTES;
|
||||||
/* other time types don't require conversion */
|
|
||||||
|
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;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue