2 * imaadp32.drv - IMA4 codec driver
4 * Copyright 2001 Hidenori Takeshima
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 * FIXME - no encoding.
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(imaadp32);
39 /***********************************************************************/
41 #define ACMDM_DRIVER_NOTIFY (ACMDM_BASE + 1)
42 #define ACMDM_DRIVER_DETAILS (ACMDM_BASE + 10)
44 #define ACMDM_HARDWARE_WAVE_CAPS_INPUT (ACMDM_BASE + 20)
45 #define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT (ACMDM_BASE + 21)
47 #define ACMDM_FORMATTAG_DETAILS (ACMDM_BASE + 25)
48 #define ACMDM_FORMAT_DETAILS (ACMDM_BASE + 26)
49 #define ACMDM_FORMAT_SUGGEST (ACMDM_BASE + 27)
51 #define ACMDM_FILTERTAG_DETAILS (ACMDM_BASE + 50)
52 #define ACMDM_FILTER_DETAILS (ACMDM_BASE + 51)
54 #define ACMDM_STREAM_OPEN (ACMDM_BASE + 76)
55 #define ACMDM_STREAM_CLOSE (ACMDM_BASE + 77)
56 #define ACMDM_STREAM_SIZE (ACMDM_BASE + 78)
57 #define ACMDM_STREAM_CONVERT (ACMDM_BASE + 79)
58 #define ACMDM_STREAM_RESET (ACMDM_BASE + 80)
59 #define ACMDM_STREAM_PREPARE (ACMDM_BASE + 81)
60 #define ACMDM_STREAM_UNPREPARE (ACMDM_BASE + 82)
61 #define ACMDM_STREAM_UPDATE (ACMDM_BASE + 83)
63 typedef struct _ACMDRVSTREAMINSTANCE
66 PWAVEFORMATEX pwfxSrc;
67 PWAVEFORMATEX pwfxDst;
75 } ACMDRVSTREAMINSTANCE, *PACMDRVSTREAMINSTANCE;
77 typedef struct _ACMDRVSTREAMHEADER *PACMDRVSTREAMHEADER;
78 typedef struct _ACMDRVSTREAMHEADER {
84 DWORD cbSrcLengthUsed;
88 DWORD cbDstLengthUsed;
92 PACMDRVSTREAMHEADER *padshNext;
96 /* Internal fields for ACM */
100 DWORD cbPreparedSrcLength;
101 LPBYTE pbPreparedDst;
102 DWORD cbPreparedDstLength;
103 } ACMDRVSTREAMHEADER;
105 typedef struct _ACMDRVSTREAMSIZE
111 } ACMDRVSTREAMSIZE, *PACMDRVSTREAMSIZE;
113 typedef struct _ACMDRVFORMATSUGGEST
117 PWAVEFORMATEX pwfxSrc;
119 PWAVEFORMATEX pwfxDst;
121 } ACMDRVFORMATSUGGEST, *PACMDRVFORMATSUGGEST;
126 /***********************************************************************/
131 CodecType_EncIMAADPCM,
132 CodecType_DecIMAADPCM,
135 typedef struct CodecImpl
140 /***********************************************************************/
143 static const int ima_step[88+1] =
145 /* from Y.Ajima's WAVFMT.TXT */
146 7, 8, 9, 10, 11, 12, 13, 14,
147 16, 17, 19, 21, 23, 25, 28, 31,
148 34, 37, 41, 45, 50, 55, 60, 66,
149 73, 80, 88, 97, 107, 118, 130, 143,
150 157, 173, 190, 209, 230, 253, 279, 307,
151 337, 371, 408, 449, 494, 544, 598, 658,
152 724, 796, 876, 963, 1060, 1166, 1282, 1411,
153 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
154 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
155 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
156 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
159 static const int ima_indexupdate[8*2] =
161 /* from Y.Ajima's WAVFMT.TXT */
162 -1,-1,-1,-1, 2, 4, 6, 8,
163 -1,-1,-1,-1, 2, 4, 6, 8,
166 static int stepindex_to_diff( int stepindex, int input )
168 /* from Y.Ajima's WAVFMT.TXT */
171 absdiff = (ima_step[stepindex]*((input&0x7)*2+1)) >> 3;
172 return (input&0x8) ? (-absdiff) : absdiff;
175 static int update_stepindex( int oldindex, int input )
179 index = oldindex + ima_indexupdate[input];
180 return (index < 0) ? 0 : (index > 88) ? 88 : index;
183 static void decode_ima_block( int channels, int samplesperblock, SHORT* pDst, BYTE* pSrc )
190 for ( n = 0; n < channels; n++ )
192 samp[n] = *(SHORT*)pSrc; pSrc += sizeof(SHORT);
193 stepindex[n] = *pSrc; pSrc += sizeof(SHORT);
198 while ( samplesperblock >= 8 )
200 for ( n = 0; n < channels; n++ )
202 for ( k = 0; k < 4; k++ )
204 inputs[k*2+0] = (*pSrc) & 0xf;
205 inputs[k*2+1] = (*pSrc) >> 4;
208 for ( k = 0; k < 8; k++ )
210 diff = stepindex_to_diff( stepindex[n], inputs[k] );
211 stepindex[n] = update_stepindex( stepindex[n], inputs[k] );
213 if ( diff < -32768 ) diff = -32768;
214 if ( diff > 32767 ) diff = 32767;
216 pDst[k*channels+n] = samp[n];
221 samplesperblock -= 8;
225 static LONG IMAADPCM32_Decode( int channels, int blockalign, int samplesperblock, BYTE* pbDst, DWORD cbDstLength, DWORD* pcbDstLengthUsed, BYTE* pbSrc, DWORD cbSrcLength, DWORD* pcbSrcLengthUsed )
227 DWORD cbDstLengthUsed = 0;
228 DWORD cbSrcLengthUsed = 0;
231 dstblocksize = samplesperblock*channels*sizeof(SHORT);
232 while ( cbDstLength >= dstblocksize && cbSrcLength >= blockalign )
234 decode_ima_block( channels, samplesperblock, (SHORT*)pbDst, pbSrc );
235 pbDst += dstblocksize;
236 cbDstLength -= dstblocksize;
237 cbDstLengthUsed += dstblocksize;
239 cbSrcLength -= blockalign;
240 cbSrcLengthUsed += blockalign;
243 *pcbSrcLengthUsed = cbSrcLengthUsed;
244 *pcbDstLengthUsed = cbDstLengthUsed;
246 return MMSYSERR_NOERROR;
250 /***********************************************************************/
252 static LONG Codec_DrvQueryConfigure( CodecImpl* This )
254 return MMSYSERR_NOTSUPPORTED;
257 static LONG Codec_DrvConfigure( CodecImpl* This, HWND hwnd, DRVCONFIGINFO* pinfo )
259 return MMSYSERR_NOTSUPPORTED;
262 static LONG Codec_DriverDetails( ACMDRIVERDETAILSW* pDrvDetails )
264 if ( pDrvDetails->cbStruct < sizeof(ACMDRIVERDETAILSW) )
265 return MMSYSERR_INVALPARAM;
267 ZeroMemory( pDrvDetails, sizeof(ACMDRIVERDETAILSW) );
268 pDrvDetails->cbStruct = sizeof(ACMDRIVERDETAILSW);
270 pDrvDetails->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
271 pDrvDetails->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
272 pDrvDetails->wMid = 0xff; /* FIXME? */
273 pDrvDetails->wPid = 0x00; /* FIXME? */
274 pDrvDetails->vdwACM = 0x01000000; /* FIXME? */
275 pDrvDetails->vdwDriver = 0x01000000; /* FIXME? */
276 pDrvDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
277 pDrvDetails->cFormatTags = 2;
278 pDrvDetails->cFilterTags = 0;
279 pDrvDetails->hicon = (HICON)NULL;
280 MultiByteToWideChar( CP_ACP, 0, "WineIMA", -1,
281 pDrvDetails->szShortName,
282 sizeof(pDrvDetails->szShortName)/sizeof(WCHAR) );
283 MultiByteToWideChar( CP_ACP, 0, "Wine IMA codec", -1,
284 pDrvDetails->szLongName,
285 sizeof(pDrvDetails->szLongName)/sizeof(WCHAR) );
286 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
287 pDrvDetails->szCopyright,
288 sizeof(pDrvDetails->szCopyright)/sizeof(WCHAR) );
289 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
290 pDrvDetails->szLicensing,
291 sizeof(pDrvDetails->szLicensing)/sizeof(WCHAR) );
292 pDrvDetails->szFeatures[0] = 0;
294 return MMSYSERR_NOERROR;
297 static LONG Codec_QueryAbout( void )
299 return MMSYSERR_NOTSUPPORTED;
302 static LONG Codec_About( HWND hwnd )
304 return MMSYSERR_NOTSUPPORTED;
307 /***********************************************************************/
309 static LONG Codec_FormatTagDetails( CodecImpl* This, ACMFORMATTAGDETAILSW* pFmtTagDetails, DWORD dwFlags )
311 FIXME( "enumerate tags\n" );
315 case ACM_FORMATTAGDETAILSF_INDEX:
316 switch ( pFmtTagDetails->dwFormatTagIndex )
319 pFmtTagDetails->dwFormatTag = 0x11; /* IMA ADPCM */
322 pFmtTagDetails->dwFormatTag = 1; /* PCM */
325 return ACMERR_NOTPOSSIBLE;
328 case ACM_FORMATTAGDETAILSF_FORMATTAG:
329 switch ( pFmtTagDetails->dwFormatTag )
331 case 0x11: /* IMA ADPCM */
332 pFmtTagDetails->dwFormatTagIndex = 0;
335 pFmtTagDetails->dwFormatTagIndex = 1;
338 return ACMERR_NOTPOSSIBLE;
341 case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
342 if ( pFmtTagDetails->dwFormatTag != 0 &&
343 pFmtTagDetails->dwFormatTag != 1 &&
344 pFmtTagDetails->dwFormatTag != 0x11 )
345 return ACMERR_NOTPOSSIBLE;
346 pFmtTagDetails->dwFormatTagIndex = 0;
349 return MMSYSERR_NOTSUPPORTED;
352 pFmtTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
353 pFmtTagDetails->cbFormatSize = sizeof(WAVEFORMATEX);
354 pFmtTagDetails->cStandardFormats = 2; /* FIXME */
355 pFmtTagDetails->szFormatTag[0] = 0; /* FIXME */
357 return MMSYSERR_NOERROR;
360 static LONG Codec_FormatDetails( CodecImpl* This, ACMFORMATDETAILSW* pFmtDetails, DWORD dwFlags )
362 FIXME( "enumerate standard formats\n" );
364 if ( pFmtDetails->cbStruct < sizeof(ACMFORMATDETAILSW) )
365 return MMSYSERR_INVALPARAM;
366 pFmtDetails->cbStruct = sizeof(ACMFORMATDETAILSW);
370 case ACM_FORMATDETAILSF_INDEX:
371 switch ( pFmtDetails->dwFormatIndex )
374 pFmtDetails->dwFormatTag = 0x11; /* IMA ADPCM */
377 pFmtDetails->dwFormatTag = 1; /* PCM */
380 return MMSYSERR_INVALPARAM;
383 case ACM_FORMATDETAILSF_FORMAT:
384 switch ( pFmtDetails->dwFormatTag )
386 case 0x11: /* IMA ADPCM */
387 pFmtDetails->dwFormatIndex = 0;
390 pFmtDetails->dwFormatIndex = 1;
393 return ACMERR_NOTPOSSIBLE;
397 return MMSYSERR_NOTSUPPORTED;
400 pFmtDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
401 pFmtDetails->pwfx->wFormatTag = pFmtDetails->dwFormatTag;
402 pFmtDetails->pwfx->nChannels = 1;
403 pFmtDetails->pwfx->nSamplesPerSec = 11025;
404 pFmtDetails->pwfx->wBitsPerSample = 4;
405 if ( pFmtDetails->dwFormatTag == 1 )
407 pFmtDetails->cbwfx = sizeof(PCMWAVEFORMAT);
411 pFmtDetails->pwfx->cbSize = sizeof(WORD);
412 pFmtDetails->cbwfx = sizeof(WAVEFORMATEX) + sizeof(WORD);
414 pFmtDetails->szFormat[0] = 0; /* FIXME */
416 return MMSYSERR_NOERROR;
420 static LONG Codec_FormatSuggest( CodecImpl* This, ACMDRVFORMATSUGGEST* pFmtSuggest )
424 FIXME( "get suggested format\n" );
426 if ( pFmtSuggest->cbStruct != sizeof(ACMDRVFORMATSUGGEST) )
427 return MMSYSERR_INVALPARAM;
429 if ( pFmtSuggest->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
430 pFmtSuggest->cbwfxDst < sizeof(PCMWAVEFORMAT) )
431 return MMSYSERR_INVALPARAM;
433 fdwSuggest = pFmtSuggest->fdwSuggest;
435 if ( fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS )
437 if ( pFmtSuggest->pwfxSrc->nChannels != pFmtSuggest->pwfxDst->nChannels )
438 return ACMERR_NOTPOSSIBLE;
439 fdwSuggest &= ~ACM_FORMATSUGGESTF_NCHANNELS;
442 if ( fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC )
444 if ( pFmtSuggest->pwfxSrc->nSamplesPerSec != pFmtSuggest->pwfxDst->nSamplesPerSec )
445 return ACMERR_NOTPOSSIBLE;
446 fdwSuggest &= ~ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
449 if ( pFmtSuggest->pwfxSrc->wFormatTag == 1 )
452 if ( pFmtSuggest->cbwfxDst < (sizeof(WAVEFORMATEX)+sizeof(WORD)) )
453 return MMSYSERR_INVALPARAM;
454 if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 16 )
455 return ACMERR_NOTPOSSIBLE;
457 if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
459 if ( pFmtSuggest->pwfxDst->wFormatTag != 0x11 )
460 return ACMERR_NOTPOSSIBLE;
461 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
464 if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
466 if ( pFmtSuggest->pwfxDst->wBitsPerSample != 4 )
467 return ACMERR_NOTPOSSIBLE;
468 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
471 if ( fdwSuggest != 0 )
472 return MMSYSERR_INVALFLAG;
474 if ( !(fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) )
475 pFmtSuggest->pwfxDst->wFormatTag = 0x11;
476 pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
477 pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
478 pFmtSuggest->pwfxDst->nAvgBytesPerSec = 0; /* FIXME */
479 pFmtSuggest->pwfxDst->nBlockAlign = 0; /* FIXME */
480 pFmtSuggest->pwfxDst->wBitsPerSample = 4;
481 pFmtSuggest->pwfxDst->cbSize = 2;
483 FIXME( "no compressor" );
484 return ACMERR_NOTPOSSIBLE;
489 if ( pFmtSuggest->cbwfxSrc < (sizeof(WAVEFORMATEX)+sizeof(WORD)) )
490 return MMSYSERR_INVALPARAM;
491 if ( pFmtSuggest->pwfxSrc->wFormatTag != 0x11 )
492 return ACMERR_NOTPOSSIBLE;
493 if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 4 )
494 return ACMERR_NOTPOSSIBLE;
496 if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
498 if ( pFmtSuggest->pwfxDst->wFormatTag != 1 )
499 return ACMERR_NOTPOSSIBLE;
500 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
503 if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
505 if ( pFmtSuggest->pwfxDst->wBitsPerSample != 16 )
506 return ACMERR_NOTPOSSIBLE;
507 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
510 if ( fdwSuggest != 0 )
511 return MMSYSERR_INVALFLAG;
513 pFmtSuggest->pwfxDst->wFormatTag = 1;
514 pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
515 pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
516 pFmtSuggest->pwfxDst->nAvgBytesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec * pFmtSuggest->pwfxSrc->nChannels * 2;
517 pFmtSuggest->pwfxDst->nBlockAlign = pFmtSuggest->pwfxSrc->nChannels * 2;
518 pFmtSuggest->pwfxDst->wBitsPerSample = 16;
521 return MMSYSERR_NOERROR;
524 static LONG Codec_FilterTagDetails( CodecImpl* This, ACMFILTERTAGDETAILSW* pFilterTagDetails, DWORD dwFlags )
526 /* This is a codec driver. */
527 return MMSYSERR_NOTSUPPORTED;
530 static LONG Codec_FilterDetails( CodecImpl* This, ACMFILTERDETAILSW* pFilterDetails, DWORD dwFlags )
532 /* This is a codec driver. */
533 return MMSYSERR_NOTSUPPORTED;
536 static LONG Codec_StreamOpen( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
538 enum CodecType codectype = CodecType_Invalid;
540 if ( pStreamInst->cbStruct != sizeof(ACMDRVSTREAMINSTANCE) )
542 TRACE("invalid size of struct\n");
543 return MMSYSERR_INVALPARAM;
546 if ( pStreamInst->fdwOpen & (~(ACM_STREAMOPENF_ASYNC|ACM_STREAMOPENF_NONREALTIME|ACM_STREAMOPENF_QUERY|CALLBACK_EVENT|CALLBACK_FUNCTION|CALLBACK_WINDOW)) )
548 TRACE("unknown flags\n");
549 return MMSYSERR_INVALFLAG;
552 /* No support for async operations. */
553 if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_ASYNC )
554 return MMSYSERR_INVALFLAG;
556 /* This is a codec driver. */
557 if ( pStreamInst->pwfxSrc->nChannels != pStreamInst->pwfxDst->nChannels || pStreamInst->pwfxSrc->nSamplesPerSec != pStreamInst->pwfxDst->nSamplesPerSec )
558 return ACMERR_NOTPOSSIBLE;
559 if ( pStreamInst->pwfltr != NULL )
560 return ACMERR_NOTPOSSIBLE;
562 if ( pStreamInst->pwfxSrc->wFormatTag == 1 )
564 if ( pStreamInst->pwfxSrc->wBitsPerSample != 16 )
565 return ACMERR_NOTPOSSIBLE;
566 if ( pStreamInst->pwfxDst->wBitsPerSample != 4 )
567 return ACMERR_NOTPOSSIBLE;
569 /* Queried as a compressor */
570 FIXME( "Compressor is not implemented now\n" );
571 return ACMERR_NOTPOSSIBLE;
574 if ( pStreamInst->pwfxDst->wFormatTag == 1 )
576 if ( pStreamInst->pwfxDst->wBitsPerSample != 16 )
577 return ACMERR_NOTPOSSIBLE;
578 if ( pStreamInst->pwfxSrc->wBitsPerSample != 4 )
579 return ACMERR_NOTPOSSIBLE;
581 switch ( pStreamInst->pwfxSrc->wFormatTag )
583 case 0x11: /* IMA ADPCM */
584 TRACE( "IMG ADPCM deompressor\n" );
585 codectype = CodecType_DecIMAADPCM;
588 return ACMERR_NOTPOSSIBLE;
593 return ACMERR_NOTPOSSIBLE;
596 if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_QUERY )
597 return MMSYSERR_NOERROR;
599 pStreamInst->dwDriver = (DWORD)codectype;
601 return MMSYSERR_NOERROR;
604 static LONG Codec_StreamClose( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
606 return MMSYSERR_NOERROR;
609 static LONG Codec_StreamSize( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMSIZE* pStreamSize )
611 enum CodecType codectype;
614 if ( pStreamSize->cbStruct != sizeof(ACMDRVSTREAMSIZE) )
615 return MMSYSERR_INVALPARAM;
617 codectype = (enum CodecType)pStreamInst->dwDriver;
619 res = MMSYSERR_NOERROR;
623 case CodecType_EncIMAADPCM:
624 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
625 pStreamSize->cbDstLength = 64 + (pStreamSize->cbSrcLength >> 2);
627 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
628 pStreamSize->cbSrcLength = pStreamSize->cbDstLength << 2;
630 res = MMSYSERR_INVALFLAG;
632 case CodecType_DecIMAADPCM:
633 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
634 pStreamSize->cbDstLength = pStreamSize->cbSrcLength << 2;
636 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
637 pStreamSize->cbSrcLength = 64 + (pStreamSize->cbDstLength >> 2);
639 res = MMSYSERR_INVALFLAG;
642 ERR( "CodecType_Invalid\n" );
643 res = MMSYSERR_NOTSUPPORTED;
650 static LONG Codec_StreamConvert( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
652 enum CodecType codectype;
655 codectype = (enum CodecType)pStreamInst->dwDriver;
657 res = MMSYSERR_NOTSUPPORTED;
660 case CodecType_EncIMAADPCM:
661 FIXME( "CodecType_EncIMAADPCM\n" );
663 case CodecType_DecIMAADPCM:
664 TRACE( "CodecType_DecIMAADPCM\n" );
665 res = IMAADPCM32_Decode( pStreamInst->pwfxSrc->nChannels, pStreamInst->pwfxSrc->nBlockAlign, *(WORD*)(((BYTE*)pStreamInst->pwfxSrc) + sizeof(WAVEFORMATEX)), pStreamHdr->pbDst, pStreamHdr->cbDstLength, &pStreamHdr->cbDstLengthUsed, pStreamHdr->pbSrc, pStreamHdr->cbSrcLength, &pStreamHdr->cbSrcLengthUsed );
668 ERR( "CodecType_Invalid\n" );
675 static LONG Codec_StreamReset( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, DWORD dwFlags )
677 return MMSYSERR_NOTSUPPORTED;
680 static LONG Codec_StreamPrepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
682 return MMSYSERR_NOTSUPPORTED;
685 static LONG Codec_StreamUnprepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
687 return MMSYSERR_NOTSUPPORTED;
692 /***********************************************************************/
694 static CodecImpl* Codec_AllocDriver( void )
698 This = HeapAlloc( GetProcessHeap(), 0, sizeof(CodecImpl) );
701 ZeroMemory( This, sizeof(CodecImpl) );
703 /* initialize members. */
708 static void Codec_Close( CodecImpl* This )
711 HeapFree( GetProcessHeap(), 0, This );
716 /***********************************************************************/
718 LONG WINAPI IMAADP32_DriverProc(
719 DWORD dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2 )
721 TRACE( "DriverProc(%08lx,%08x,%08x,%08lx,%08lx)\n",
722 dwDriverId, hdrvr, msg, lParam1, lParam2 );
734 return (LONG)Codec_AllocDriver();
736 TRACE("DRV_CLOSE\n");
737 Codec_Close( (CodecImpl*)dwDriverId );
740 TRACE("DRV_ENABLE\n");
743 TRACE("DRV_DISABLE\n");
745 case DRV_QUERYCONFIGURE:
746 TRACE("DRV_QUERYCONFIGURE\n");
747 return Codec_DrvQueryConfigure( (CodecImpl*)dwDriverId );
749 TRACE("DRV_CONFIGURE\n");
750 return Codec_DrvConfigure( (CodecImpl*)dwDriverId,
751 (HWND)lParam1, (DRVCONFIGINFO*)lParam2 );
753 TRACE("DRV_INSTALL\n");
756 TRACE("DRV_REMOVE\n");
759 TRACE("DRV_POWER\n");
762 case ACMDM_DRIVER_NOTIFY:
763 return MMSYSERR_NOERROR;
764 case ACMDM_DRIVER_DETAILS:
765 return Codec_DriverDetails((ACMDRIVERDETAILSW*)lParam1);
766 case ACMDM_DRIVER_ABOUT:
767 TRACE("ACMDM_DRIVER_ABOUT\n");
768 return (lParam1 == -1) ? Codec_QueryAbout() : Codec_About( (HWND)lParam1 );
770 case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
771 return MMSYSERR_NOTSUPPORTED;
772 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
773 return MMSYSERR_NOTSUPPORTED;
775 case ACMDM_FORMATTAG_DETAILS:
776 return Codec_FormatTagDetails( (CodecImpl*)dwDriverId, (ACMFORMATTAGDETAILSW*)lParam1, (DWORD)lParam2 );
777 case ACMDM_FORMAT_DETAILS:
778 return Codec_FormatDetails( (CodecImpl*)dwDriverId, (ACMFORMATDETAILSW*)lParam1, (DWORD)lParam2 );
779 case ACMDM_FORMAT_SUGGEST:
780 return Codec_FormatSuggest( (CodecImpl*)dwDriverId, (ACMDRVFORMATSUGGEST*)lParam1 );
782 case ACMDM_FILTERTAG_DETAILS:
783 return Codec_FilterTagDetails( (CodecImpl*)dwDriverId, (ACMFILTERTAGDETAILSW*)lParam1, (DWORD)lParam2 );
784 case ACMDM_FILTER_DETAILS:
785 return Codec_FilterDetails( (CodecImpl*)dwDriverId, (ACMFILTERDETAILSW*)lParam1, (DWORD)lParam2 );
787 case ACMDM_STREAM_OPEN:
788 return Codec_StreamOpen( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
789 case ACMDM_STREAM_CLOSE:
790 return Codec_StreamClose( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
791 case ACMDM_STREAM_SIZE:
792 return Codec_StreamSize( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMSIZE*)lParam2 );
793 case ACMDM_STREAM_CONVERT:
794 return Codec_StreamConvert( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
795 case ACMDM_STREAM_RESET:
796 return Codec_StreamReset( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (DWORD)lParam2 );
797 case ACMDM_STREAM_PREPARE:
798 return Codec_StreamPrepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
799 case ACMDM_STREAM_UNPREPARE:
800 return Codec_StreamUnprepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
804 return DefDriverProc( dwDriverId, hdrvr, msg, lParam1, lParam2 );
807 /***********************************************************************/
809 BOOL WINAPI IMAADP32_DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved )
811 TRACE( "(%08x,%08lx,%p)\n",hInst,dwReason,lpvReserved );