msadp32: Also convert to 8-bit PCM.

This commit is contained in:
Andrew Eikum 2013-11-04 10:05:58 -06:00 committed by Alexandre Julliard
parent 1483bfa21d
commit 39185814b1
1 changed files with 62 additions and 30 deletions

View File

@ -223,6 +223,11 @@ static inline void process_nibble(unsigned nibble, int* idelta,
if (*idelta < 16) *idelta = 16; if (*idelta < 16) *idelta = 16;
} }
static inline unsigned char C168(short s)
{
return HIBYTE(s) ^ (unsigned char)0x80;
}
static void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi, static void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi,
const unsigned char* src, LPDWORD nsrc, const unsigned char* src, LPDWORD nsrc,
unsigned char* dst, LPDWORD ndst) unsigned char* dst, LPDWORD ndst)
@ -234,10 +239,10 @@ static void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi,
int nsamp; int nsamp;
int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock; int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
*ndst / (nsamp_blk * 2 * 2)); *ndst / (nsamp_blk * adsi->pwfxDst->nBlockAlign));
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign; *nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
*ndst = nblock * nsamp_blk * 2 * 2; *ndst = nblock * nsamp_blk * adsi->pwfxDst->nBlockAlign;
nsamp_blk -= 2; /* see below for samples from block head */ nsamp_blk -= 2; /* see below for samples from block head */
for (; nblock > 0; nblock--) for (; nblock > 0; nblock--)
@ -256,18 +261,34 @@ static void cvtSSms16K(const ACMDRVSTREAMINSTANCE *adsi,
sample2L = R16(src); src += 2; sample2L = R16(src); src += 2;
sample2R = R16(src); src += 2; sample2R = R16(src); src += 2;
/* store samples from block head */ if(adsi->pwfxDst->wBitsPerSample == 8){
W16(dst, sample2L); dst += 2; /* store samples from block head */
W16(dst, sample2R); dst += 2; *dst = C168(sample2L); ++dst;
W16(dst, sample1L); dst += 2; *dst = C168(sample2R); ++dst;
W16(dst, sample1R); dst += 2; *dst = C168(sample1L); ++dst;
*dst = C168(sample1R); ++dst;
for (nsamp = nsamp_blk; nsamp > 0; nsamp--) for (nsamp = nsamp_blk; nsamp > 0; nsamp--)
{ {
process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL); process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL);
W16(dst, sample1L); dst += 2; *dst = C168(sample1L); ++dst;
process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR); process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR);
W16(dst, sample1R); dst += 2; *dst = C168(sample1R); ++dst;
}
}else if(adsi->pwfxDst->wBitsPerSample == 16){
/* store samples from block head */
W16(dst, sample2L); dst += 2;
W16(dst, sample2R); dst += 2;
W16(dst, sample1L); dst += 2;
W16(dst, sample1R); dst += 2;
for (nsamp = nsamp_blk; nsamp > 0; nsamp--)
{
process_nibble(*src >> 4, &ideltaL, &sample1L, &sample2L, &coeffL);
W16(dst, sample1L); dst += 2;
process_nibble(*src++ & 0x0F, &ideltaR, &sample1R, &sample2R, &coeffR);
W16(dst, sample1R); dst += 2;
}
} }
src = in_src + adsi->pwfxSrc->nBlockAlign; src = in_src + adsi->pwfxSrc->nBlockAlign;
} }
@ -283,10 +304,10 @@ static void cvtMMms16K(const ACMDRVSTREAMINSTANCE *adsi,
int nsamp; int nsamp;
int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock; int nsamp_blk = ((ADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
*ndst / (nsamp_blk * 2)); *ndst / (nsamp_blk * adsi->pwfxDst->nBlockAlign));
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign; *nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
*ndst = nblock * nsamp_blk * 2; *ndst = nblock * nsamp_blk * adsi->pwfxDst->nBlockAlign;
nsamp_blk -= 2; /* see below for samples from block head */ nsamp_blk -= 2; /* see below for samples from block head */
for (; nblock > 0; nblock--) for (; nblock > 0; nblock--)
@ -301,16 +322,30 @@ static void cvtMMms16K(const ACMDRVSTREAMINSTANCE *adsi,
sample2 = R16(src); src += 2; sample2 = R16(src); src += 2;
/* store samples from block head */ /* store samples from block head */
W16(dst, sample2); dst += 2; if(adsi->pwfxDst->wBitsPerSample == 8){
W16(dst, sample1); dst += 2; *dst = C168(sample2); ++dst;
*dst = C168(sample1); ++dst;
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2) for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
{ {
process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff); process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff);
W16(dst, sample1); dst += 2; *dst = C168(sample1); ++dst;
process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff); process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff);
W16(dst, sample1); dst += 2; *dst = C168(sample1); ++dst;
}
}else if(adsi->pwfxDst->wBitsPerSample == 16){
W16(dst, sample2); dst += 2;
W16(dst, sample1); dst += 2;
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
{
process_nibble(*src >> 4, &idelta, &sample1, &sample2, &coeff);
W16(dst, sample1); dst += 2;
process_nibble(*src++ & 0x0F, &idelta, &sample1, &sample2, &coeff);
W16(dst, sample1); dst += 2;
}
} }
src = in_src + adsi->pwfxSrc->nBlockAlign; src = in_src + adsi->pwfxSrc->nBlockAlign;
} }
} }
@ -553,12 +588,9 @@ static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM && else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{ {
/* resampling or mono <=> stereo not available /* resampling or mono <=> stereo not available */
* ADPCM algo only define 16 bit per sample output
*/
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec || if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels || adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels)
adsi->pwfxDst->wBitsPerSample != 16)
goto theEnd; goto theEnd;
#if 0 #if 0
@ -577,9 +609,9 @@ static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
#endif #endif
/* adpcm decoding... */ /* adpcm decoding... */
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2) if (adsi->pwfxDst->nChannels == 2)
aad->convert = cvtSSms16K; aad->convert = cvtSSms16K;
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1) else if (adsi->pwfxDst->nChannels == 1)
aad->convert = cvtMMms16K; aad->convert = cvtMMms16K;
} }
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&