From 67b97bc9efdc71898cb237ea32a21d995da0db26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Tue, 15 Mar 2005 21:44:42 +0000 Subject: [PATCH] Sync to Wine-20050310: Jeremy White - Aggressively round up to the proper alignment when reporting position on streams where we are converting up. - When we are converting from one sample rate to another, we do have to adjust when calculating TIME_SAMPLES. Alex Villacis Lasso - Change SUBLANG_DEFAULT to SUBLANG_NEUTRAL for LANG_SPANISH in all resources, so that Spanish locales other than Spain also use Spanish resources. Robert Reif - Added parameter checking to timeGetDevCaps. - Added timer tests. Christian Costa - Added some more cases to MCI_MapMsgAtoW. - Fixed offsets calculations. svn path=/trunk/; revision=14106 --- reactos/lib/winmm/mci.c | 9 +++- reactos/lib/winmm/time.c | 12 +++++- reactos/lib/winmm/wavemap/wavemap.c | 66 ++++++++++++++++++++++++++--- reactos/lib/winmm/winmm_Es.rc | 2 +- 4 files changed, 79 insertions(+), 10 deletions(-) diff --git a/reactos/lib/winmm/mci.c b/reactos/lib/winmm/mci.c index 0ebeaa6b9e8..d5e1a34709f 100644 --- a/reactos/lib/winmm/mci.c +++ b/reactos/lib/winmm/mci.c @@ -278,6 +278,11 @@ static int MCI_MapMsgAtoW(UINT msg, DWORD_PTR dwParam1, DWORD_PTR *dwParam2) case MCI_UPDATE: case MCI_RESUME: case MCI_DELETE: + case MCI_MONITOR: + case MCI_SETAUDIO: + case MCI_SIGNAL: + case MCI_SETVIDEO: + case MCI_LIST: return 0; case MCI_OPEN: @@ -975,8 +980,8 @@ static LPCWSTR MCI_FindCommand(UINT uTbl, LPCWSTR verb) */ static DWORD MCI_GetReturnType(LPCWSTR lpCmd) { - lpCmd += strlenW(lpCmd) + 1 + sizeof(DWORD) + sizeof(WORD); - if (*lpCmd == '\0' && *(const WORD*)(lpCmd + 1 + sizeof(DWORD)) == MCI_RETURN) { + lpCmd = (LPCWSTR)((BYTE*)(lpCmd + strlenW(lpCmd) + 1) + sizeof(DWORD) + sizeof(WORD)); + if (*lpCmd == '\0' && *(const WORD*)((BYTE*)(lpCmd + 1) + sizeof(DWORD)) == MCI_RETURN) { return *(const DWORD*)(lpCmd + 1); } return 0L; diff --git a/reactos/lib/winmm/time.c b/reactos/lib/winmm/time.c index ea8daef3697..dbd912e3904 100644 --- a/reactos/lib/winmm/time.c +++ b/reactos/lib/winmm/time.c @@ -408,9 +408,19 @@ MMRESULT WINAPI timeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize) { TRACE("(%p, %u)\n", lpCaps, wSize); + if (lpCaps == 0) { + WARN("invalid lpCaps\n"); + return TIMERR_NOCANDO; + } + + if (wSize < sizeof(TIMECAPS)) { + WARN("invalid wSize\n"); + return TIMERR_NOCANDO; + } + lpCaps->wPeriodMin = MMSYSTIME_MININTERVAL; lpCaps->wPeriodMax = MMSYSTIME_MAXINTERVAL; - return 0; + return TIMERR_NOERROR; } /************************************************************************** diff --git a/reactos/lib/winmm/wavemap/wavemap.c b/reactos/lib/winmm/wavemap/wavemap.c index 9fb05d2db70..2ff43cdbe1e 100644 --- a/reactos/lib/winmm/wavemap/wavemap.c +++ b/reactos/lib/winmm/wavemap/wavemap.c @@ -62,6 +62,9 @@ typedef struct tagWAVEMAPDATA { /* ratio to compute position from a PCM playback to any format */ DWORD avgSpeedOuter; DWORD avgSpeedInner; + /* channel size of inner and outer */ + DWORD nSamplesPerSecOuter; + DWORD nSamplesPerSecInner; } WAVEMAPDATA; static BOOL WAVEMAP_IsData(WAVEMAPDATA* wm) @@ -177,6 +180,7 @@ static DWORD wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) wom->dwClientInstance = lpDesc->dwInstance; wom->u.out.hOuterWave = (HWAVEOUT)lpDesc->hWave; wom->avgSpeedOuter = wom->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec; + wom->nSamplesPerSecOuter = wom->nSamplesPerSecInner = lpDesc->lpFormat->nSamplesPerSec; for (i = ndlo; i < ndhi; i++) { /* if no ACM stuff is involved, no need to handle callbacks at this @@ -198,7 +202,7 @@ static DWORD wodOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) #define TRY(sps,bps) wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \ switch (res=wodOpenHelper(wom, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \ - case MMSYSERR_NOERROR: wom->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \ + case MMSYSERR_NOERROR: wom->avgSpeedInner = wfx.nAvgBytesPerSec; wom->nSamplesPerSecInner = wfx.nSamplesPerSec; goto found; \ case WAVERR_BADFORMAT: break; \ default: goto error; \ } @@ -414,12 +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); - /* 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; } @@ -691,6 +742,7 @@ static DWORD widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) } wim->avgSpeedOuter = wim->avgSpeedInner = lpDesc->lpFormat->nAvgBytesPerSec; + wim->nSamplesPerSecOuter = wim->nSamplesPerSecInner = lpDesc->lpFormat->nSamplesPerSec; for (i = ndlo; i < ndhi; i++) { if (waveInOpen(&wim->u.in.hInnerWave, i, lpDesc->lpFormat, (DWORD)widCallback, @@ -710,7 +762,7 @@ static DWORD widOpen(LPDWORD lpdwUser, LPWAVEOPENDESC lpDesc, DWORD dwFlags) #define TRY(sps,bps) wfx.nSamplesPerSec = (sps); wfx.wBitsPerSample = (bps); \ switch (res=widOpenHelper(wim, i, lpDesc, &wfx, dwFlags | WAVE_FORMAT_DIRECT)) { \ - case MMSYSERR_NOERROR: wim->avgSpeedInner = wfx.nAvgBytesPerSec; goto found; \ + case MMSYSERR_NOERROR: wim->avgSpeedInner = wfx.nAvgBytesPerSec; wim->nSamplesPerSecInner = wfx.nSamplesPerSec; goto found; \ case WAVERR_BADFORMAT: break; \ default: goto error; \ } @@ -915,6 +967,8 @@ static DWORD widGetPosition(WAVEMAPDATA* wim, LPMMTIME lpTime, DWORD dwParam2) val = waveInGetPosition(wim->u.in.hInnerWave, lpTime, dwParam2); if (lpTime->wType == TIME_BYTES) lpTime->u.cb = MulDiv(lpTime->u.cb, wim->avgSpeedOuter, wim->avgSpeedInner); + if (lpTime->wType == TIME_SAMPLES) + lpTime->u.cb = MulDiv(lpTime->u.cb, wim->nSamplesPerSecOuter, wim->nSamplesPerSecInner); /* other time types don't require conversion */ return val; } diff --git a/reactos/lib/winmm/winmm_Es.rc b/reactos/lib/winmm/winmm_Es.rc index 29be5a6ad9a..7c4712cada7 100644 --- a/reactos/lib/winmm/winmm_Es.rc +++ b/reactos/lib/winmm/winmm_Es.rc @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_DEFAULT +STRINGTABLE LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL BEGIN /* MMSYS errors */