Correctly handle where waveOutGetPosition changes timepos.wType

because the requested type is not supported.
Added Jeremy White's waveOutGetPosition fix to waveInGetPosition.
This commit is contained in:
Robert Reif 2005-04-11 12:49:04 +00:00 committed by Alexandre Julliard
parent f0d4fa0465
commit c002dfc005
1 changed files with 61 additions and 11 deletions

View File

@ -428,9 +428,10 @@ static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
if (lpTime->wType == TIME_MS) if (lpTime->wType == TIME_MS)
timepos.wType = TIME_BYTES; timepos.wType = TIME_BYTES;
/* This can change timepos.wType if the requested type is not supported */
val = waveOutGetPosition(wom->u.out.hInnerWave, &timepos, dwParam2); val = waveOutGetPosition(wom->u.out.hInnerWave, &timepos, dwParam2);
if (lpTime->wType == TIME_BYTES || lpTime->wType == TIME_MS) if (timepos.wType == TIME_BYTES)
{ {
DWORD dwInnerSamplesPerOuter = wom->nSamplesPerSecInner / wom->nSamplesPerSecOuter; DWORD dwInnerSamplesPerOuter = wom->nSamplesPerSecInner / wom->nSamplesPerSecOuter;
if (dwInnerSamplesPerOuter > 0) if (dwInnerSamplesPerOuter > 0)
@ -464,10 +465,12 @@ static DWORD wodGetPosition(WAVEMAPDATA* wom, LPMMTIME lpTime, DWORD dwParam2)
/* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */ /* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */
if (lpTime->wType == TIME_MS) if (lpTime->wType == TIME_MS)
lpTime->u.cb = MulDiv(lpTime->u.cb, 1000, wom->avgSpeedOuter); lpTime->u.ms = MulDiv(lpTime->u.cb, 1000, wom->avgSpeedOuter);
else
lpTime->wType = TIME_BYTES;
} }
else if (lpTime->wType == TIME_SAMPLES) else if (lpTime->wType == TIME_SAMPLES && timepos.wType == TIME_SAMPLES)
lpTime->u.cb = MulDiv(timepos.u.cb, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner); lpTime->u.sample = MulDiv(timepos.u.sample, wom->nSamplesPerSecOuter, wom->nSamplesPerSecInner);
else else
/* other time types don't require conversion */ /* other time types don't require conversion */
lpTime->u = timepos.u; lpTime->u = timepos.u;
@ -962,15 +965,62 @@ static DWORD widUnprepare(WAVEMAPDATA* wim, LPWAVEHDR lpWaveHdrDst, DWORD dwPara
static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2) static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2)
{ {
DWORD val; DWORD val;
MMTIME timepos;
TRACE("(%p %p %08lx)\n", wim, lpTime, dwParam2); TRACE("(%p %p %08lx)\n", wim, lpTime, dwParam2);
val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2); memcpy(&timepos, lpTime, sizeof(timepos));
if (lpTime->wType == TIME_BYTES)
lpTime->u.cb = MulDiv(lpTime->u.cb, wim->avgSpeedOuter, wim->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, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner); timepos.wType = TIME_BYTES;
/* other time types don't require conversion */
/* This can change timepos.wType if the requested type is not supported */
val = waveInGetPosition(wim->u.in.hInnerWave, &timepos, dwParam2);
if (timepos.wType == TIME_BYTES)
{
DWORD dwInnerSamplesPerOuter = wim->nSamplesPerSecInner / wim->nSamplesPerSecOuter;
if (dwInnerSamplesPerOuter > 0)
{
DWORD dwInnerBytesPerSample = wim->avgSpeedInner / wim->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, wim->avgSpeedOuter, wim->avgSpeedInner);
/* Once we have the TIME_BYTES right, we can easily convert to TIME_MS */
if (lpTime->wType == TIME_MS)
lpTime->u.ms = MulDiv(lpTime->u.cb, 1000, wim->avgSpeedOuter);
else
lpTime->wType = TIME_BYTES;
}
else if (lpTime->wType == TIME_SAMPLES && timepos.wType == TIME_SAMPLES)
lpTime->u.sample = MulDiv(timepos.u.sample, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner);
else
/* other time types don't require conversion */
lpTime->u = timepos.u;
return val; return val;
} }