Vincent Pelletier : msadp32.acm: Block align the adpcm extra data.
Alexandre Julliard
julliard at winehq.org
Wed Feb 4 09:15:45 CST 2009
Module: wine
Branch: master
Commit: 0924ddd2ba981bb6cd2fcd55c4b2cfed7527030b
URL: http://source.winehq.org/git/wine.git/?a=commit;h=0924ddd2ba981bb6cd2fcd55c4b2cfed7527030b
Author: Vincent Pelletier <plr.vincent at gmail.com>
Date: Sun Feb 1 09:51:31 2009 +0100
msadp32.acm: Block align the adpcm extra data.
Based heavily on Stefano Guidoni's patch.
---
dlls/msadp32.acm/msadp32.c | 37 +++++++++++++++++++++++++++++--------
1 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/dlls/msadp32.acm/msadp32.c b/dlls/msadp32.acm/msadp32.c
index 40b8260..f345450 100644
--- a/dlls/msadp32.acm/msadp32.c
+++ b/dlls/msadp32.acm/msadp32.c
@@ -618,6 +618,9 @@ static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
*/
static LRESULT ADPCM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
{
+ DWORD nblocks;
+ WORD wSamplesPerBlock;
+ /* wSamplesPerBlock formula comes from MSDN ADPCMWAVEFORMAT page.*/
switch (adss->fdwSize)
{
case ACM_STREAMSIZEF_DESTINATION:
@@ -625,14 +628,20 @@ static LRESULT ADPCM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMS
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ADPCM)
{
- /* don't take block overhead into account, doesn't matter too much */
- adss->cbSrcLength = adss->cbDstLength * 4;
+ wSamplesPerBlock = adsi->pwfxDst->nBlockAlign * 2 / adsi->pwfxDst->nChannels - 12;
+ nblocks = adss->cbDstLength / adsi->pwfxDst->nBlockAlign;
+ if (nblocks == 0)
+ return ACMERR_NOTPOSSIBLE;
+ adss->cbSrcLength = nblocks * adsi->pwfxSrc->nBlockAlign * wSamplesPerBlock;
}
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{
- FIXME("misses the block header overhead\n");
- adss->cbSrcLength = 256 + adss->cbDstLength / 4;
+ wSamplesPerBlock = adsi->pwfxSrc->nBlockAlign * 2 / adsi->pwfxSrc->nChannels - 12;
+ nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * wSamplesPerBlock);
+ if (nblocks == 0)
+ return ACMERR_NOTPOSSIBLE;
+ adss->cbSrcLength = nblocks * adsi->pwfxSrc->nBlockAlign;
}
else
{
@@ -644,14 +653,26 @@ static LRESULT ADPCM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMS
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ADPCM)
{
- FIXME("misses the block header overhead\n");
- adss->cbDstLength = 256 + adss->cbSrcLength / 4;
+ wSamplesPerBlock = adsi->pwfxDst->nBlockAlign * 2 / adsi->pwfxDst->nChannels - 12;
+ nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * wSamplesPerBlock);
+ if (nblocks == 0)
+ return ACMERR_NOTPOSSIBLE;
+ if (adss->cbSrcLength % (adsi->pwfxSrc->nBlockAlign * wSamplesPerBlock))
+ /* Round block count up. */
+ nblocks++;
+ adss->cbDstLength = nblocks * adsi->pwfxSrc->nBlockAlign;
}
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ADPCM &&
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
{
- /* don't take block overhead into account, doesn't matter too much */
- adss->cbDstLength = adss->cbSrcLength * 4;
+ wSamplesPerBlock = adsi->pwfxSrc->nBlockAlign * 2 / adsi->pwfxSrc->nChannels - 12;
+ nblocks = adss->cbSrcLength / adsi->pwfxSrc->nBlockAlign;
+ if (nblocks == 0)
+ return ACMERR_NOTPOSSIBLE;
+ if (adss->cbSrcLength % adsi->pwfxSrc->nBlockAlign)
+ /* Round block count up. */
+ nblocks++;
+ adss->cbDstLength = nblocks * adsi->pwfxSrc->nBlockAlign * wSamplesPerBlock;
}
else
{
More information about the wine-cvs
mailing list