Module: wine Branch: master Commit: 0924ddd2ba981bb6cd2fcd55c4b2cfed7527030b URL: http://source.winehq.org/git/wine.git/?a=commit;h=0924ddd2ba981bb6cd2fcd55c4...
Author: Vincent Pelletier plr.vincent@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 {