2 * msg711.drv - G711 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.
33 #include "../msacmdrv.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(msg711);
40 /***********************************************************************/
51 typedef struct CodecImpl
56 /***********************************************************************/
58 static const WORD dec_mulaw[256] =
60 0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84,
61 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,
62 0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84,
63 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,
64 0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804,
65 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,
66 0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444,
67 0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844,
68 0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64,
69 0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64,
70 0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74,
71 0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74,
72 0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC,
73 0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C,
74 0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0,
75 0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000,
76 0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C,
77 0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C,
78 0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C,
79 0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C,
80 0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC,
81 0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC,
82 0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC,
83 0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC,
84 0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C,
85 0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C,
86 0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C,
87 0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C,
88 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
89 0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084,
90 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
91 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000,
94 static const WORD dec_alaw[256] =
96 0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80,
97 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
98 0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0,
99 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
100 0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600,
101 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
102 0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00,
103 0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,
104 0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8,
105 0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,
106 0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8,
107 0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,
108 0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60,
109 0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,
110 0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0,
111 0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,
112 0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280,
113 0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,
114 0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940,
115 0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,
116 0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00,
117 0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,
118 0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500,
119 0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,
120 0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128,
121 0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,
122 0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028,
123 0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,
124 0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0,
125 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,
126 0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250,
127 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350,
130 static LONG MSG711_Decode( const WORD* pdec, BYTE* pbDst, DWORD cbDstLength, DWORD* pcbDstLengthUsed, BYTE* pbSrc, DWORD cbSrcLength, DWORD* pcbSrcLengthUsed )
135 cSample = cbSrcLength;
136 if ( cSample > (cbDstLength>>1) )
137 cSample = (cbDstLength>>1);
139 *pcbSrcLengthUsed = cSample;
140 *pcbDstLengthUsed = cSample << 1;
142 while ( cSample-- > 0 )
145 *pbDst++ = LOBYTE(w);
146 *pbDst++ = HIBYTE(w);
149 return MMSYSERR_NOERROR;
153 /***********************************************************************/
155 static LONG Codec_DrvQueryConfigure( CodecImpl* This )
157 return MMSYSERR_NOTSUPPORTED;
160 static LONG Codec_DrvConfigure( CodecImpl* This, HWND hwnd, DRVCONFIGINFO* pinfo )
162 return MMSYSERR_NOTSUPPORTED;
165 static LONG Codec_DriverDetails( ACMDRIVERDETAILSW* pDrvDetails )
167 if ( pDrvDetails->cbStruct < sizeof(ACMDRIVERDETAILSW) )
168 return MMSYSERR_INVALPARAM;
170 ZeroMemory( pDrvDetails, sizeof(ACMDRIVERDETAILSW) );
171 pDrvDetails->cbStruct = sizeof(ACMDRIVERDETAILSW);
173 pDrvDetails->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
174 pDrvDetails->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
175 pDrvDetails->wMid = 0xff; /* FIXME? */
176 pDrvDetails->wPid = 0x00; /* FIXME? */
177 pDrvDetails->vdwACM = 0x01000000; /* FIXME? */
178 pDrvDetails->vdwDriver = 0x01000000; /* FIXME? */
179 pDrvDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
180 pDrvDetails->cFormatTags = 3;
181 pDrvDetails->cFilterTags = 0;
182 pDrvDetails->hicon = (HICON)NULL;
183 MultiByteToWideChar( CP_ACP, 0, "WineG711", -1,
184 pDrvDetails->szShortName,
185 sizeof(pDrvDetails->szShortName)/sizeof(WCHAR) );
186 MultiByteToWideChar( CP_ACP, 0, "Wine G711 codec", -1,
187 pDrvDetails->szLongName,
188 sizeof(pDrvDetails->szLongName)/sizeof(WCHAR) );
189 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
190 pDrvDetails->szCopyright,
191 sizeof(pDrvDetails->szCopyright)/sizeof(WCHAR) );
192 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
193 pDrvDetails->szLicensing,
194 sizeof(pDrvDetails->szLicensing)/sizeof(WCHAR) );
195 pDrvDetails->szFeatures[0] = 0;
197 return MMSYSERR_NOERROR;
200 static LONG Codec_QueryAbout( void )
202 return MMSYSERR_NOTSUPPORTED;
205 static LONG Codec_About( HWND hwnd )
207 return MMSYSERR_NOTSUPPORTED;
210 /***********************************************************************/
212 static LONG Codec_FormatTagDetails( CodecImpl* This, ACMFORMATTAGDETAILSW* pFmtTagDetails, DWORD dwFlags )
214 FIXME( "enumerate tags\n" );
218 case ACM_FORMATTAGDETAILSF_INDEX:
219 switch ( pFmtTagDetails->dwFormatTagIndex )
222 pFmtTagDetails->dwFormatTag = 7; /* Mu-Law */
225 pFmtTagDetails->dwFormatTag = 6; /* A-Law */
228 pFmtTagDetails->dwFormatTag = 1; /* PCM */
231 return ACMERR_NOTPOSSIBLE;
234 case ACM_FORMATTAGDETAILSF_FORMATTAG:
235 switch ( pFmtTagDetails->dwFormatTag )
238 pFmtTagDetails->dwFormatTagIndex = 0;
241 pFmtTagDetails->dwFormatTagIndex = 1;
244 pFmtTagDetails->dwFormatTagIndex = 2;
247 return ACMERR_NOTPOSSIBLE;
250 case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
251 if ( pFmtTagDetails->dwFormatTag != 0 &&
252 pFmtTagDetails->dwFormatTag != 1 &&
253 pFmtTagDetails->dwFormatTag != 6 &&
254 pFmtTagDetails->dwFormatTag != 7 )
255 return ACMERR_NOTPOSSIBLE;
256 pFmtTagDetails->dwFormatTagIndex = 0;
259 return MMSYSERR_NOTSUPPORTED;
262 pFmtTagDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
263 pFmtTagDetails->cbFormatSize = sizeof(WAVEFORMATEX);
264 pFmtTagDetails->cStandardFormats = 3; /* FIXME */
265 pFmtTagDetails->szFormatTag[0] = 0; /* FIXME */
267 return MMSYSERR_NOERROR;
270 static LONG Codec_FormatDetails( CodecImpl* This, ACMFORMATDETAILSW* pFmtDetails, DWORD dwFlags )
272 FIXME( "enumerate standard formats\n" );
274 if ( pFmtDetails->cbStruct < sizeof(ACMFORMATDETAILSW) )
275 return MMSYSERR_INVALPARAM;
276 pFmtDetails->cbStruct = sizeof(ACMFORMATDETAILSW);
280 case ACM_FORMATDETAILSF_INDEX:
281 switch ( pFmtDetails->dwFormatIndex )
284 pFmtDetails->dwFormatTag = 7; /* Mu-Law */
287 pFmtDetails->dwFormatTag = 6; /* A-Law */
290 pFmtDetails->dwFormatTag = 1; /* PCM */
293 return MMSYSERR_INVALPARAM;
296 case ACM_FORMATDETAILSF_FORMAT:
297 switch ( pFmtDetails->dwFormatTag )
300 pFmtDetails->dwFormatIndex = 0;
303 pFmtDetails->dwFormatIndex = 1;
306 pFmtDetails->dwFormatIndex = 2;
309 return ACMERR_NOTPOSSIBLE;
313 return MMSYSERR_NOTSUPPORTED;
316 pFmtDetails->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
317 pFmtDetails->pwfx->wFormatTag = pFmtDetails->dwFormatTag;
318 pFmtDetails->pwfx->nChannels = 1;
319 pFmtDetails->pwfx->nSamplesPerSec = 8000;
320 pFmtDetails->pwfx->wBitsPerSample = 8;
321 if ( pFmtDetails->dwFormatTag == 1 )
323 pFmtDetails->cbwfx = sizeof(PCMWAVEFORMAT);
327 pFmtDetails->pwfx->cbSize = 0;
328 pFmtDetails->cbwfx = sizeof(WAVEFORMATEX);
330 pFmtDetails->szFormat[0] = 0; /* FIXME */
332 return MMSYSERR_NOERROR;
336 static LONG Codec_FormatSuggest( CodecImpl* This, ACMDRVFORMATSUGGEST* pFmtSuggest )
340 FIXME( "get suggested format\n" );
342 if ( pFmtSuggest->cbStruct != sizeof(ACMDRVFORMATSUGGEST) )
343 return MMSYSERR_INVALPARAM;
345 if ( pFmtSuggest->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
346 pFmtSuggest->cbwfxDst < sizeof(PCMWAVEFORMAT) )
347 return MMSYSERR_INVALPARAM;
349 fdwSuggest = pFmtSuggest->fdwSuggest;
351 if ( fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS )
353 if ( pFmtSuggest->pwfxSrc->nChannels != pFmtSuggest->pwfxDst->nChannels )
354 return ACMERR_NOTPOSSIBLE;
355 fdwSuggest &= ~ACM_FORMATSUGGESTF_NCHANNELS;
358 if ( fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC )
360 if ( pFmtSuggest->pwfxSrc->nSamplesPerSec != pFmtSuggest->pwfxDst->nSamplesPerSec )
361 return ACMERR_NOTPOSSIBLE;
362 fdwSuggest &= ~ACM_FORMATSUGGESTF_NSAMPLESPERSEC;
365 if ( pFmtSuggest->pwfxSrc->wFormatTag == 1 )
368 if ( pFmtSuggest->cbwfxDst < sizeof(WAVEFORMATEX) )
369 return MMSYSERR_INVALPARAM;
370 if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 16 )
371 return ACMERR_NOTPOSSIBLE;
373 if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
375 if ( pFmtSuggest->pwfxDst->wFormatTag != 6 &&
376 pFmtSuggest->pwfxDst->wFormatTag != 7 )
377 return ACMERR_NOTPOSSIBLE;
378 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
381 if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
383 if ( pFmtSuggest->pwfxDst->wBitsPerSample != 8 )
384 return ACMERR_NOTPOSSIBLE;
385 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
388 if ( fdwSuggest != 0 )
389 return MMSYSERR_INVALFLAG;
391 if ( !(fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG) )
392 pFmtSuggest->pwfxDst->wFormatTag = 7;
393 pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
394 pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
395 pFmtSuggest->pwfxDst->nAvgBytesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec * pFmtSuggest->pwfxSrc->nChannels;
396 pFmtSuggest->pwfxDst->nBlockAlign = pFmtSuggest->pwfxSrc->nChannels;
397 pFmtSuggest->pwfxDst->wBitsPerSample = 8;
398 pFmtSuggest->pwfxDst->cbSize = 0;
400 FIXME( "no compressor" );
401 return ACMERR_NOTPOSSIBLE;
406 if ( pFmtSuggest->cbwfxSrc < sizeof(WAVEFORMATEX) )
407 return MMSYSERR_INVALPARAM;
408 if ( pFmtSuggest->pwfxSrc->wFormatTag != 6 &&
409 pFmtSuggest->pwfxSrc->wFormatTag != 7 )
410 return ACMERR_NOTPOSSIBLE;
411 if ( pFmtSuggest->pwfxSrc->wBitsPerSample != 8 )
412 return ACMERR_NOTPOSSIBLE;
414 if ( fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG )
416 if ( pFmtSuggest->pwfxDst->wFormatTag != 1 )
417 return ACMERR_NOTPOSSIBLE;
418 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
421 if ( fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE )
423 if ( pFmtSuggest->pwfxDst->wBitsPerSample != 16 )
424 return ACMERR_NOTPOSSIBLE;
425 fdwSuggest &= ~ACM_FORMATSUGGESTF_WFORMATTAG;
428 if ( fdwSuggest != 0 )
429 return MMSYSERR_INVALFLAG;
431 pFmtSuggest->pwfxDst->wFormatTag = 1;
432 pFmtSuggest->pwfxDst->nChannels = pFmtSuggest->pwfxSrc->nChannels;
433 pFmtSuggest->pwfxDst->nSamplesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec;
434 pFmtSuggest->pwfxDst->nAvgBytesPerSec = pFmtSuggest->pwfxSrc->nSamplesPerSec * pFmtSuggest->pwfxSrc->nChannels * 2;
435 pFmtSuggest->pwfxDst->nBlockAlign = pFmtSuggest->pwfxSrc->nChannels * 2;
436 pFmtSuggest->pwfxDst->wBitsPerSample = 16;
439 return MMSYSERR_NOERROR;
442 static LONG Codec_FilterTagDetails( CodecImpl* This, ACMFILTERTAGDETAILSW* pFilterTagDetails, DWORD dwFlags )
444 /* This is a codec driver. */
445 return MMSYSERR_NOTSUPPORTED;
448 static LONG Codec_FilterDetails( CodecImpl* This, ACMFILTERDETAILSW* pFilterDetails, DWORD dwFlags )
450 /* This is a codec driver. */
451 return MMSYSERR_NOTSUPPORTED;
454 static LONG Codec_StreamOpen( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
456 enum CodecType codectype = CodecType_Invalid;
458 if ( pStreamInst->cbStruct != sizeof(ACMDRVSTREAMINSTANCE) )
460 TRACE("invalid size of struct\n");
461 return MMSYSERR_INVALPARAM;
464 if ( pStreamInst->fdwOpen & (~(ACM_STREAMOPENF_ASYNC|ACM_STREAMOPENF_NONREALTIME|ACM_STREAMOPENF_QUERY|CALLBACK_EVENT|CALLBACK_FUNCTION|CALLBACK_WINDOW)) )
466 TRACE("unknown flags\n");
467 return MMSYSERR_INVALFLAG;
470 /* No support for async operations. */
471 if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_ASYNC )
472 return MMSYSERR_INVALFLAG;
474 /* This is a codec driver. */
475 if ( pStreamInst->pwfxSrc->nChannels != pStreamInst->pwfxDst->nChannels || pStreamInst->pwfxSrc->nSamplesPerSec != pStreamInst->pwfxDst->nSamplesPerSec )
476 return ACMERR_NOTPOSSIBLE;
477 if ( pStreamInst->pwfltr != NULL )
478 return ACMERR_NOTPOSSIBLE;
480 if ( pStreamInst->pwfxSrc->wFormatTag == 1 )
482 if ( pStreamInst->pwfxSrc->wBitsPerSample != 16 )
483 return ACMERR_NOTPOSSIBLE;
484 if ( pStreamInst->pwfxDst->wBitsPerSample != 8 )
485 return ACMERR_NOTPOSSIBLE;
487 /* Queried as a compressor */
488 FIXME( "Compressor is not implemented now\n" );
489 return ACMERR_NOTPOSSIBLE;
492 if ( pStreamInst->pwfxDst->wFormatTag == 1 )
494 if ( pStreamInst->pwfxDst->wBitsPerSample != 16 )
495 return ACMERR_NOTPOSSIBLE;
496 if ( pStreamInst->pwfxSrc->wBitsPerSample != 8 )
497 return ACMERR_NOTPOSSIBLE;
499 switch ( pStreamInst->pwfxSrc->wFormatTag )
502 TRACE( "A-Law deompressor\n" );
503 codectype = CodecType_DecALaw;
506 TRACE( "Mu-Law deompressor\n" );
507 codectype = CodecType_DecMuLaw;
510 return ACMERR_NOTPOSSIBLE;
515 return ACMERR_NOTPOSSIBLE;
518 if ( pStreamInst->fdwOpen & ACM_STREAMOPENF_QUERY )
519 return MMSYSERR_NOERROR;
521 pStreamInst->dwDriver = (DWORD)codectype;
523 return MMSYSERR_NOERROR;
526 static LONG Codec_StreamClose( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst )
528 return MMSYSERR_NOERROR;
531 static LONG Codec_StreamSize( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMSIZE* pStreamSize )
533 enum CodecType codectype;
536 if ( pStreamSize->cbStruct != sizeof(ACMDRVSTREAMSIZE) )
537 return MMSYSERR_INVALPARAM;
539 codectype = (enum CodecType)pStreamInst->dwDriver;
541 res = MMSYSERR_NOERROR;
544 case CodecType_EncMuLaw:
545 case CodecType_EncALaw:
546 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
547 pStreamSize->cbDstLength = pStreamSize->cbSrcLength >> 1;
549 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
550 pStreamSize->cbSrcLength = pStreamSize->cbDstLength << 1;
552 res = MMSYSERR_INVALFLAG;
554 case CodecType_DecMuLaw:
555 case CodecType_DecALaw:
556 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_SOURCE )
557 pStreamSize->cbDstLength = pStreamSize->cbSrcLength << 1;
559 if ( pStreamSize->fdwSize == ACM_STREAMSIZEF_DESTINATION )
560 pStreamSize->cbSrcLength = pStreamSize->cbDstLength >> 1;
562 res = MMSYSERR_INVALFLAG;
565 ERR( "CodecType_Invalid\n" );
566 res = MMSYSERR_NOTSUPPORTED;
573 static LONG Codec_StreamConvert( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
575 enum CodecType codectype;
578 codectype = (enum CodecType)pStreamInst->dwDriver;
580 res = MMSYSERR_NOTSUPPORTED;
583 case CodecType_EncMuLaw:
584 FIXME( "CodecType_EncMuLaw\n" );
586 case CodecType_EncALaw:
587 FIXME( "CodecType_EncALaw\n" );
589 case CodecType_DecMuLaw:
590 TRACE( "CodecType_DecMuLaw\n" );
591 res = MSG711_Decode( dec_mulaw, pStreamHdr->pbDst, pStreamHdr->cbDstLength, &pStreamHdr->cbDstLengthUsed, pStreamHdr->pbSrc, pStreamHdr->cbSrcLength, &pStreamHdr->cbSrcLengthUsed );
593 case CodecType_DecALaw:
594 TRACE( "CodecType_DecALaw\n" );
595 res = MSG711_Decode( dec_alaw, pStreamHdr->pbDst, pStreamHdr->cbDstLength, &pStreamHdr->cbDstLengthUsed, pStreamHdr->pbSrc, pStreamHdr->cbSrcLength, &pStreamHdr->cbSrcLengthUsed );
598 ERR( "CodecType_Invalid\n" );
605 static LONG Codec_StreamReset( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, DWORD dwFlags )
607 return MMSYSERR_NOTSUPPORTED;
610 static LONG Codec_StreamPrepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
612 return MMSYSERR_NOTSUPPORTED;
615 static LONG Codec_StreamUnprepare( CodecImpl* This, ACMDRVSTREAMINSTANCE* pStreamInst, ACMDRVSTREAMHEADER* pStreamHdr )
617 return MMSYSERR_NOTSUPPORTED;
622 /***********************************************************************/
624 static CodecImpl* Codec_AllocDriver( void )
628 This = HeapAlloc( GetProcessHeap(), 0, sizeof(CodecImpl) );
631 ZeroMemory( This, sizeof(CodecImpl) );
633 /* initialize members. */
638 static void Codec_Close( CodecImpl* This )
641 HeapFree( GetProcessHeap(), 0, This );
646 /***********************************************************************/
648 LONG WINAPI MSG711_DriverProc(
649 DWORD dwDriverId, HDRVR hdrvr, UINT msg, LONG lParam1, LONG lParam2 )
651 TRACE( "DriverProc(%08lx,%08x,%08x,%08lx,%08lx)\n",
652 dwDriverId, hdrvr, msg, lParam1, lParam2 );
664 return (LONG)Codec_AllocDriver();
666 TRACE("DRV_CLOSE\n");
667 Codec_Close( (CodecImpl*)dwDriverId );
670 TRACE("DRV_ENABLE\n");
673 TRACE("DRV_DISABLE\n");
675 case DRV_QUERYCONFIGURE:
676 TRACE("DRV_QUERYCONFIGURE\n");
677 return Codec_DrvQueryConfigure( (CodecImpl*)dwDriverId );
679 TRACE("DRV_CONFIGURE\n");
680 return Codec_DrvConfigure( (CodecImpl*)dwDriverId,
681 (HWND)lParam1, (DRVCONFIGINFO*)lParam2 );
683 TRACE("DRV_INSTALL\n");
686 TRACE("DRV_REMOVE\n");
689 TRACE("DRV_POWER\n");
692 case ACMDM_DRIVER_NOTIFY:
693 return MMSYSERR_NOERROR;
694 case ACMDM_DRIVER_DETAILS:
695 return Codec_DriverDetails((ACMDRIVERDETAILSW*)lParam1);
696 case ACMDM_DRIVER_ABOUT:
697 TRACE("ACMDM_DRIVER_ABOUT\n");
698 return (lParam1 == -1) ? Codec_QueryAbout() : Codec_About( (HWND)lParam1 );
700 case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
701 return MMSYSERR_NOTSUPPORTED;
702 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
703 return MMSYSERR_NOTSUPPORTED;
705 case ACMDM_FORMATTAG_DETAILS:
706 return Codec_FormatTagDetails( (CodecImpl*)dwDriverId, (ACMFORMATTAGDETAILSW*)lParam1, (DWORD)lParam2 );
707 case ACMDM_FORMAT_DETAILS:
708 return Codec_FormatDetails( (CodecImpl*)dwDriverId, (ACMFORMATDETAILSW*)lParam1, (DWORD)lParam2 );
709 case ACMDM_FORMAT_SUGGEST:
710 return Codec_FormatSuggest( (CodecImpl*)dwDriverId, (ACMDRVFORMATSUGGEST*)lParam1 );
712 case ACMDM_FILTERTAG_DETAILS:
713 return Codec_FilterTagDetails( (CodecImpl*)dwDriverId, (ACMFILTERTAGDETAILSW*)lParam1, (DWORD)lParam2 );
714 case ACMDM_FILTER_DETAILS:
715 return Codec_FilterDetails( (CodecImpl*)dwDriverId, (ACMFILTERDETAILSW*)lParam1, (DWORD)lParam2 );
717 case ACMDM_STREAM_OPEN:
718 return Codec_StreamOpen( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
719 case ACMDM_STREAM_CLOSE:
720 return Codec_StreamClose( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1 );
721 case ACMDM_STREAM_SIZE:
722 return Codec_StreamSize( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMSIZE*)lParam2 );
723 case ACMDM_STREAM_CONVERT:
724 return Codec_StreamConvert( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
725 case ACMDM_STREAM_RESET:
726 return Codec_StreamReset( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (DWORD)lParam2 );
727 case ACMDM_STREAM_PREPARE:
728 return Codec_StreamPrepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
729 case ACMDM_STREAM_UNPREPARE:
730 return Codec_StreamUnprepare( (CodecImpl*)dwDriverId, (ACMDRVSTREAMINSTANCE*)lParam1, (ACMDRVSTREAMHEADER*)lParam2 );
734 return DefDriverProc( dwDriverId, hdrvr, msg, lParam1, lParam2 );
737 /***********************************************************************/
739 BOOL WINAPI MSG711_DllMain( HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved )
741 TRACE( "(%08x,%08lx,%p)\n",hInst,dwReason,lpvReserved );