diff --git a/reactos/dll/win32/msacm32/imaadp32/Makefile.in b/reactos/dll/win32/msacm32/imaadp32/Makefile.in deleted file mode 100644 index 79cc94e4aee..00000000000 --- a/reactos/dll/win32/msacm32/imaadp32/Makefile.in +++ /dev/null @@ -1,12 +0,0 @@ -TOPSRCDIR = @top_srcdir@ -TOPOBJDIR = ../../.. -SRCDIR = @srcdir@ -VPATH = @srcdir@ -MODULE = imaadp32.acm -IMPORTS = winmm user32 kernel32 - -C_SRCS = imaadp32.c - -@MAKE_DLL_RULES@ - -### Dependencies: diff --git a/reactos/dll/win32/msacm32/imaadp32/imaadp32.acm.spec b/reactos/dll/win32/msacm32/imaadp32/imaadp32.acm.spec deleted file mode 100644 index a0ba1c7e701..00000000000 --- a/reactos/dll/win32/msacm32/imaadp32/imaadp32.acm.spec +++ /dev/null @@ -1 +0,0 @@ -@ stdcall DriverProc (long long long long long) ADPCM_DriverProc diff --git a/reactos/dll/win32/msacm32/imaadp32/imaadp32.c b/reactos/dll/win32/msacm32/imaadp32/imaadp32.c deleted file mode 100644 index 573d583b27b..00000000000 --- a/reactos/dll/win32/msacm32/imaadp32/imaadp32.c +++ /dev/null @@ -1,938 +0,0 @@ -/* - * IMA ADPCM handling - * - * Copyright (C) 2001,2002 Eric Pouech - * - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "winnls.h" -#include "mmsystem.h" -#include "mmreg.h" -#include "msacm.h" -#include "msacmdrv.h" -#include "wine/debug.h" - -/* see http://www.pcisys.net/~melanson/codecs/adpcm.txt for the details */ - -WINE_DEFAULT_DEBUG_CHANNEL(adpcm); - -/*********************************************************************** - * ADPCM_drvOpen - */ -static DWORD ADPCM_drvOpen(LPCSTR str) -{ - return 1; -} - -/*********************************************************************** - * ADPCM_drvClose - */ -static DWORD ADPCM_drvClose(DWORD dwDevID) -{ - return 1; -} - -typedef struct tagAcmAdpcmData -{ - void (*convert)(PACMDRVSTREAMINSTANCE adsi, - const unsigned char*, LPDWORD, unsigned char*, LPDWORD); - /* IMA encoding only */ - BYTE stepIndexL; - BYTE stepIndexR; - /* short sample; */ -} AcmAdpcmData; - -/* table to list all supported formats... those are the basic ones. this - * also helps given a unique index to each of the supported formats - */ -typedef struct -{ - int nChannels; - int nBits; - int rate; -} Format; - -static Format PCM_Formats[] = -{ - {1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000}, - {1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025}, - {1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050}, - {1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100}, -}; - -static Format ADPCM_Formats[] = -{ - {1, 4, 8000}, {2, 4, 8000}, {1, 4, 11025}, {2, 4, 11025}, - {1, 4, 22050}, {2, 4, 22050}, {1, 4, 44100}, {2, 4, 44100}, -}; - -#define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0])) -#define NUM_ADPCM_FORMATS (sizeof(ADPCM_Formats) / sizeof(ADPCM_Formats[0])) - -/*********************************************************************** - * ADPCM_GetFormatIndex - */ -static DWORD ADPCM_GetFormatIndex(LPWAVEFORMATEX wfx) -{ - int i, hi; - Format* fmts; - - switch (wfx->wFormatTag) - { - case WAVE_FORMAT_PCM: - hi = NUM_PCM_FORMATS; - fmts = PCM_Formats; - break; - case WAVE_FORMAT_IMA_ADPCM: - hi = NUM_ADPCM_FORMATS; - fmts = ADPCM_Formats; - break; - default: - return 0xFFFFFFFF; - } - - for (i = 0; i < hi; i++) - { - if (wfx->nChannels == fmts[i].nChannels && - wfx->nSamplesPerSec == fmts[i].rate && - wfx->wBitsPerSample == fmts[i].nBits) - return i; - } - - return 0xFFFFFFFF; -} - -/*********************************************************************** - * R16 - * - * Read a 16 bit sample (correctly handles endianess) - */ -static inline short R16(const unsigned char* src) -{ - return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8)); -} - -/*********************************************************************** - * W16 - * - * Write a 16 bit sample (correctly handles endianess) - */ -static inline void W16(unsigned char* dst, short s) -{ - dst[0] = LOBYTE(s); - dst[1] = HIBYTE(s); -} - -/* IMA (or DVI) APDCM codec routines */ - -static const unsigned IMA_StepTable[89] = -{ - 7, 8, 9, 10, 11, 12, 13, 14, - 16, 17, 19, 21, 23, 25, 28, 31, - 34, 37, 41, 45, 50, 55, 60, 66, - 73, 80, 88, 97, 107, 118, 130, 143, - 157, 173, 190, 209, 230, 253, 279, 307, - 337, 371, 408, 449, 494, 544, 598, 658, - 724, 796, 876, 963, 1060, 1166, 1282, 1411, - 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, - 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, - 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, - 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, - 32767 -}; - -static const int IMA_IndexTable[16] = -{ - -1, -1, -1, -1, 2, 4, 6, 8, - -1, -1, -1, -1, 2, 4, 6, 8 -}; - -static inline void clamp_step_index(int* stepIndex) -{ - if (*stepIndex < 0 ) *stepIndex = 0; - if (*stepIndex > 88) *stepIndex = 88; -} - -static inline void clamp_sample(int* sample) -{ - if (*sample < -32768) *sample = -32768; - if (*sample > 32767) *sample = 32767; -} - -static inline void process_nibble(unsigned char code, int* stepIndex, int* sample) -{ - unsigned step; - int diff; - - code &= 0x0F; - - step = IMA_StepTable[*stepIndex]; - diff = step >> 3; - if (code & 1) diff += step >> 2; - if (code & 2) diff += step >> 1; - if (code & 4) diff += step; - if (code & 8) *sample -= diff; - else *sample += diff; - clamp_sample(sample); - *stepIndex += IMA_IndexTable[code]; - clamp_step_index(stepIndex); -} - -static inline unsigned char generate_nibble(int in, int* stepIndex, int* sample) -{ - int effdiff, diff = in - *sample; - unsigned step; - unsigned char code; - - if (diff < 0) - { - diff = -diff; - code = 8; - } - else - { - code = 0; - } - - step = IMA_StepTable[*stepIndex]; - effdiff = (step >> 3); - if (diff >= step) - { - code |= 4; - diff -= step; - effdiff += step; - } - step >>= 1; - if (diff >= step) - { - code |= 2; - diff -= step; - effdiff += step; - } - step >>= 1; - if (diff >= step) - { - code |= 1; - effdiff += step; - } - if (code & 8) *sample -= effdiff; - else *sample += effdiff; - clamp_sample(sample); - *stepIndex += IMA_IndexTable[code]; - clamp_step_index(stepIndex); - return code; -} - -static void cvtSSima16K(PACMDRVSTREAMINSTANCE adsi, - const unsigned char* src, LPDWORD nsrc, - unsigned char* dst, LPDWORD ndst) -{ - int i; - int sampleL, sampleR; - int stepIndexL, stepIndexR; - int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock; - int nsamp; - /* 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 - * of entire blocks in destination buffer - */ - DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, - *ndst / (nsamp_blk * 2 * 2)); - - *nsrc = nblock * adsi->pwfxSrc->nBlockAlign; - *ndst = nblock * (nsamp_blk * 2 * 2); - - nsamp_blk--; /* remove the sample in block header */ - for (; nblock > 0; nblock--) - { - const unsigned char* in_src = src; - - /* handle headers first */ - sampleL = R16(src); - stepIndexL = (unsigned)*(src + 2); - clamp_step_index(&stepIndexL); - src += 4; - W16(dst, sampleL); dst += 2; - - sampleR = R16(src); - stepIndexR = (unsigned)*(src + 2); - clamp_step_index(&stepIndexR); - src += 4; - W16(dst, sampleR); dst += 2; - - for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8) - { - for (i = 0; i < 4; i++) - { - process_nibble(*src, &stepIndexL, &sampleL); - W16(dst + (2 * i + 0) * 4 + 0, sampleL); - process_nibble(*src++ >> 4, &stepIndexL, &sampleL); - W16(dst + (2 * i + 1) * 4 + 0, sampleL); - } - for (i = 0; i < 4; i++) - { - process_nibble(*src , &stepIndexR, &sampleR); - W16(dst + (2 * i + 0) * 4 + 2, sampleR); - process_nibble(*src++ >>4, &stepIndexR, &sampleR); - W16(dst + (2 * i + 1) * 4 + 2, sampleR); - } - dst += 32; - } - /* we have now to realign the source pointer on block */ - src = in_src + adsi->pwfxSrc->nBlockAlign; - } -} - -static void cvtMMima16K(PACMDRVSTREAMINSTANCE adsi, - const unsigned char* src, LPDWORD nsrc, - unsigned char* dst, LPDWORD ndst) -{ - int sample; - int stepIndex; - int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock; - int nsamp; - /* 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 - * of entire blocks in destination buffer - */ - DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, - *ndst / (nsamp_blk * 2)); - - *nsrc = nblock * adsi->pwfxSrc->nBlockAlign; - *ndst = nblock * nsamp_blk * 2; - - nsamp_blk--; /* remove the sample in block header */ - for (; nblock > 0; nblock--) - { - const unsigned char* in_src = src; - - /* handle header first */ - sample = R16(src); - stepIndex = (unsigned)*(src + 2); - clamp_step_index(&stepIndex); - src += 4; - W16(dst, sample); dst += 2; - - for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2) - { - process_nibble(*src, &stepIndex, &sample); - W16(dst, sample); dst += 2; - process_nibble(*src++ >> 4, &stepIndex, &sample); - W16(dst, sample); dst += 2; - } - /* we have now to realign the source pointer on block */ - src = in_src + adsi->pwfxSrc->nBlockAlign; - } -} - -static void cvtSS16imaK(PACMDRVSTREAMINSTANCE adsi, - const unsigned char* src, LPDWORD nsrc, - unsigned char* dst, LPDWORD ndst) -{ - int stepIndexL, stepIndexR; - int sampleL, sampleR; - BYTE code1, code2; - int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock; - int i, nsamp; - /* 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 - * of entire blocks in destination buffer - */ - DWORD nblock = min(*nsrc / (nsamp_blk * 2 * 2), - *ndst / adsi->pwfxDst->nBlockAlign); - - *nsrc = nblock * (nsamp_blk * 2 * 2); - *ndst = nblock * adsi->pwfxDst->nBlockAlign; - - stepIndexL = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL; - stepIndexR = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR; - - nsamp_blk--; /* so that we won't count the sample in header while filling the block */ - - for (; nblock > 0; nblock--) - { - char* in_dst = dst; - - /* generate header */ - sampleL = R16(src); src += 2; - W16(dst, sampleL); dst += 2; - *dst = (unsigned char)(unsigned)stepIndexL; - dst += 2; - - sampleR = R16(src); src += 2; - W16(dst, sampleR); dst += 2; - *dst = (unsigned char)(unsigned)stepIndexR; - dst += 2; - - for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8) - { - for (i = 0; i < 4; i++) - { - code1 = generate_nibble(R16(src + (2 * i + 0) * 2 + 0), - &stepIndexL, &sampleL); - code2 = generate_nibble(R16(src + (2 * i + 1) * 2 + 0), - &stepIndexL, &sampleL); - *dst++ = (code1 << 4) | code2; - } - for (i = 0; i < 4; i++) - { - code1 = generate_nibble(R16(src + (2 * i + 0) * 2 + 1), - &stepIndexR, &sampleR); - code2 = generate_nibble(R16(src + (2 * i + 1) * 2 + 1), - &stepIndexR, &sampleR); - *dst++ = (code1 << 4) | code2; - } - src += 32; - } - dst = in_dst + adsi->pwfxDst->nBlockAlign; - } - ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndexL; - ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR = stepIndexR; -} - -static void cvtMM16imaK(PACMDRVSTREAMINSTANCE adsi, - const unsigned char* src, LPDWORD nsrc, - unsigned char* dst, LPDWORD ndst) -{ - int stepIndex; - int sample; - BYTE code1, code2; - int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock; - int nsamp; - /* 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 - * of entire blocks in destination buffer - */ - DWORD nblock = min(*nsrc / (nsamp_blk * 2), - *ndst / adsi->pwfxDst->nBlockAlign); - - *nsrc = nblock * (nsamp_blk * 2); - *ndst = nblock * adsi->pwfxDst->nBlockAlign; - - stepIndex = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL; - nsamp_blk--; /* so that we won't count the sample in header while filling the block */ - - for (; nblock > 0; nblock--) - { - char* in_dst = dst; - - /* generate header */ - /* FIXME: what about the last effective sample from previous block ??? */ - /* perhaps something like: - * sample += R16(src); - * clamp_sample(sample); - * and with : - * + saving the sample in adsi->dwDriver when all blocks are done - + + reset should set the field in adsi->dwDriver to 0 too - */ - sample = R16(src); src += 2; - W16(dst, sample); dst += 2; - *dst = (unsigned char)(unsigned)stepIndex; - dst += 2; - - for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2) - { - code1 = generate_nibble(R16(src), &stepIndex, &sample); - src += 2; - code2 = generate_nibble(R16(src), &stepIndex, &sample); - src += 2; - *dst++ = (code1 << 4) | code2; - } - dst = in_dst + adsi->pwfxDst->nBlockAlign; - } - ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndex; -} - -/*********************************************************************** - * ADPCM_DriverDetails - * - */ -static LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add) -{ - add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC; - add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED; - add->wMid = 0xFF; - add->wPid = 0x00; - add->vdwACM = 0x01000000; - add->vdwDriver = 0x01000000; - add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; - add->cFormatTags = 2; /* PCM, IMA ADPCM */ - add->cFilterTags = 0; - add->hicon = NULL; - MultiByteToWideChar( CP_ACP, 0, "WINE-ADPCM", -1, - add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, "Wine IMA ADPCM converter", -1, - add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1, - add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) ); - MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1, - add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) ); - add->szFeatures[0] = 0; - - return MMSYSERR_NOERROR; -} - -/*********************************************************************** - * ADPCM_FormatTagDetails - * - */ -static LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery) -{ - static WCHAR szPcm[]={'P','C','M',0}; - static WCHAR szImaAdPcm[]={'I','M','A',' ','A','d','P','C','M',0}; - - switch (dwQuery) - { - case ACM_FORMATTAGDETAILSF_INDEX: - if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE; - break; - case ACM_FORMATTAGDETAILSF_LARGESTSIZE: - if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN) - { - aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_IMA_ADPCM is bigger than PCM */ - break; - } - /* fall thru */ - case ACM_FORMATTAGDETAILSF_FORMATTAG: - switch (aftd->dwFormatTag) - { - case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break; - case WAVE_FORMAT_IMA_ADPCM: aftd->dwFormatTagIndex = 1; break; - default: return ACMERR_NOTPOSSIBLE; - } - break; - default: - WARN("Unsupported query %08lx\n", dwQuery); - return MMSYSERR_NOTSUPPORTED; - } - - aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; - switch (aftd->dwFormatTagIndex) - { - case 0: - aftd->dwFormatTag = WAVE_FORMAT_PCM; - aftd->cbFormatSize = sizeof(PCMWAVEFORMAT); - aftd->cStandardFormats = NUM_PCM_FORMATS; - lstrcpyW(aftd->szFormatTag, szPcm); - break; - case 1: - aftd->dwFormatTag = WAVE_FORMAT_IMA_ADPCM; - aftd->cbFormatSize = sizeof(IMAADPCMWAVEFORMAT); - aftd->cStandardFormats = NUM_ADPCM_FORMATS; - lstrcpyW(aftd->szFormatTag, szImaAdPcm); - break; - } - return MMSYSERR_NOERROR; -} - -/*********************************************************************** - * ADPCM_FormatDetails - * - */ -static LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery) -{ - switch (dwQuery) - { - case ACM_FORMATDETAILSF_FORMAT: - if (ADPCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; - break; - case ACM_FORMATDETAILSF_INDEX: - afd->pwfx->wFormatTag = afd->dwFormatTag; - switch (afd->dwFormatTag) - { - case WAVE_FORMAT_PCM: - if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE; - afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels; - afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate; - afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits; - /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible - * afd->pwfx->cbSize = 0; - */ - afd->pwfx->nBlockAlign = - (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8; - afd->pwfx->nAvgBytesPerSec = - afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign; - break; - case WAVE_FORMAT_IMA_ADPCM: - if (afd->dwFormatIndex >= NUM_ADPCM_FORMATS) return ACMERR_NOTPOSSIBLE; - afd->pwfx->nChannels = ADPCM_Formats[afd->dwFormatIndex].nChannels; - afd->pwfx->nSamplesPerSec = ADPCM_Formats[afd->dwFormatIndex].rate; - afd->pwfx->wBitsPerSample = ADPCM_Formats[afd->dwFormatIndex].nBits; - afd->pwfx->nBlockAlign = 1024; - /* we got 4 bits per sample */ - afd->pwfx->nAvgBytesPerSec = - (afd->pwfx->nSamplesPerSec * 4) / 8; - if (afd->cbwfx >= sizeof(WAVEFORMATEX)) - afd->pwfx->cbSize = sizeof(WORD); - if (afd->cbwfx >= sizeof(IMAADPCMWAVEFORMAT)) - ((IMAADPCMWAVEFORMAT*)afd->pwfx)->wSamplesPerBlock = (1024 - 4 * afd->pwfx->nChannels) * (2 / afd->pwfx->nChannels) + 1; - break; - default: - WARN("Unsupported tag %08lx\n", afd->dwFormatTag); - return MMSYSERR_INVALPARAM; - } - break; - default: - WARN("Unsupported query %08lx\n", dwQuery); - return MMSYSERR_NOTSUPPORTED; - } - afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; - afd->szFormat[0] = 0; /* let MSACM format this for us... */ - - return MMSYSERR_NOERROR; -} - -/*********************************************************************** - * ADPCM_FormatSuggest - * - */ -static LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs) -{ - /* some tests ... */ - if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) || - adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) || - ADPCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; - /* FIXME: should do those tests against the real size (according to format tag */ - - /* If no suggestion for destination, then copy source value */ - if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS)) - adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels; - if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC)) - adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec; - - if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE)) - { - if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) - adfs->pwfxDst->wBitsPerSample = 4; - else - adfs->pwfxDst->wBitsPerSample = 16; - } - if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG)) - { - if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) - adfs->pwfxDst->wFormatTag = WAVE_FORMAT_IMA_ADPCM; - else - adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; - } - - /* check if result is ok */ - if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE; - - /* recompute other values */ - switch (adfs->pwfxDst->wFormatTag) - { - case WAVE_FORMAT_PCM: - adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8; - adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign; - break; - case WAVE_FORMAT_IMA_ADPCM: - adfs->pwfxDst->nBlockAlign = 1024; - /* FIXME: not handling header overhead */ - adfs->pwfxDst->nAvgBytesPerSec = ((adfs->pwfxDst->nSamplesPerSec * 4) / 8) * adfs->pwfxSrc->nChannels; - ((IMAADPCMWAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock = (1024 - 4 * adfs->pwfxSrc->nChannels) * (2 / adfs->pwfxSrc->nChannels) + 1; - TRACE("setting spb=%u\n", ((IMAADPCMWAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock); - break; - default: - FIXME("\n"); - break; - } - - return MMSYSERR_NOERROR; -} - -/*********************************************************************** - * ADPCM_Reset - * - */ -static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData* aad) -{ - aad->stepIndexL = aad->stepIndexR = 0; -} - -/*********************************************************************** - * ADPCM_StreamOpen - * - */ -static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi) -{ - AcmAdpcmData* aad; - unsigned nspb; - - assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC)); - - if (ADPCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF || - ADPCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF) - return ACMERR_NOTPOSSIBLE; - - aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmAdpcmData)); - if (aad == 0) return MMSYSERR_NOMEM; - - adsi->dwDriver = (DWORD)aad; - - if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) - { - goto theEnd; - } - else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) - { - /* resampling or mono <=> stereo not available - * ADPCM algo only define 16 bit per sample output - */ - if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec || - adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels || - adsi->pwfxDst->wBitsPerSample != 16) - goto theEnd; - - nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock; - TRACE("spb=%u\n", nspb); - - /* we check that in a block, after the header, samples are present on - * 4-sample packet pattern - * we also check that the block alignement is bigger than the expected size - */ - if (((nspb - 1) & 3) != 0) goto theEnd; - if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign) - goto theEnd; - - /* adpcm decoding... */ - if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2) - aad->convert = cvtSSima16K; - if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1) - aad->convert = cvtMMima16K; - } - else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM) - { - if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec || - adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels || - adsi->pwfxSrc->wBitsPerSample != 16) - goto theEnd; - - nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock; - TRACE("spb=%u\n", nspb); - - /* we check that in a block, after the header, samples are present on - * 4-sample packet pattern - * we also check that the block alignement is bigger than the expected size - */ - if (((nspb - 1) & 3) != 0) goto theEnd; - if ((((nspb - 1) / 2) + 4) * adsi->pwfxDst->nChannels < adsi->pwfxDst->nBlockAlign) - goto theEnd; - - /* adpcm coding... */ - if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 2) - aad->convert = cvtSS16imaK; - if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 1) - aad->convert = cvtMM16imaK; - } - else goto theEnd; - ADPCM_Reset(adsi, aad); - - return MMSYSERR_NOERROR; - - theEnd: - HeapFree(GetProcessHeap(), 0, aad); - adsi->dwDriver = 0L; - return MMSYSERR_NOTSUPPORTED; -} - -/*********************************************************************** - * ADPCM_StreamClose - * - */ -static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi) -{ - HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver); - return MMSYSERR_NOERROR; -} - -/*********************************************************************** - * ADPCM_round - * - */ -static inline DWORD ADPCM_round(DWORD a, DWORD b, DWORD c) -{ - assert(a && b && c); - /* to be sure, always return an entire number of c... */ - return ((double)a * (double)b + (double)c - 1) / (double)c; -} - -/*********************************************************************** - * ADPCM_StreamSize - * - */ -static LRESULT ADPCM_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss) -{ - switch (adss->fdwSize) - { - case ACM_STREAMSIZEF_DESTINATION: - /* cbDstLength => cbSrcLength */ - if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM) - { - /* don't take block overhead into account, doesn't matter too much */ - adss->cbSrcLength = adss->cbDstLength * 4; - } - else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) - { - FIXME("misses the block header overhead\n"); - adss->cbSrcLength = 256 + adss->cbDstLength / 4; - } - else - { - return MMSYSERR_NOTSUPPORTED; - } - break; - case ACM_STREAMSIZEF_SOURCE: - /* cbSrcLength => cbDstLength */ - if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_IMA_ADPCM) - { - FIXME("misses the block header overhead\n"); - adss->cbDstLength = 256 + adss->cbSrcLength / 4; - } - else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM && - adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM) - { - /* don't take block overhead into account, doesn't matter too much */ - adss->cbDstLength = adss->cbSrcLength * 4; - } - else - { - return MMSYSERR_NOTSUPPORTED; - } - break; - default: - WARN("Unsupported query %08lx\n", adss->fdwSize); - return MMSYSERR_NOTSUPPORTED; - } - return MMSYSERR_NOERROR; -} - -/*********************************************************************** - * ADPCM_StreamConvert - * - */ -static LRESULT ADPCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh) -{ - AcmAdpcmData* aad = (AcmAdpcmData*)adsi->dwDriver; - DWORD nsrc = adsh->cbSrcLength; - DWORD ndst = adsh->cbDstLength; - - if (adsh->fdwConvert & - ~(ACM_STREAMCONVERTF_BLOCKALIGN| - ACM_STREAMCONVERTF_END| - ACM_STREAMCONVERTF_START)) - { - FIXME("Unsupported fdwConvert (%08lx), ignoring it\n", adsh->fdwConvert); - } - /* ACM_STREAMCONVERTF_BLOCKALIGN - * currently all conversions are block aligned, so do nothing for this flag - * ACM_STREAMCONVERTF_END - * no pending data, so do nothing for this flag - */ - if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START)) - { - ADPCM_Reset(adsi, aad); - } - - aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst); - adsh->cbSrcLengthUsed = nsrc; - adsh->cbDstLengthUsed = ndst; - - return MMSYSERR_NOERROR; -} - -/************************************************************************** - * ADPCM_DriverProc [exported] - */ -LRESULT CALLBACK ADPCM_DriverProc(DWORD dwDevID, HDRVR hDriv, UINT wMsg, - LPARAM dwParam1, LPARAM dwParam2) -{ - TRACE("(%08lx %08lx %04x %08lx %08lx);\n", - dwDevID, (DWORD)hDriv, wMsg, dwParam1, dwParam2); - - switch (wMsg) - { - case DRV_LOAD: return 1; - case DRV_FREE: return 1; - case DRV_OPEN: return ADPCM_drvOpen((LPSTR)dwParam1); - case DRV_CLOSE: return ADPCM_drvClose(dwDevID); - case DRV_ENABLE: return 1; - case DRV_DISABLE: return 1; - case DRV_QUERYCONFIGURE: return 1; - case DRV_CONFIGURE: MessageBoxA(0, "MSACM IMA ADPCM filter !", "Wine Driver", MB_OK); return 1; - case DRV_INSTALL: return DRVCNF_RESTART; - case DRV_REMOVE: return DRVCNF_RESTART; - - case ACMDM_DRIVER_NOTIFY: - /* no caching from other ACM drivers is done so far */ - return MMSYSERR_NOERROR; - - case ACMDM_DRIVER_DETAILS: - return ADPCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1); - - case ACMDM_FORMATTAG_DETAILS: - return ADPCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2); - - case ACMDM_FORMAT_DETAILS: - return ADPCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2); - - case ACMDM_FORMAT_SUGGEST: - return ADPCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1); - - case ACMDM_STREAM_OPEN: - return ADPCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1); - - case ACMDM_STREAM_CLOSE: - return ADPCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1); - - case ACMDM_STREAM_SIZE: - return ADPCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2); - - case ACMDM_STREAM_CONVERT: - return ADPCM_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2); - - case ACMDM_HARDWARE_WAVE_CAPS_INPUT: - case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT: - /* this converter is not a hardware driver */ - case ACMDM_FILTERTAG_DETAILS: - case ACMDM_FILTER_DETAILS: - /* this converter is not a filter */ - case ACMDM_STREAM_RESET: - /* only needed for asynchronous driver... we aren't, so just say it */ - return MMSYSERR_NOTSUPPORTED; - case ACMDM_STREAM_PREPARE: - case ACMDM_STREAM_UNPREPARE: - /* nothing special to do here... so don't do anything */ - return MMSYSERR_NOERROR; - - default: - return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2); - } - return 0; -}