Fixed bug when PCMWAVEFORMAT is passed into acmStreamOpen.
Fixed bug where interpolation is done with data past end of buffer. A proper fix would be to project the last sample based on the previous two but that requires significant changes. Added TRACE and WARN where needed.
This commit is contained in:
parent
23983b8f83
commit
87c73c0065
|
@ -56,6 +56,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||||
*/
|
*/
|
||||||
static DWORD PCM_drvOpen(LPCSTR str, PACMDRVOPENDESCW adod)
|
static DWORD PCM_drvOpen(LPCSTR str, PACMDRVOPENDESCW adod)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %p)\n", str, adod);
|
||||||
|
|
||||||
return (adod == NULL) ||
|
return (adod == NULL) ||
|
||||||
(adod->fccType == ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC &&
|
(adod->fccType == ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC &&
|
||||||
adod->fccComp == ACMDRIVERDETAILS_FCCCOMP_UNDEFINED);
|
adod->fccComp == ACMDRIVERDETAILS_FCCCOMP_UNDEFINED);
|
||||||
|
@ -66,6 +68,8 @@ static DWORD PCM_drvOpen(LPCSTR str, PACMDRVOPENDESCW adod)
|
||||||
*/
|
*/
|
||||||
static DWORD PCM_drvClose(DWORD dwDevID)
|
static DWORD PCM_drvClose(DWORD dwDevID)
|
||||||
{
|
{
|
||||||
|
TRACE("(%ld)\n", dwDevID);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,6 +121,7 @@ static struct {
|
||||||
static DWORD PCM_GetFormatIndex(LPWAVEFORMATEX wfx)
|
static DWORD PCM_GetFormatIndex(LPWAVEFORMATEX wfx)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
TRACE("(%p)\n", wfx);
|
||||||
|
|
||||||
for (i = 0; i < NUM_PCM_FORMATS; i++) {
|
for (i = 0; i < NUM_PCM_FORMATS; i++) {
|
||||||
if (wfx->nChannels == PCM_Formats[i].nChannels &&
|
if (wfx->nChannels == PCM_Formats[i].nChannels &&
|
||||||
|
@ -219,26 +224,32 @@ static inline unsigned char M8(unsigned char a, unsigned char b)
|
||||||
|
|
||||||
static void cvtMM88K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMM88K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
memcpy(dst, src, ns);
|
memcpy(dst, src, ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cvtSS88K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSS88K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
memcpy(dst, src, ns * 2);
|
memcpy(dst, src, ns * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cvtMM1616K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMM1616K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
memcpy(dst, src, ns * 2);
|
memcpy(dst, src, ns * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cvtSS1616K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSS1616K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
memcpy(dst, src, ns * 4);
|
memcpy(dst, src, ns * 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cvtMS88K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMS88K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
*dst++ = *src;
|
*dst++ = *src;
|
||||||
*dst++ = *src++;
|
*dst++ = *src++;
|
||||||
|
@ -248,6 +259,7 @@ static void cvtMS88K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
static void cvtMS816K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMS816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
short v;
|
short v;
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
v = C816(*src++);
|
v = C816(*src++);
|
||||||
|
@ -259,6 +271,7 @@ static void cvtMS816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
static void cvtMS168K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMS168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
v = C168(R16(src)); src += 2;
|
v = C168(R16(src)); src += 2;
|
||||||
|
@ -270,6 +283,7 @@ static void cvtMS168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
static void cvtMS1616K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMS1616K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
short v;
|
short v;
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
v = R16(src); src += 2;
|
v = R16(src); src += 2;
|
||||||
|
@ -280,6 +294,8 @@ static void cvtMS1616K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtSM88K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSM88K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
*dst++ = M8(src[0], src[1]);
|
*dst++ = M8(src[0], src[1]);
|
||||||
src += 2;
|
src += 2;
|
||||||
|
@ -289,6 +305,7 @@ static void cvtSM88K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
static void cvtSM816K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSM816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
short v;
|
short v;
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
v = M16(C816(src[0]), C816(src[1]));
|
v = M16(C816(src[0]), C816(src[1]));
|
||||||
|
@ -299,6 +316,8 @@ static void cvtSM816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtSM168K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSM168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
*dst++ = C168(M16(R16(src), R16(src + 2)));
|
*dst++ = C168(M16(R16(src), R16(src + 2)));
|
||||||
src += 4;
|
src += 4;
|
||||||
|
@ -307,6 +326,8 @@ static void cvtSM168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtSM1616K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSM1616K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
W16(dst, M16(R16(src),R16(src+2))); dst += 2;
|
W16(dst, M16(R16(src),R16(src+2))); dst += 2;
|
||||||
src += 4;
|
src += 4;
|
||||||
|
@ -315,6 +336,8 @@ static void cvtSM1616K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtMM816K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMM816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
W16(dst, C816(*src++)); dst += 2;
|
W16(dst, C816(*src++)); dst += 2;
|
||||||
}
|
}
|
||||||
|
@ -322,6 +345,8 @@ static void cvtMM816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtSS816K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSS816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
W16(dst, C816(*src++)); dst += 2;
|
W16(dst, C816(*src++)); dst += 2;
|
||||||
W16(dst, C816(*src++)); dst += 2;
|
W16(dst, C816(*src++)); dst += 2;
|
||||||
|
@ -330,6 +355,8 @@ static void cvtSS816K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtMM168K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtMM168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
*dst++ = C168(R16(src)); src += 2;
|
*dst++ = C168(R16(src)); src += 2;
|
||||||
}
|
}
|
||||||
|
@ -337,6 +364,8 @@ static void cvtMM168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
|
|
||||||
static void cvtSS168K(const unsigned char* src, int ns, unsigned char* dst)
|
static void cvtSS168K(const unsigned char* src, int ns, unsigned char* dst)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d, %p)\n", src, ns, dst);
|
||||||
|
|
||||||
while (ns--) {
|
while (ns--) {
|
||||||
*dst++ = C168(R16(src)); src += 2;
|
*dst++ = C168(R16(src)); src += 2;
|
||||||
*dst++ = C168(R16(src)); src += 2;
|
*dst++ = C168(R16(src)); src += 2;
|
||||||
|
@ -366,6 +395,7 @@ static void cvtSS88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -395,6 +425,7 @@ static void cvtSM88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -405,7 +436,10 @@ static void cvtSM88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
*dst++ = I(M8(apd->last[0].b, apd->last[1].b), M8(src[0], src[1]), r);
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
*dst++ = I(M8(apd->last[0].b, apd->last[1].b), M8(src[0], src[1]), r);
|
||||||
|
else
|
||||||
|
*dst++ = M8(apd->last[0].b, apd->last[1].b);
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -415,6 +449,7 @@ static void cvtMS88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -424,7 +459,10 @@ static void cvtMS88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
dst[0] = dst[1] = I(apd->last[0].b, src[0], r);
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
dst[0] = dst[1] = I(apd->last[0].b, src[0], r);
|
||||||
|
else
|
||||||
|
dst[0] = dst[1] = apd->last[0].b;
|
||||||
dst += 2;
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
|
@ -435,6 +473,7 @@ static void cvtMM88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -444,7 +483,10 @@ static void cvtMM88C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
*dst++ = I(apd->last[0].b, src[0], r);
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
*dst++ = I(apd->last[0].b, src[0], r);
|
||||||
|
else
|
||||||
|
*dst++ = apd->last[0].b;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -454,6 +496,7 @@ static void cvtSS816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -464,8 +507,16 @@ static void cvtSS816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
W16(dst, I(C816(apd->last[0].b), C816(src[0]), r)); dst += 2;
|
if (*nsrc) /* don't go off end of data */
|
||||||
W16(dst, I(C816(apd->last[1].b), C816(src[1]), r)); dst += 2;
|
W16(dst, I(C816(apd->last[0].b), C816(src[0]), r));
|
||||||
|
else
|
||||||
|
W16(dst, C816(apd->last[0].b));
|
||||||
|
dst += 2;
|
||||||
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
W16(dst, I(C816(apd->last[1].b), C816(src[1]), r));
|
||||||
|
else
|
||||||
|
W16(dst, C816(apd->last[1].b));
|
||||||
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -475,6 +526,7 @@ static void cvtSM816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -485,8 +537,11 @@ static void cvtSM816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
W16(dst, I(M16(C816(apd->last[0].b), C816(apd->last[1].b)),
|
if (*nsrc) /* don't go off end of data */
|
||||||
M16(C816(src[0]), C816(src[1])), r));
|
W16(dst, I(M16(C816(apd->last[0].b), C816(apd->last[1].b)),
|
||||||
|
M16(C816(src[0]), C816(src[1])), r));
|
||||||
|
else
|
||||||
|
W16(dst, M16(C816(apd->last[0].b), C816(apd->last[1].b)));
|
||||||
dst += 2;
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
|
@ -498,6 +553,7 @@ static void cvtMS816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
short v;
|
short v;
|
||||||
|
TRACE("(%p, %p, %p->(%ld), %p, %p->(%ld))\n", apd, src, nsrc, *nsrc, dst, ndst, *ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -507,7 +563,10 @@ static void cvtMS816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
v = I(C816(apd->last[0].b), C816(src[0]), r);
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
v = I(C816(apd->last[0].b), C816(src[0]), r);
|
||||||
|
else
|
||||||
|
v = C816(apd->last[0].b);
|
||||||
W16(dst, v); dst += 2;
|
W16(dst, v); dst += 2;
|
||||||
W16(dst, v); dst += 2;
|
W16(dst, v); dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
|
@ -519,6 +578,7 @@ static void cvtMM816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -528,7 +588,10 @@ static void cvtMM816C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
W16(dst, I(C816(apd->last[0].b), C816(src[0]), r));
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
W16(dst, I(C816(apd->last[0].b), C816(src[0]), r));
|
||||||
|
else
|
||||||
|
W16(dst, C816(apd->last[0].b));
|
||||||
dst += 2;
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
|
@ -539,6 +602,7 @@ static void cvtSS168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -549,8 +613,13 @@ static void cvtSS168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
*dst++ = C168(I(apd->last[0].s, R16(src) , r));
|
if (*nsrc) { /* don't go off end of data */
|
||||||
*dst++ = C168(I(apd->last[1].s, R16(src+2), r));
|
*dst++ = C168(I(apd->last[0].s, R16(src) , r));
|
||||||
|
*dst++ = C168(I(apd->last[1].s, R16(src+2), r));
|
||||||
|
} else {
|
||||||
|
*dst++ = C168(apd->last[0].s);
|
||||||
|
*dst++ = C168(apd->last[1].s);
|
||||||
|
}
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -560,6 +629,7 @@ static void cvtSM168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -570,8 +640,11 @@ static void cvtSM168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
*dst++ = C168(I(M16(apd->last[0].s, apd->last[1].s),
|
if (*nsrc) /* don't go off end of data */
|
||||||
M16(R16(src), R16(src + 2)), r));
|
*dst++ = C168(I(M16(apd->last[0].s, apd->last[1].s),
|
||||||
|
M16(R16(src), R16(src + 2)), r));
|
||||||
|
else
|
||||||
|
*dst++ = C168(M16(apd->last[0].s, apd->last[1].s));
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -582,6 +655,7 @@ static void cvtMS168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -591,7 +665,11 @@ static void cvtMS168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
dst[0] = dst[1] = C168(I(apd->last[0].s, R16(src), r)); dst += 2;
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
dst[0] = dst[1] = C168(I(apd->last[0].s, R16(src), r));
|
||||||
|
else
|
||||||
|
dst[0] = dst[1] = C168(apd->last[0].s);
|
||||||
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -602,6 +680,7 @@ static void cvtMM168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -611,7 +690,10 @@ static void cvtMM168C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
*dst++ = C168(I(apd->last[0].s, R16(src), r));
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
*dst++ = C168(I(apd->last[0].s, R16(src), r));
|
||||||
|
else
|
||||||
|
*dst++ = C168(apd->last[0].s);
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -621,6 +703,7 @@ static void cvtSS1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -631,8 +714,16 @@ static void cvtSS1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
W16(dst, I(apd->last[0].s, R16(src) , r)); dst += 2;
|
if (*nsrc) /* don't go off end of data */
|
||||||
W16(dst, I(apd->last[1].s, R16(src+2), r)); dst += 2;
|
W16(dst, I(apd->last[0].s, R16(src), r));
|
||||||
|
else
|
||||||
|
W16(dst, apd->last[0].s);
|
||||||
|
dst += 2;
|
||||||
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
W16(dst, I(apd->last[1].s, R16(src+2), r));
|
||||||
|
else
|
||||||
|
W16(dst, apd->last[1].s);
|
||||||
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -642,6 +733,7 @@ static void cvtSM1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -652,8 +744,11 @@ static void cvtSM1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
W16(dst, I(M16(apd->last[0].s, apd->last[1].s),
|
if (*nsrc) /* don't go off end of data */
|
||||||
M16(R16(src), R16(src+2)), r));
|
W16(dst, I(M16(apd->last[0].s, apd->last[1].s),
|
||||||
|
M16(R16(src), R16(src+2)), r));
|
||||||
|
else
|
||||||
|
W16(dst, M16(apd->last[0].s, apd->last[1].s));
|
||||||
dst += 2;
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
|
@ -665,6 +760,7 @@ static void cvtMS1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
short v;
|
short v;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -674,7 +770,10 @@ static void cvtMS1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
v = I(apd->last[0].s, R16(src), r);
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
v = I(apd->last[0].s, R16(src), r);
|
||||||
|
else
|
||||||
|
v = apd->last[0].s;
|
||||||
W16(dst, v); dst += 2;
|
W16(dst, v); dst += 2;
|
||||||
W16(dst, v); dst += 2;
|
W16(dst, v); dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
|
@ -686,6 +785,7 @@ static void cvtMM1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
double r;
|
double r;
|
||||||
|
TRACE("(%p, %p, %p, %p, %p)\n", apd, src, nsrc, dst, ndst);
|
||||||
|
|
||||||
while (*nsrc != 0 && *ndst != 0) {
|
while (*nsrc != 0 && *ndst != 0) {
|
||||||
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
while ((r = (double)apd->srcPos - apd->dstPos) <= 0) {
|
||||||
|
@ -695,7 +795,11 @@ static void cvtMM1616C(AcmPcmData* apd, const unsigned char* src, LPDWORD nsrc,
|
||||||
(*nsrc)--;
|
(*nsrc)--;
|
||||||
}
|
}
|
||||||
/* now do the interpolation */
|
/* now do the interpolation */
|
||||||
W16(dst, I(apd->last[0].s, R16(src), r)); dst += 2;
|
if (*nsrc) /* don't go off end of data */
|
||||||
|
W16(dst, I(apd->last[0].s, R16(src), r));
|
||||||
|
else
|
||||||
|
W16(dst, apd->last[0].s);
|
||||||
|
dst += 2;
|
||||||
apd->dstPos += apd->dstIncr;
|
apd->dstPos += apd->dstIncr;
|
||||||
(*ndst)--;
|
(*ndst)--;
|
||||||
}
|
}
|
||||||
|
@ -716,6 +820,8 @@ static void (*PCM_ConvertChangeRate[16])(AcmPcmData* apd,
|
||||||
*/
|
*/
|
||||||
static LRESULT PCM_DriverDetails(PACMDRIVERDETAILSW add)
|
static LRESULT PCM_DriverDetails(PACMDRIVERDETAILSW add)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p)\n", add);
|
||||||
|
|
||||||
add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
|
add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
|
||||||
add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
|
add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
|
||||||
add->wMid = 0xFF;
|
add->wMid = 0xFF;
|
||||||
|
@ -745,17 +851,27 @@ static LRESULT PCM_DriverDetails(PACMDRIVERDETAILSW add)
|
||||||
*/
|
*/
|
||||||
static LRESULT PCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
|
static LRESULT PCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %08lx)\n", aftd, dwQuery);
|
||||||
|
|
||||||
switch (dwQuery) {
|
switch (dwQuery) {
|
||||||
case ACM_FORMATTAGDETAILSF_INDEX:
|
case ACM_FORMATTAGDETAILSF_INDEX:
|
||||||
if (aftd->dwFormatTagIndex != 0) return ACMERR_NOTPOSSIBLE;
|
if (aftd->dwFormatTagIndex != 0) {
|
||||||
|
WARN("not possible\n");
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
case ACM_FORMATTAGDETAILSF_FORMATTAG:
|
||||||
if (aftd->dwFormatTag != WAVE_FORMAT_PCM) return ACMERR_NOTPOSSIBLE;
|
if (aftd->dwFormatTag != WAVE_FORMAT_PCM) {
|
||||||
|
WARN("not possible\n");
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
|
||||||
if (aftd->dwFormatTag != WAVE_FORMAT_UNKNOWN &&
|
if (aftd->dwFormatTag != WAVE_FORMAT_UNKNOWN &&
|
||||||
aftd->dwFormatTag != WAVE_FORMAT_PCM)
|
aftd->dwFormatTag != WAVE_FORMAT_PCM) {
|
||||||
|
WARN("not possible\n");
|
||||||
return ACMERR_NOTPOSSIBLE;
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
WARN("Unsupported query %08lx\n", dwQuery);
|
WARN("Unsupported query %08lx\n", dwQuery);
|
||||||
|
@ -778,9 +894,14 @@ static LRESULT PCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
|
||||||
*/
|
*/
|
||||||
static LRESULT PCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
|
static LRESULT PCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %08lx)\n", afd, dwQuery);
|
||||||
|
|
||||||
switch (dwQuery) {
|
switch (dwQuery) {
|
||||||
case ACM_FORMATDETAILSF_FORMAT:
|
case ACM_FORMATDETAILSF_FORMAT:
|
||||||
if (PCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
if (PCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) {
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
WARN("not possible\n");
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ACM_FORMATDETAILSF_INDEX:
|
case ACM_FORMATDETAILSF_INDEX:
|
||||||
assert(afd->dwFormatIndex < NUM_PCM_FORMATS);
|
assert(afd->dwFormatIndex < NUM_PCM_FORMATS);
|
||||||
|
@ -815,10 +936,15 @@ static LRESULT PCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
|
||||||
*/
|
*/
|
||||||
static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p)\n", adfs);
|
||||||
|
|
||||||
/* some tests ... */
|
/* some tests ... */
|
||||||
if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
|
if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
|
||||||
adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
|
adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
|
||||||
PCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
PCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) {
|
||||||
|
WARN("not possible\n");
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
/* is no suggestion for destination, then copy source value */
|
/* is no suggestion for destination, then copy source value */
|
||||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS)) {
|
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS)) {
|
||||||
|
@ -831,11 +957,17 @@ static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
||||||
adfs->pwfxDst->wBitsPerSample = adfs->pwfxSrc->wBitsPerSample;
|
adfs->pwfxDst->wBitsPerSample = adfs->pwfxSrc->wBitsPerSample;
|
||||||
}
|
}
|
||||||
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG)) {
|
if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG)) {
|
||||||
if (adfs->pwfxSrc->wFormatTag != WAVE_FORMAT_PCM) return ACMERR_NOTPOSSIBLE;
|
if (adfs->pwfxSrc->wFormatTag != WAVE_FORMAT_PCM) {
|
||||||
|
WARN("not possible\n");
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
adfs->pwfxDst->wFormatTag = adfs->pwfxSrc->wFormatTag;
|
adfs->pwfxDst->wFormatTag = adfs->pwfxSrc->wFormatTag;
|
||||||
}
|
}
|
||||||
/* check if result is ok */
|
/* check if result is ok */
|
||||||
if (PCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
|
if (PCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) {
|
||||||
|
WARN("not possible\n");
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
/* recompute other values */
|
/* recompute other values */
|
||||||
adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
|
adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
|
||||||
|
@ -850,6 +982,8 @@ static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
||||||
*/
|
*/
|
||||||
static void PCM_Reset(AcmPcmData* apd, int srcNumBits)
|
static void PCM_Reset(AcmPcmData* apd, int srcNumBits)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p, %d)\n", apd, srcNumBits);
|
||||||
|
|
||||||
apd->srcPos = 0;
|
apd->srcPos = 0;
|
||||||
apd->dstPos = 0;
|
apd->dstPos = 0;
|
||||||
/* initialize with neutral value */
|
/* initialize with neutral value */
|
||||||
|
@ -871,14 +1005,21 @@ static LRESULT PCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||||
AcmPcmData* apd;
|
AcmPcmData* apd;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", adsi);
|
||||||
|
|
||||||
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
||||||
|
|
||||||
if (PCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
if (PCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
||||||
PCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
|
PCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF) {
|
||||||
|
WARN("not possible\n");
|
||||||
return ACMERR_NOTPOSSIBLE;
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
apd = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmPcmData));
|
apd = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmPcmData));
|
||||||
if (apd == 0) return MMSYSERR_NOMEM;
|
if (apd == 0) {
|
||||||
|
WARN("no memory\n");
|
||||||
|
return MMSYSERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
adsi->dwDriver = (DWORD)apd;
|
adsi->dwDriver = (DWORD)apd;
|
||||||
adsi->fdwDriver = 0;
|
adsi->fdwDriver = 0;
|
||||||
|
@ -907,6 +1048,8 @@ static LRESULT PCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||||
*/
|
*/
|
||||||
static LRESULT PCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
static LRESULT PCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p)\n", adsi);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
@ -931,6 +1074,8 @@ static LRESULT PCM_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss
|
||||||
DWORD srcMask = ~(adsi->pwfxSrc->nBlockAlign - 1);
|
DWORD srcMask = ~(adsi->pwfxSrc->nBlockAlign - 1);
|
||||||
DWORD dstMask = ~(adsi->pwfxDst->nBlockAlign - 1);
|
DWORD dstMask = ~(adsi->pwfxDst->nBlockAlign - 1);
|
||||||
|
|
||||||
|
TRACE("(%p, %p)\n", adsi, adss);
|
||||||
|
|
||||||
switch (adss->fdwSize) {
|
switch (adss->fdwSize) {
|
||||||
case ACM_STREAMSIZEF_DESTINATION:
|
case ACM_STREAMSIZEF_DESTINATION:
|
||||||
/* cbDstLength => cbSrcLength */
|
/* cbDstLength => cbSrcLength */
|
||||||
|
@ -961,6 +1106,17 @@ static LRESULT PCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER
|
||||||
DWORD nsrc = NUM_OF(adsh->cbSrcLength, adsi->pwfxSrc->nBlockAlign);
|
DWORD nsrc = NUM_OF(adsh->cbSrcLength, adsi->pwfxSrc->nBlockAlign);
|
||||||
DWORD ndst = NUM_OF(adsh->cbDstLength, adsi->pwfxDst->nBlockAlign);
|
DWORD ndst = NUM_OF(adsh->cbDstLength, adsi->pwfxDst->nBlockAlign);
|
||||||
|
|
||||||
|
TRACE("(%p, %p)\n", adsi, adsh);
|
||||||
|
|
||||||
|
TRACE("nsrc=%ld,adsh->cbSrcLength=%ld\n", nsrc, adsh->cbSrcLength);
|
||||||
|
TRACE("ndst=%ld,adsh->cbDstLength=%ld\n", ndst, adsh->cbDstLength);
|
||||||
|
TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
|
||||||
|
adsi->pwfxSrc->wFormatTag, adsi->pwfxSrc->nChannels, adsi->pwfxSrc->nSamplesPerSec, adsi->pwfxSrc->nAvgBytesPerSec,
|
||||||
|
adsi->pwfxSrc->nBlockAlign, adsi->pwfxSrc->wBitsPerSample, adsi->pwfxSrc->cbSize);
|
||||||
|
TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
|
||||||
|
adsi->pwfxDst->wFormatTag, adsi->pwfxDst->nChannels, adsi->pwfxDst->nSamplesPerSec, adsi->pwfxDst->nAvgBytesPerSec,
|
||||||
|
adsi->pwfxDst->nBlockAlign, adsi->pwfxDst->wBitsPerSample, adsi->pwfxDst->cbSize);
|
||||||
|
|
||||||
if (adsh->fdwConvert &
|
if (adsh->fdwConvert &
|
||||||
~(ACM_STREAMCONVERTF_BLOCKALIGN|
|
~(ACM_STREAMCONVERTF_BLOCKALIGN|
|
||||||
ACM_STREAMCONVERTF_END|
|
ACM_STREAMCONVERTF_END|
|
||||||
|
|
|
@ -44,6 +44,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(msacm);
|
||||||
|
|
||||||
static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
|
static PWINE_ACMSTREAM ACM_GetStream(HACMSTREAM has)
|
||||||
{
|
{
|
||||||
|
TRACE("(%p)\n", has);
|
||||||
|
|
||||||
return (PWINE_ACMSTREAM)has;
|
return (PWINE_ACMSTREAM)has;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +60,7 @@ MMRESULT WINAPI acmStreamClose(HACMSTREAM has, DWORD fdwClose)
|
||||||
TRACE("(%p, %ld)\n", has, fdwClose);
|
TRACE("(%p, %ld)\n", has, fdwClose);
|
||||||
|
|
||||||
if ((was = ACM_GetStream(has)) == NULL) {
|
if ((was = ACM_GetStream(has)) == NULL) {
|
||||||
|
WARN("invalid handle\n");
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
}
|
}
|
||||||
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
|
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_CLOSE, (DWORD)&was->drvInst, 0);
|
||||||
|
@ -82,13 +85,18 @@ MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
|
||||||
|
|
||||||
TRACE("(%p, %p, %ld)\n", has, pash, fdwConvert);
|
TRACE("(%p, %p, %ld)\n", has, pash, fdwConvert);
|
||||||
|
|
||||||
if ((was = ACM_GetStream(has)) == NULL)
|
if ((was = ACM_GetStream(has)) == NULL) {
|
||||||
|
WARN("invalid handle\n");
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
|
}
|
||||||
|
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
|
}
|
||||||
if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
|
if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) {
|
||||||
|
WARN("unprepared header\n");
|
||||||
return ACMERR_UNPREPARED;
|
return ACMERR_UNPREPARED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
|
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
|
||||||
* size. some fields are private to msacm internals, and are exposed
|
* size. some fields are private to msacm internals, and are exposed
|
||||||
|
@ -101,6 +109,7 @@ MMRESULT WINAPI acmStreamConvert(HACMSTREAM has, PACMSTREAMHEADER pash,
|
||||||
padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
|
padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
|
||||||
padsh->pbPreparedDst != padsh->pbDst ||
|
padsh->pbPreparedDst != padsh->pbDst ||
|
||||||
padsh->cbPreparedDstLength < padsh->cbDstLength) {
|
padsh->cbPreparedDstLength < padsh->cbDstLength) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,10 +146,27 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pw
|
||||||
MMRESULT ret;
|
MMRESULT ret;
|
||||||
int wfxSrcSize;
|
int wfxSrcSize;
|
||||||
int wfxDstSize;
|
int wfxDstSize;
|
||||||
|
WAVEFORMATEX wfxSrc, wfxDst;
|
||||||
|
|
||||||
TRACE("(%p, %p, %p, %p, %p, %ld, %ld, %ld)\n",
|
TRACE("(%p, %p, %p, %p, %p, %ld, %ld, %ld)\n",
|
||||||
phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
|
phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen);
|
||||||
|
|
||||||
|
/* NOTE: pwfxSrc and/or pwfxDst can point to a structure smaller than
|
||||||
|
* WAVEFORMATEX so don't use them directly when not sure */
|
||||||
|
if (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) {
|
||||||
|
memcpy(&wfxSrc, pwfxSrc, sizeof(PCMWAVEFORMAT));
|
||||||
|
wfxSrc.wBitsPerSample = pwfxSrc->wBitsPerSample;
|
||||||
|
wfxSrc.cbSize = 0;
|
||||||
|
pwfxSrc = &wfxSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pwfxDst->wFormatTag == WAVE_FORMAT_PCM) {
|
||||||
|
memcpy(&wfxDst, pwfxDst, sizeof(PCMWAVEFORMAT));
|
||||||
|
wfxDst.wBitsPerSample = pwfxDst->wBitsPerSample;
|
||||||
|
wfxDst.cbSize = 0;
|
||||||
|
pwfxDst = &wfxDst;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
|
TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%lu, nAvgBytesPerSec=%lu, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
|
||||||
pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
|
pwfxSrc->wFormatTag, pwfxSrc->nChannels, pwfxSrc->nSamplesPerSec, pwfxSrc->nAvgBytesPerSec,
|
||||||
pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
|
pwfxSrc->nBlockAlign, pwfxSrc->wBitsPerSample, pwfxSrc->cbSize);
|
||||||
|
@ -155,7 +181,10 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pw
|
||||||
*/
|
*/
|
||||||
if (fdwOpen & ACM_STREAMOPENF_QUERY) phas = NULL;
|
if (fdwOpen & ACM_STREAMOPENF_QUERY) phas = NULL;
|
||||||
|
|
||||||
if (pwfltr && (pwfxSrc->wFormatTag != pwfxDst->wFormatTag)) return MMSYSERR_INVALPARAM;
|
if (pwfltr && (pwfxSrc->wFormatTag != pwfxDst->wFormatTag)) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
|
return MMSYSERR_INVALPARAM;
|
||||||
|
}
|
||||||
|
|
||||||
wfxSrcSize = wfxDstSize = sizeof(WAVEFORMATEX);
|
wfxSrcSize = wfxDstSize = sizeof(WAVEFORMATEX);
|
||||||
if (pwfxSrc->wFormatTag != WAVE_FORMAT_PCM) wfxSrcSize += pwfxSrc->cbSize;
|
if (pwfxSrc->wFormatTag != WAVE_FORMAT_PCM) wfxSrcSize += pwfxSrc->cbSize;
|
||||||
|
@ -163,8 +192,10 @@ MMRESULT WINAPI acmStreamOpen(PHACMSTREAM phas, HACMDRIVER had, PWAVEFORMATEX pw
|
||||||
|
|
||||||
was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize +
|
was = HeapAlloc(MSACM_hHeap, 0, sizeof(*was) + wfxSrcSize + wfxDstSize +
|
||||||
((pwfltr) ? sizeof(WAVEFILTER) : 0));
|
((pwfltr) ? sizeof(WAVEFILTER) : 0));
|
||||||
if (was == NULL)
|
if (was == NULL) {
|
||||||
|
WARN("no memory\n");
|
||||||
return MMSYSERR_NOMEM;
|
return MMSYSERR_NOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
was->drvInst.cbStruct = sizeof(was->drvInst);
|
was->drvInst.cbStruct = sizeof(was->drvInst);
|
||||||
was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
|
was->drvInst.pwfxSrc = (PWAVEFORMATEX)((LPSTR)was + sizeof(*was));
|
||||||
|
@ -263,10 +294,14 @@ MMRESULT WINAPI acmStreamPrepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
|
||||||
|
|
||||||
TRACE("(%p, %p, %ld)\n", has, pash, fdwPrepare);
|
TRACE("(%p, %p, %ld)\n", has, pash, fdwPrepare);
|
||||||
|
|
||||||
if ((was = ACM_GetStream(has)) == NULL)
|
if ((was = ACM_GetStream(has)) == NULL) {
|
||||||
|
WARN("invalid handle\n");
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
|
}
|
||||||
|
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
|
}
|
||||||
if (fdwPrepare)
|
if (fdwPrepare)
|
||||||
ret = MMSYSERR_INVALFLAG;
|
ret = MMSYSERR_INVALFLAG;
|
||||||
|
|
||||||
|
@ -324,8 +359,10 @@ MMRESULT WINAPI acmStreamReset(HACMSTREAM has, DWORD fdwReset)
|
||||||
TRACE("(%p, %ld)\n", has, fdwReset);
|
TRACE("(%p, %ld)\n", has, fdwReset);
|
||||||
|
|
||||||
if (fdwReset) {
|
if (fdwReset) {
|
||||||
|
WARN("invalid flag\n");
|
||||||
ret = MMSYSERR_INVALFLAG;
|
ret = MMSYSERR_INVALFLAG;
|
||||||
} else if ((was = ACM_GetStream(has)) == NULL) {
|
} else if ((was = ACM_GetStream(has)) == NULL) {
|
||||||
|
WARN("invalid handle\n");
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
} else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
|
} else if (was->drvInst.fdwOpen & ACM_STREAMOPENF_ASYNC) {
|
||||||
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
|
ret = SendDriverMessage(was->pDrv->hDrvr, ACMDM_STREAM_RESET, (DWORD)&was->drvInst, 0);
|
||||||
|
@ -347,9 +384,11 @@ MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
|
||||||
TRACE("(%p, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
|
TRACE("(%p, %ld, %p, %ld)\n", has, cbInput, pdwOutputBytes, fdwSize);
|
||||||
|
|
||||||
if ((was = ACM_GetStream(has)) == NULL) {
|
if ((was = ACM_GetStream(has)) == NULL) {
|
||||||
|
WARN("invalid handle\n");
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
}
|
}
|
||||||
if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
|
if ((fdwSize & ~ACM_STREAMSIZEF_QUERYMASK) != 0) {
|
||||||
|
WARN("invalid flag\n");
|
||||||
return MMSYSERR_INVALFLAG;
|
return MMSYSERR_INVALFLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +404,7 @@ MMRESULT WINAPI acmStreamSize(HACMSTREAM has, DWORD cbInput,
|
||||||
adss.cbDstLength = 0;
|
adss.cbDstLength = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
WARN("invalid flag\n");
|
||||||
return MMSYSERR_INVALFLAG;
|
return MMSYSERR_INVALFLAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,13 +438,18 @@ MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
|
||||||
|
|
||||||
TRACE("(%p, %p, %ld)\n", has, pash, fdwUnprepare);
|
TRACE("(%p, %p, %ld)\n", has, pash, fdwUnprepare);
|
||||||
|
|
||||||
if ((was = ACM_GetStream(has)) == NULL)
|
if ((was = ACM_GetStream(has)) == NULL) {
|
||||||
|
WARN("invalid handle\n");
|
||||||
return MMSYSERR_INVALHANDLE;
|
return MMSYSERR_INVALHANDLE;
|
||||||
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER))
|
}
|
||||||
|
if (!pash || pash->cbStruct < sizeof(ACMSTREAMHEADER)) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
|
}
|
||||||
if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED))
|
if (!(pash->fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED)) {
|
||||||
|
WARN("unprepared header\n");
|
||||||
return ACMERR_UNPREPARED;
|
return ACMERR_UNPREPARED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
|
/* Note: the ACMSTREAMHEADER and ACMDRVSTREAMHEADER structs are of same
|
||||||
* size. some fields are private to msacm internals, and are exposed
|
* size. some fields are private to msacm internals, and are exposed
|
||||||
|
@ -417,6 +462,7 @@ MMRESULT WINAPI acmStreamUnprepareHeader(HACMSTREAM has, PACMSTREAMHEADER pash,
|
||||||
padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
|
padsh->cbPreparedSrcLength < padsh->cbSrcLength ||
|
||||||
padsh->pbPreparedDst != padsh->pbDst ||
|
padsh->pbPreparedDst != padsh->pbDst ||
|
||||||
padsh->cbPreparedDstLength < padsh->cbDstLength) {
|
padsh->cbPreparedDstLength < padsh->cbDstLength) {
|
||||||
|
WARN("invalid parameter\n");
|
||||||
return MMSYSERR_INVALPARAM;
|
return MMSYSERR_INVALPARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue