Sync to Wine-20050310:

Jeremy White <jwhite@codeweavers.com>
- 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 <a_villacis@palosanto.com>
- 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 <reif@earthlink.net>
- Added parameter checking to timeGetDevCaps.
- Added timer tests.
Christian Costa <titan.costa@wanadoo.fr>
- Added some more cases to MCI_MapMsgAtoW.
- Fixed offsets calculations.

svn path=/trunk/; revision=14106
This commit is contained in:
Gé van Geldorp 2005-03-15 21:44:42 +00:00
parent f4ccfedf3e
commit 67b97bc9ef
4 changed files with 79 additions and 10 deletions

View file

@ -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;

View file

@ -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;
}
/**************************************************************************

View file

@ -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;
}

View file

@ -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 */