Sync to Wine-20050310:
Jeremy White <jwhite(a)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(a)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(a)earthlink.net>
- Added parameter checking to timeGetDevCaps.
- Added timer tests.
Christian Costa <titan.costa(a)wanadoo.fr>
- Added some more cases to MCI_MapMsgAtoW.
- Fixed offsets calculations.
Modified: trunk/reactos/lib/winmm/mci.c
Modified: trunk/reactos/lib/winmm/time.c
Modified: trunk/reactos/lib/winmm/wavemap/wavemap.c
Modified: trunk/reactos/lib/winmm/winmm_Es.rc
_____
Modified: trunk/reactos/lib/winmm/mci.c
--- trunk/reactos/lib/winmm/mci.c 2005-03-15 21:39:07 UTC (rev
14105)
+++ trunk/reactos/lib/winmm/mci.c 2005-03-15 21:44:42 UTC (rev
14106)
@@ -278,6 +278,11 @@
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 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;
_____
Modified: trunk/reactos/lib/winmm/time.c
--- trunk/reactos/lib/winmm/time.c 2005-03-15 21:39:07 UTC (rev
14105)
+++ trunk/reactos/lib/winmm/time.c 2005-03-15 21:44:42 UTC (rev
14106)
@@ -408,9 +408,19 @@
{
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;
}
/***********************************************************************
***
_____
Modified: trunk/reactos/lib/winmm/wavemap/wavemap.c
--- trunk/reactos/lib/winmm/wavemap/wavemap.c 2005-03-15 21:39:07 UTC
(rev 14105)
+++ trunk/reactos/lib/winmm/wavemap/wavemap.c 2005-03-15 21:44:42 UTC
(rev 14106)
@@ -62,6 +62,9 @@
/* 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 @@
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 @@
#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 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 @@
}
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 @@
#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 @@
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;
}
_____
Modified: trunk/reactos/lib/winmm/winmm_Es.rc
--- trunk/reactos/lib/winmm/winmm_Es.rc 2005-03-15 21:39:07 UTC (rev
14105)
+++ trunk/reactos/lib/winmm/winmm_Es.rc 2005-03-15 21:44:42 UTC (rev
14106)
@@ -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 */