msacm32: Added converter for ADPCM to PCM 8 bit mono.
Signed-off-by: Fabian Maurer <dark.shadow4@web.de> Signed-off-by: Andrew Eikum <aeikum@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a0fe286174
commit
351bd33f2c
|
@ -179,6 +179,25 @@ static inline void W16(unsigned char* dst, short s)
|
||||||
dst[1] = HIBYTE(s);
|
dst[1] = HIBYTE(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* W8
|
||||||
|
*
|
||||||
|
* Write a 8 bit sample
|
||||||
|
*/
|
||||||
|
static inline void W8(unsigned char* dst, short s)
|
||||||
|
{
|
||||||
|
dst[0] = (unsigned char)((s + 32768) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void W8_16(unsigned char* dst, short s, int bytes)
|
||||||
|
{
|
||||||
|
if(bytes == 1)
|
||||||
|
W8(dst, s);
|
||||||
|
else
|
||||||
|
W16(dst, s);
|
||||||
|
}
|
||||||
|
|
||||||
/* IMA (or DVI) APDCM codec routines */
|
/* IMA (or DVI) APDCM codec routines */
|
||||||
|
|
||||||
static const unsigned IMA_StepTable[89] =
|
static const unsigned IMA_StepTable[89] =
|
||||||
|
@ -339,43 +358,43 @@ static void cvtSSima16K(PACMDRVSTREAMINSTANCE adsi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cvtMMima16K(PACMDRVSTREAMINSTANCE adsi,
|
static void cvtMMimaK(PACMDRVSTREAMINSTANCE adsi,
|
||||||
const unsigned char* src, LPDWORD nsrc,
|
const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
{
|
{
|
||||||
int sample;
|
int sample;
|
||||||
int stepIndex;
|
int stepIndex;
|
||||||
int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||||
int nsamp;
|
int nsamp;
|
||||||
|
int bytesPerSample = adsi->pwfxDst->wBitsPerSample / 8;
|
||||||
/* compute the number of entire blocks we can decode...
|
/* compute the number of entire blocks we can decode...
|
||||||
* it's the min of the number of entire blocks in source buffer and the number
|
* it's the min of the number of entire blocks in source buffer and the number
|
||||||
* of entire blocks in destination buffer
|
* of entire blocks in destination buffer
|
||||||
*/
|
*/
|
||||||
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
|
DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, *ndst / (nsamp_blk * bytesPerSample));
|
||||||
*ndst / (nsamp_blk * 2));
|
|
||||||
|
|
||||||
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
|
*nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
|
||||||
*ndst = nblock * nsamp_blk * 2;
|
*ndst = nblock * nsamp_blk * bytesPerSample;
|
||||||
|
|
||||||
nsamp_blk--; /* remove the sample in block header */
|
nsamp_blk--; /* remove the sample in block header */
|
||||||
for (; nblock > 0; nblock--)
|
for (; nblock > 0; nblock--)
|
||||||
{
|
{
|
||||||
const unsigned char* in_src = src;
|
const unsigned char* in_src = src;
|
||||||
|
|
||||||
/* handle header first */
|
/* handle header first */
|
||||||
sample = R16(src);
|
sample = R16(src);
|
||||||
stepIndex = (unsigned)*(src + 2);
|
stepIndex = (unsigned)*(src + 2);
|
||||||
clamp_step_index(&stepIndex);
|
clamp_step_index(&stepIndex);
|
||||||
src += 4;
|
src += 4;
|
||||||
W16(dst, sample); dst += 2;
|
W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
|
||||||
|
|
||||||
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
|
for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
|
||||||
{
|
{
|
||||||
process_nibble(*src, &stepIndex, &sample);
|
process_nibble(*src, &stepIndex, &sample);
|
||||||
W16(dst, sample); dst += 2;
|
W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
|
||||||
process_nibble(*src++ >> 4, &stepIndex, &sample);
|
process_nibble(*src++ >> 4, &stepIndex, &sample);
|
||||||
W16(dst, sample); dst += 2;
|
W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
|
||||||
}
|
}
|
||||||
/* we have now to realign the source pointer on block */
|
/* we have now to realign the source pointer on block */
|
||||||
src = in_src + adsi->pwfxSrc->nBlockAlign;
|
src = in_src + adsi->pwfxSrc->nBlockAlign;
|
||||||
}
|
}
|
||||||
|
@ -733,13 +752,14 @@ static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
|
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_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
|
* ADPCM algo only define 16 bit per sample output
|
||||||
|
* (The API seems to still allow 8 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)
|
(adsi->pwfxDst->wBitsPerSample != 16 && adsi->pwfxDst->wBitsPerSample != 8))
|
||||||
goto theEnd;
|
goto theEnd;
|
||||||
|
|
||||||
nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
|
||||||
TRACE("spb=%u\n", nspb);
|
TRACE("spb=%u\n", nspb);
|
||||||
|
@ -752,11 +772,16 @@ static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||||
if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign)
|
if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign)
|
||||||
goto theEnd;
|
goto theEnd;
|
||||||
|
|
||||||
/* adpcm decoding... */
|
/* adpcm decoding... */
|
||||||
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
|
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
|
||||||
aad->convert = cvtSSima16K;
|
aad->convert = cvtSSima16K;
|
||||||
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
|
if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
|
||||||
aad->convert = cvtMMima16K;
|
aad->convert = cvtMMimaK;
|
||||||
|
if (adsi->pwfxDst->wBitsPerSample == 8 && adsi->pwfxDst->nChannels == 1)
|
||||||
|
aad->convert = cvtMMimaK;
|
||||||
|
/* FIXME: Stereo support for 8bit samples*/
|
||||||
|
if (adsi->pwfxDst->wBitsPerSample == 8 && adsi->pwfxDst->nChannels == 2)
|
||||||
|
goto theEnd;
|
||||||
}
|
}
|
||||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM)
|
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM)
|
||||||
|
|
Loading…
Reference in New Issue