2 * G711 handling (includes A-Law & MU-Law)
4 * Copyright (C) 2002 Eric Pouech
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(g711
);
38 /***********************************************************************
41 static LRESULT
G711_drvOpen(LPCSTR str
)
46 /***********************************************************************
49 static LRESULT
G711_drvClose(DWORD_PTR dwDevID
)
54 typedef struct tagAcmG711Data
56 void (*convert
)(PACMDRVSTREAMINSTANCE adsi
,
57 const unsigned char*, LPDWORD
, unsigned char*, LPDWORD
);
60 /* table to list all supported formats... those are the basic ones. this
61 * also helps given a unique index to each of the supported formats
70 static const Format PCM_Formats
[] =
72 /*{1, 8, 8000}, {2, 8, 8000}, */{1, 16, 8000}, {2, 16, 8000},
73 /*{1, 8, 11025}, {2, 8, 11025}, */{1, 16, 11025}, {2, 16, 11025},
74 /*{1, 8, 22050}, {2, 8, 22050}, */{1, 16, 22050}, {2, 16, 22050},
75 /*{1, 8, 44100}, {2, 8, 44100}, */{1, 16, 44100}, {2, 16, 44100},
78 static const Format ALaw_Formats
[] =
80 {1, 8, 8000}, {2, 8, 8000}, {1, 8, 11025}, {2, 8, 11025},
81 {1, 8, 22050}, {2, 8, 22050}, {1, 8, 44100}, {2, 8, 44100},
84 static const Format ULaw_Formats
[] =
86 {1, 8, 8000}, {2, 8, 8000}, {1, 8, 11025}, {2, 8, 11025},
87 {1, 8, 22050}, {2, 8, 22050}, {1, 8, 44100}, {2, 8, 44100},
90 /***********************************************************************
93 static DWORD
G711_GetFormatIndex(const WAVEFORMATEX
*wfx
)
98 switch (wfx
->wFormatTag
)
100 case WAVE_FORMAT_PCM
:
101 hi
= ARRAY_SIZE(PCM_Formats
);
104 case WAVE_FORMAT_ALAW
:
105 hi
= ARRAY_SIZE(ALaw_Formats
);
108 case WAVE_FORMAT_MULAW
:
109 hi
= ARRAY_SIZE(ULaw_Formats
);
116 for (i
= 0; i
< hi
; i
++)
118 if (wfx
->nChannels
== fmts
[i
].nChannels
&&
119 wfx
->nSamplesPerSec
== fmts
[i
].rate
&&
120 wfx
->wBitsPerSample
== fmts
[i
].nBits
)
127 /***********************************************************************
130 * Read a 16 bit sample (correctly handles endianness)
132 static inline short R16(const unsigned char* src
)
134 return (short)((unsigned short)src
[0] | ((unsigned short)src
[1] << 8));
137 /***********************************************************************
140 * Write a 16 bit sample (correctly handles endianness)
142 static inline void W16(unsigned char* dst
, short s
)
148 /* You can uncomment this if you don't want the statically generated conversion
149 * table, but rather recompute the Xlaw => PCM conversion for each sample
150 #define NO_FASTDECODE
151 * Since the conversion tables are rather small (2k), I don't think it's really
152 * interesting not to use them, but keeping the actual conversion code around
153 * is helpful to regenerate the tables when needed.
156 /* -------------------------------------------------------------------------------*/
159 * This source code is a product of Sun Microsystems, Inc. and is provided
160 * for unrestricted use. Users may copy or modify this source code without
163 * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
164 * THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
165 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
167 * Sun source code is provided with no support and without any obligation on
168 * the part of Sun Microsystems, Inc. to assist in its use, correction,
169 * modification or enhancement.
171 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
172 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
173 * OR ANY PART THEREOF.
175 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
176 * or profits or other special, indirect and consequential damages, even if
177 * Sun has been advised of the possibility of such damages.
179 * Sun Microsystems, Inc.
181 * Mountain View, California 94043
187 * u-law, A-law and linear PCM conversions.
192 * Functions linear2alaw, linear2ulaw have been updated to correctly
193 * convert unquantized 16 bit values.
194 * Tables for direct u- to A-law and A- to u-law conversions have been
196 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
201 #define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
202 #define QUANT_MASK (0xf) /* Quantization field mask. */
203 #define NSEGS (8) /* Number of A-law segments. */
204 #define SEG_SHIFT (4) /* Left shift for segment number. */
205 #define SEG_MASK (0x70) /* Segment field mask. */
207 static const short seg_aend
[8] = {0x1F, 0x3F, 0x7F, 0x0FF, 0x1FF, 0x3FF, 0x7FF, 0x0FFF};
208 static const short seg_uend
[8] = {0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
210 /* copy from CCITT G.711 specifications */
211 static const unsigned char _u2a
[128] = { /* u- to A-law conversions */
212 1, 1, 2, 2, 3, 3, 4, 4,
213 5, 5, 6, 6, 7, 7, 8, 8,
214 9, 10, 11, 12, 13, 14, 15, 16,
215 17, 18, 19, 20, 21, 22, 23, 24,
216 25, 27, 29, 31, 33, 34, 35, 36,
217 37, 38, 39, 40, 41, 42, 43, 44,
218 46, 48, 49, 50, 51, 52, 53, 54,
219 55, 56, 57, 58, 59, 60, 61, 62,
220 64, 65, 66, 67, 68, 69, 70, 71,
221 72, 73, 74, 75, 76, 77, 78, 79,
223 81, 82, 83, 84, 85, 86, 87, 88,
225 80, 82, 83, 84, 85, 86, 87, 88,
226 89, 90, 91, 92, 93, 94, 95, 96,
227 97, 98, 99, 100, 101, 102, 103, 104,
228 105, 106, 107, 108, 109, 110, 111, 112,
229 113, 114, 115, 116, 117, 118, 119, 120,
230 121, 122, 123, 124, 125, 126, 127, 128};
232 static const unsigned char _a2u
[128] = { /* A- to u-law conversions */
233 1, 3, 5, 7, 9, 11, 13, 15,
234 16, 17, 18, 19, 20, 21, 22, 23,
235 24, 25, 26, 27, 28, 29, 30, 31,
236 32, 32, 33, 33, 34, 34, 35, 35,
237 36, 37, 38, 39, 40, 41, 42, 43,
238 44, 45, 46, 47, 48, 48, 49, 49,
239 50, 51, 52, 53, 54, 55, 56, 57,
240 58, 59, 60, 61, 62, 63, 64, 64,
241 65, 66, 67, 68, 69, 70, 71, 72,
243 73, 74, 75, 76, 77, 78, 79, 79,
245 73, 74, 75, 76, 77, 78, 79, 80,
247 80, 81, 82, 83, 84, 85, 86, 87,
248 88, 89, 90, 91, 92, 93, 94, 95,
249 96, 97, 98, 99, 100, 101, 102, 103,
250 104, 105, 106, 107, 108, 109, 110, 111,
251 112, 113, 114, 115, 116, 117, 118, 119,
252 120, 121, 122, 123, 124, 125, 126, 127};
256 int val
, /* changed from "short" *drago* */
258 int size
) /* changed from "short" *drago* */
260 int i
; /* changed from "short" *drago* */
262 for (i
= 0; i
< size
; i
++) {
270 * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
272 * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
274 * Linear Input Code Compressed Code
275 * ------------------------ ---------------
276 * 0000000wxyza 000wxyz
277 * 0000001wxyza 001wxyz
278 * 000001wxyzab 010wxyz
279 * 00001wxyzabc 011wxyz
280 * 0001wxyzabcd 100wxyz
281 * 001wxyzabcde 101wxyz
282 * 01wxyzabcdef 110wxyz
283 * 1wxyzabcdefg 111wxyz
285 * For further information see John C. Bellamy's Digital Telephony, 1982,
286 * John Wiley & Sons, pps 98-111 and 472-476.
288 static inline unsigned char
289 linear2alaw(int pcm_val
) /* 2's complement (16-bit range) */
290 /* changed from "short" *drago* */
292 int mask
; /* changed from "short" *drago* */
293 int seg
; /* changed from "short" *drago* */
296 pcm_val
= pcm_val
>> 3;
299 mask
= 0xD5; /* sign (7th) bit = 1 */
301 mask
= 0x55; /* sign bit = 0 */
302 pcm_val
= -pcm_val
- 1;
305 /* Convert the scaled magnitude to segment number. */
306 seg
= search(pcm_val
, seg_aend
, 8);
308 /* Combine the sign, segment, and quantization bits. */
310 if (seg
>= 8) /* out of range, return maximum value. */
311 return (unsigned char) (0x7F ^ mask
);
313 aval
= (unsigned char) seg
<< SEG_SHIFT
;
315 aval
|= (pcm_val
>> 1) & QUANT_MASK
;
317 aval
|= (pcm_val
>> seg
) & QUANT_MASK
;
318 return (aval
^ mask
);
324 * alaw2linear() - Convert an A-law value to 16-bit linear PCM
328 alaw2linear(unsigned char a_val
)
330 int t
; /* changed from "short" *drago* */
331 int seg
; /* changed from "short" *drago* */
335 t
= (a_val
& QUANT_MASK
) << 4;
336 seg
= ((unsigned)a_val
& SEG_MASK
) >> SEG_SHIFT
;
348 return ((a_val
& SIGN_BIT
) ? t
: -t
);
352 * this array has been statically generated from the above routine
354 static const unsigned short _a2l
[] = {
355 0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80,
356 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
357 0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0,
358 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
359 0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600,
360 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
361 0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00,
362 0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,
363 0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8,
364 0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,
365 0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8,
366 0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,
367 0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60,
368 0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,
369 0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0,
370 0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,
371 0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280,
372 0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,
373 0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940,
374 0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,
375 0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00,
376 0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,
377 0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500,
378 0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,
379 0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128,
380 0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,
381 0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028,
382 0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,
383 0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0,
384 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,
385 0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250,
386 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350,
389 alaw2linear(unsigned char a_val
)
391 return (short)_a2l
[a_val
];
395 #define BIAS (0x84) /* Bias for linear code. */
399 * linear2ulaw() - Convert a linear PCM value to u-law
401 * In order to simplify the encoding process, the original linear magnitude
402 * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
403 * (33 - 8191). The result can be seen in the following encoding table:
405 * Biased Linear Input Code Compressed Code
406 * ------------------------ ---------------
407 * 00000001wxyza 000wxyz
408 * 0000001wxyzab 001wxyz
409 * 000001wxyzabc 010wxyz
410 * 00001wxyzabcd 011wxyz
411 * 0001wxyzabcde 100wxyz
412 * 001wxyzabcdef 101wxyz
413 * 01wxyzabcdefg 110wxyz
414 * 1wxyzabcdefgh 111wxyz
416 * Each biased linear code has a leading 1 which identifies the segment
417 * number. The value of the segment number is equal to 7 minus the number
418 * of leading 0's. The quantization interval is directly available as the
419 * four bits wxyz. * The trailing bits (a - h) are ignored.
421 * Ordinarily the complement of the resulting code word is used for
422 * transmission, and so the code word is complemented before it is returned.
424 * For further information see John C. Bellamy's Digital Telephony, 1982,
425 * John Wiley & Sons, pps 98-111 and 472-476.
427 static inline unsigned char
428 linear2ulaw(short pcm_val
) /* 2's complement (16-bit range) */
434 /* Get the sign and the magnitude of the value. */
435 pcm_val
= pcm_val
>> 2;
442 if ( pcm_val
> CLIP
) pcm_val
= CLIP
; /* clip the magnitude */
443 pcm_val
+= (BIAS
>> 2);
445 /* Convert the scaled magnitude to segment number. */
446 seg
= search(pcm_val
, seg_uend
, 8);
449 * Combine the sign, segment, quantization bits;
450 * and complement the code word.
452 if (seg
>= 8) /* out of range, return maximum value. */
453 return (unsigned char) (0x7F ^ mask
);
455 uval
= (unsigned char) (seg
<< 4) | ((pcm_val
>> (seg
+ 1)) & 0xF);
456 return (uval
^ mask
);
462 * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
464 * First, a biased linear code is derived from the code word. An unbiased
465 * output can then be obtained by subtracting 33 from the biased code.
467 * Note that this function expects to be passed the complement of the
468 * original code word. This is in keeping with ISDN conventions.
471 ulaw2linear(unsigned char u_val
)
475 /* Complement to obtain normal u-law value. */
479 * Extract and bias the quantization bits. Then
480 * shift up by the segment number and subtract out the bias.
482 t
= ((u_val
& QUANT_MASK
) << 3) + BIAS
;
483 t
<<= ((unsigned)u_val
& SEG_MASK
) >> SEG_SHIFT
;
485 return ((u_val
& SIGN_BIT
) ? (BIAS
- t
) : (t
- BIAS
));
489 * this array has been statically generated from the above routine
491 static const unsigned short _u2l
[] = {
492 0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84,
493 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,
494 0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84,
495 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,
496 0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804,
497 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,
498 0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444,
499 0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844,
500 0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64,
501 0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64,
502 0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74,
503 0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74,
504 0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC,
505 0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C,
506 0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0,
507 0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000,
508 0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C,
509 0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C,
510 0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C,
511 0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C,
512 0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC,
513 0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC,
514 0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC,
515 0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC,
516 0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C,
517 0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C,
518 0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C,
519 0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C,
520 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
521 0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084,
522 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
523 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000,
525 static inline short ulaw2linear(unsigned char u_val
)
527 return (short)_u2l
[u_val
];
531 /* A-law to u-law conversion */
532 static inline unsigned char
533 alaw2ulaw(unsigned char aval
)
536 return (unsigned char) ((aval
& 0x80) ? (0xFF ^ _a2u
[aval
^ 0xD5]) :
537 (0x7F ^ _a2u
[aval
^ 0x55]));
540 /* u-law to A-law conversion */
541 static inline unsigned char
542 ulaw2alaw(unsigned char uval
)
545 return (uval
& 0x80) ? (0xD5 ^ (_u2a
[0xFF ^ uval
] - 1)) : (0x55 ^ (_u2a
[0x7F ^ uval
] - 1));
548 /* -------------------------------------------------------------------------------*/
550 static void cvtXXalaw16K(PACMDRVSTREAMINSTANCE adsi
,
551 const unsigned char* src
, LPDWORD srcsize
,
552 unsigned char* dst
, LPDWORD dstsize
)
554 DWORD len
= min(*srcsize
, *dstsize
/ 2);
560 for (i
= 0; i
< len
; i
++)
562 w
= alaw2linear(*src
++);
563 W16(dst
, w
); dst
+= 2;
567 static void cvtXX16alawK(PACMDRVSTREAMINSTANCE adsi
,
568 const unsigned char* src
, LPDWORD srcsize
,
569 unsigned char* dst
, LPDWORD dstsize
)
571 DWORD len
= min(*srcsize
/ 2, *dstsize
);
576 for (i
= 0; i
< len
; i
++)
578 *dst
++ = linear2alaw(R16(src
)); src
+= 2;
582 static void cvtXXulaw16K(PACMDRVSTREAMINSTANCE adsi
,
583 const unsigned char* src
, LPDWORD srcsize
,
584 unsigned char* dst
, LPDWORD dstsize
)
586 DWORD len
= min(*srcsize
, *dstsize
/ 2);
592 for (i
= 0; i
< len
; i
++)
594 w
= ulaw2linear(*src
++);
595 W16(dst
, w
); dst
+= 2;
599 static void cvtXX16ulawK(PACMDRVSTREAMINSTANCE adsi
,
600 const unsigned char* src
, LPDWORD srcsize
,
601 unsigned char* dst
, LPDWORD dstsize
)
603 DWORD len
= min(*srcsize
/ 2, *dstsize
);
608 for (i
= 0; i
< len
; i
++)
610 *dst
++ = linear2ulaw(R16(src
)); src
+= 2;
614 static void cvtXXalawulawK(PACMDRVSTREAMINSTANCE adsi
,
615 const unsigned char* src
, LPDWORD srcsize
,
616 unsigned char* dst
, LPDWORD dstsize
)
618 DWORD len
= min(*srcsize
, *dstsize
);
624 for (i
= 0; i
< len
; i
++)
625 *dst
++ = alaw2ulaw(*src
++);
629 static void cvtXXulawalawK(PACMDRVSTREAMINSTANCE adsi
,
630 const unsigned char* src
, LPDWORD srcsize
,
631 unsigned char* dst
, LPDWORD dstsize
)
633 DWORD len
= min(*srcsize
, *dstsize
);
639 for (i
= 0; i
< len
; i
++)
640 *dst
++ = ulaw2alaw(*src
++);
643 /***********************************************************************
647 static LRESULT
G711_DriverDetails(PACMDRIVERDETAILSW add
)
649 add
->fccType
= ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
;
650 add
->fccComp
= ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
;
651 add
->wMid
= MM_MICROSOFT
;
652 add
->wPid
= MM_MSFT_ACM_G711
;
653 add
->vdwACM
= 0x01000000;
654 add
->vdwDriver
= 0x01000000;
655 add
->fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
656 add
->cFormatTags
= 3; /* PCM, G711 A-LAW & MU-LAW */
657 add
->cFilterTags
= 0;
659 MultiByteToWideChar( CP_ACP
, 0, "Microsoft CCITT G.711", -1,
660 add
->szShortName
, ARRAY_SIZE( add
->szShortName
));
661 MultiByteToWideChar( CP_ACP
, 0, "Wine G711 converter", -1,
662 add
->szLongName
, ARRAY_SIZE( add
->szLongName
));
663 MultiByteToWideChar( CP_ACP
, 0, "Brought to you by the Wine team...", -1,
664 add
->szCopyright
, ARRAY_SIZE( add
->szCopyright
));
665 MultiByteToWideChar( CP_ACP
, 0, "Refer to LICENSE file", -1,
666 add
->szLicensing
, ARRAY_SIZE( add
->szLicensing
));
667 add
->szFeatures
[0] = 0;
669 return MMSYSERR_NOERROR
;
672 /***********************************************************************
673 * G711_FormatTagDetails
676 static LRESULT
G711_FormatTagDetails(PACMFORMATTAGDETAILSW aftd
, DWORD dwQuery
)
680 case ACM_FORMATTAGDETAILSF_INDEX
:
681 if (aftd
->dwFormatTagIndex
>= 3) return ACMERR_NOTPOSSIBLE
;
683 case ACM_FORMATTAGDETAILSF_LARGESTSIZE
:
684 if (aftd
->dwFormatTag
== WAVE_FORMAT_UNKNOWN
)
686 aftd
->dwFormatTagIndex
= 1;
690 case ACM_FORMATTAGDETAILSF_FORMATTAG
:
691 switch (aftd
->dwFormatTag
)
693 case WAVE_FORMAT_PCM
: aftd
->dwFormatTagIndex
= 0; break;
694 case WAVE_FORMAT_ALAW
: aftd
->dwFormatTagIndex
= 1; break;
695 case WAVE_FORMAT_MULAW
: aftd
->dwFormatTagIndex
= 2; break;
696 default: return ACMERR_NOTPOSSIBLE
;
700 WARN("Unsupported query %08lx\n", dwQuery
);
701 return MMSYSERR_NOTSUPPORTED
;
704 aftd
->fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
705 switch (aftd
->dwFormatTagIndex
)
708 aftd
->dwFormatTag
= WAVE_FORMAT_PCM
;
709 aftd
->cbFormatSize
= sizeof(PCMWAVEFORMAT
);
710 aftd
->cStandardFormats
= ARRAY_SIZE(PCM_Formats
);
711 lstrcpyW(aftd
->szFormatTag
, L
"PCM");
714 aftd
->dwFormatTag
= WAVE_FORMAT_ALAW
;
715 aftd
->cbFormatSize
= sizeof(WAVEFORMATEX
);
716 aftd
->cStandardFormats
= ARRAY_SIZE(ALaw_Formats
);
717 lstrcpyW(aftd
->szFormatTag
, L
"A-Law");
720 aftd
->dwFormatTag
= WAVE_FORMAT_MULAW
;
721 aftd
->cbFormatSize
= sizeof(WAVEFORMATEX
);
722 aftd
->cStandardFormats
= ARRAY_SIZE(ULaw_Formats
);
723 lstrcpyW(aftd
->szFormatTag
, L
"U-Law");
726 return MMSYSERR_NOERROR
;
729 /***********************************************************************
733 static LRESULT
G711_FormatDetails(PACMFORMATDETAILSW afd
, DWORD dwQuery
)
737 case ACM_FORMATDETAILSF_FORMAT
:
738 if (G711_GetFormatIndex(afd
->pwfx
) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE
;
740 case ACM_FORMATDETAILSF_INDEX
:
741 afd
->pwfx
->wFormatTag
= afd
->dwFormatTag
;
742 switch (afd
->dwFormatTag
)
744 case WAVE_FORMAT_PCM
:
745 if (afd
->dwFormatIndex
>= ARRAY_SIZE(PCM_Formats
)) return ACMERR_NOTPOSSIBLE
;
746 afd
->pwfx
->nChannels
= PCM_Formats
[afd
->dwFormatIndex
].nChannels
;
747 afd
->pwfx
->nSamplesPerSec
= PCM_Formats
[afd
->dwFormatIndex
].rate
;
748 afd
->pwfx
->wBitsPerSample
= PCM_Formats
[afd
->dwFormatIndex
].nBits
;
749 afd
->pwfx
->nBlockAlign
= afd
->pwfx
->nChannels
* 2;
750 afd
->pwfx
->nAvgBytesPerSec
= afd
->pwfx
->nSamplesPerSec
* afd
->pwfx
->nBlockAlign
;
752 case WAVE_FORMAT_ALAW
:
753 if (afd
->dwFormatIndex
>= ARRAY_SIZE(ALaw_Formats
)) return ACMERR_NOTPOSSIBLE
;
754 afd
->pwfx
->nChannels
= ALaw_Formats
[afd
->dwFormatIndex
].nChannels
;
755 afd
->pwfx
->nSamplesPerSec
= ALaw_Formats
[afd
->dwFormatIndex
].rate
;
756 afd
->pwfx
->wBitsPerSample
= ALaw_Formats
[afd
->dwFormatIndex
].nBits
;
757 afd
->pwfx
->nBlockAlign
= ALaw_Formats
[afd
->dwFormatIndex
].nChannels
;
758 afd
->pwfx
->nAvgBytesPerSec
= afd
->pwfx
->nSamplesPerSec
* afd
->pwfx
->nChannels
;
759 afd
->pwfx
->cbSize
= 0;
761 case WAVE_FORMAT_MULAW
:
762 if (afd
->dwFormatIndex
>= ARRAY_SIZE(ULaw_Formats
)) return ACMERR_NOTPOSSIBLE
;
763 afd
->pwfx
->nChannels
= ULaw_Formats
[afd
->dwFormatIndex
].nChannels
;
764 afd
->pwfx
->nSamplesPerSec
= ULaw_Formats
[afd
->dwFormatIndex
].rate
;
765 afd
->pwfx
->wBitsPerSample
= ULaw_Formats
[afd
->dwFormatIndex
].nBits
;
766 afd
->pwfx
->nBlockAlign
= ULaw_Formats
[afd
->dwFormatIndex
].nChannels
;
767 afd
->pwfx
->nAvgBytesPerSec
= afd
->pwfx
->nSamplesPerSec
* afd
->pwfx
->nChannels
;
768 afd
->pwfx
->cbSize
= 0;
771 WARN("Unsupported tag %08lx\n", afd
->dwFormatTag
);
772 return MMSYSERR_INVALPARAM
;
776 WARN("Unsupported query %08lx\n", dwQuery
);
777 return MMSYSERR_NOTSUPPORTED
;
779 afd
->fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
780 afd
->szFormat
[0] = 0; /* let MSACM format this for us... */
782 return MMSYSERR_NOERROR
;
785 /***********************************************************************
789 static LRESULT
G711_FormatSuggest(PACMDRVFORMATSUGGEST adfs
)
792 if (adfs
->cbwfxSrc
< sizeof(PCMWAVEFORMAT
) ||
793 adfs
->cbwfxDst
< sizeof(PCMWAVEFORMAT
) ||
794 G711_GetFormatIndex(adfs
->pwfxSrc
) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE
;
795 /* FIXME: should do those tests against the real size (according to format tag */
797 /* If no suggestion for destination, then copy source value */
798 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_NCHANNELS
))
799 adfs
->pwfxDst
->nChannels
= adfs
->pwfxSrc
->nChannels
;
800 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_NSAMPLESPERSEC
))
801 adfs
->pwfxDst
->nSamplesPerSec
= adfs
->pwfxSrc
->nSamplesPerSec
;
803 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_WBITSPERSAMPLE
))
805 if (adfs
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
)
806 adfs
->pwfxDst
->wBitsPerSample
= 8;
808 adfs
->pwfxDst
->wBitsPerSample
= 16;
810 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
))
812 switch (adfs
->pwfxSrc
->wFormatTag
)
814 case WAVE_FORMAT_PCM
: adfs
->pwfxDst
->wFormatTag
= WAVE_FORMAT_ALAW
; break;
815 case WAVE_FORMAT_ALAW
: adfs
->pwfxDst
->wFormatTag
= WAVE_FORMAT_PCM
; break;
816 case WAVE_FORMAT_MULAW
: adfs
->pwfxDst
->wFormatTag
= WAVE_FORMAT_PCM
; break;
819 /* check if result is ok */
820 if (G711_GetFormatIndex(adfs
->pwfxDst
) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE
;
822 /* recompute other values */
823 switch (adfs
->pwfxDst
->wFormatTag
)
825 case WAVE_FORMAT_PCM
:
826 adfs
->pwfxDst
->nBlockAlign
= adfs
->pwfxDst
->nChannels
* 2;
827 adfs
->pwfxDst
->nAvgBytesPerSec
= adfs
->pwfxDst
->nSamplesPerSec
* adfs
->pwfxDst
->nBlockAlign
;
829 case WAVE_FORMAT_ALAW
:
830 adfs
->pwfxDst
->nBlockAlign
= adfs
->pwfxDst
->nChannels
;
831 adfs
->pwfxDst
->nAvgBytesPerSec
= adfs
->pwfxDst
->nSamplesPerSec
* adfs
->pwfxSrc
->nChannels
;
833 case WAVE_FORMAT_MULAW
:
834 adfs
->pwfxDst
->nBlockAlign
= adfs
->pwfxDst
->nChannels
;
835 adfs
->pwfxDst
->nAvgBytesPerSec
= adfs
->pwfxDst
->nSamplesPerSec
* adfs
->pwfxSrc
->nChannels
;
839 return MMSYSERR_NOERROR
;
842 /***********************************************************************
846 static void G711_Reset(PACMDRVSTREAMINSTANCE adsi
, AcmG711Data
* aad
)
850 /***********************************************************************
854 static LRESULT
G711_StreamOpen(PACMDRVSTREAMINSTANCE adsi
)
858 assert(!(adsi
->fdwOpen
& ACM_STREAMOPENF_ASYNC
));
860 if (G711_GetFormatIndex(adsi
->pwfxSrc
) == 0xFFFFFFFF ||
861 G711_GetFormatIndex(adsi
->pwfxDst
) == 0xFFFFFFFF)
862 return ACMERR_NOTPOSSIBLE
;
864 aad
= HeapAlloc(GetProcessHeap(), 0, sizeof(AcmG711Data
));
865 if (aad
== 0) return MMSYSERR_NOMEM
;
867 adsi
->dwDriver
= (DWORD_PTR
)aad
;
869 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
870 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
874 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_ALAW
&&
875 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
877 /* resampling or mono <=> stereo not available
878 * G711 algo only define 16 bit per sample output
880 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
881 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
||
882 adsi
->pwfxDst
->wBitsPerSample
!= 16)
885 /* g711 A-Law decoding... */
886 if (adsi
->pwfxDst
->wBitsPerSample
== 16)
887 aad
->convert
= cvtXXalaw16K
;
889 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
890 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_ALAW
)
892 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
893 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
||
894 adsi
->pwfxSrc
->wBitsPerSample
!= 16)
898 if (adsi
->pwfxSrc
->wBitsPerSample
== 16)
899 aad
->convert
= cvtXX16alawK
;
901 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MULAW
&&
902 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
904 /* resampling or mono <=> stereo not available
905 * G711 algo only define 16 bit per sample output
907 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
908 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
||
909 adsi
->pwfxDst
->wBitsPerSample
!= 16)
912 /* g711 MU-Law decoding... */
913 if (adsi
->pwfxDst
->wBitsPerSample
== 16)
914 aad
->convert
= cvtXXulaw16K
;
916 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
917 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MULAW
)
919 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
920 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
||
921 adsi
->pwfxSrc
->wBitsPerSample
!= 16)
925 if (adsi
->pwfxSrc
->wBitsPerSample
== 16)
926 aad
->convert
= cvtXX16ulawK
;
928 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MULAW
&&
929 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_ALAW
)
931 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
932 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
)
935 /* MU-Law => A-Law... */
936 aad
->convert
= cvtXXulawalawK
;
938 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_ALAW
&&
939 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MULAW
)
941 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
942 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
)
945 /* A-Law => MU-Law... */
946 aad
->convert
= cvtXXalawulawK
;
950 G711_Reset(adsi
, aad
);
952 return MMSYSERR_NOERROR
;
955 HeapFree(GetProcessHeap(), 0, aad
);
957 return MMSYSERR_NOTSUPPORTED
;
960 /***********************************************************************
964 static LRESULT
G711_StreamClose(PACMDRVSTREAMINSTANCE adsi
)
966 HeapFree(GetProcessHeap(), 0, (void*)adsi
->dwDriver
);
967 return MMSYSERR_NOERROR
;
970 /***********************************************************************
974 static LRESULT
G711_StreamSize(const ACMDRVSTREAMINSTANCE
*adsi
, PACMDRVSTREAMSIZE adss
)
976 switch (adss
->fdwSize
)
978 case ACM_STREAMSIZEF_DESTINATION
:
979 /* cbDstLength => cbSrcLength */
980 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
981 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_ALAW
||
982 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MULAW
))
984 adss
->cbSrcLength
= adss
->cbDstLength
* 2;
986 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_ALAW
||
987 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MULAW
) &&
988 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
990 adss
->cbSrcLength
= adss
->cbDstLength
/ 2;
992 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_ALAW
||
993 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MULAW
) &&
994 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_ALAW
||
995 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MULAW
))
997 adss
->cbSrcLength
= adss
->cbDstLength
;
1001 return MMSYSERR_NOTSUPPORTED
;
1004 case ACM_STREAMSIZEF_SOURCE
:
1005 /* cbSrcLength => cbDstLength */
1006 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
1007 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_ALAW
||
1008 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MULAW
))
1010 adss
->cbDstLength
= adss
->cbSrcLength
/ 2;
1012 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_ALAW
||
1013 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MULAW
) &&
1014 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
1016 adss
->cbDstLength
= adss
->cbSrcLength
* 2;
1018 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_ALAW
||
1019 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MULAW
) &&
1020 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_ALAW
||
1021 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MULAW
))
1023 adss
->cbDstLength
= adss
->cbSrcLength
;
1027 return MMSYSERR_NOTSUPPORTED
;
1031 WARN("Unsupported query %08lx\n", adss
->fdwSize
);
1032 return MMSYSERR_NOTSUPPORTED
;
1034 return MMSYSERR_NOERROR
;
1037 /***********************************************************************
1038 * G711_StreamConvert
1041 static LRESULT
G711_StreamConvert(PACMDRVSTREAMINSTANCE adsi
, PACMDRVSTREAMHEADER adsh
)
1043 AcmG711Data
* aad
= (AcmG711Data
*)adsi
->dwDriver
;
1044 DWORD nsrc
= adsh
->cbSrcLength
;
1045 DWORD ndst
= adsh
->cbDstLength
;
1047 if (adsh
->fdwConvert
&
1048 ~(ACM_STREAMCONVERTF_BLOCKALIGN
|
1049 ACM_STREAMCONVERTF_END
|
1050 ACM_STREAMCONVERTF_START
))
1052 FIXME("Unsupported fdwConvert (%08lx), ignoring it\n", adsh
->fdwConvert
);
1054 /* ACM_STREAMCONVERTF_BLOCKALIGN
1055 * currently all conversions are block aligned, so do nothing for this flag
1056 * ACM_STREAMCONVERTF_END
1057 * no pending data, so do nothing for this flag
1059 if ((adsh
->fdwConvert
& ACM_STREAMCONVERTF_START
))
1061 G711_Reset(adsi
, aad
);
1064 aad
->convert(adsi
, adsh
->pbSrc
, &nsrc
, adsh
->pbDst
, &ndst
);
1065 adsh
->cbSrcLengthUsed
= nsrc
;
1066 adsh
->cbDstLengthUsed
= ndst
;
1068 return MMSYSERR_NOERROR
;
1071 /**************************************************************************
1072 * G711_DriverProc [exported]
1074 LRESULT CALLBACK
G711_DriverProc(DWORD_PTR dwDevID
, HDRVR hDriv
, UINT wMsg
,
1075 LPARAM dwParam1
, LPARAM dwParam2
)
1077 TRACE("(%08Ix %p %04x %08Ix %08Ix);\n",
1078 dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
1082 case DRV_LOAD
: return 1;
1083 case DRV_FREE
: return 1;
1084 case DRV_OPEN
: return G711_drvOpen((LPSTR
)dwParam1
);
1085 case DRV_CLOSE
: return G711_drvClose(dwDevID
);
1086 case DRV_ENABLE
: return 1;
1087 case DRV_DISABLE
: return 1;
1088 case DRV_QUERYCONFIGURE
: return 1;
1089 case DRV_CONFIGURE
: MessageBoxA(0, "MS G711 (a-Law & mu-Law) filter !", "Wine Driver", MB_OK
); return 1;
1090 case DRV_INSTALL
: return DRVCNF_RESTART
;
1091 case DRV_REMOVE
: return DRVCNF_RESTART
;
1093 case ACMDM_DRIVER_NOTIFY
:
1094 /* no caching from other ACM drivers is done so far */
1095 return MMSYSERR_NOERROR
;
1097 case ACMDM_DRIVER_DETAILS
:
1098 return G711_DriverDetails((PACMDRIVERDETAILSW
)dwParam1
);
1100 case ACMDM_FORMATTAG_DETAILS
:
1101 return G711_FormatTagDetails((PACMFORMATTAGDETAILSW
)dwParam1
, dwParam2
);
1103 case ACMDM_FORMAT_DETAILS
:
1104 return G711_FormatDetails((PACMFORMATDETAILSW
)dwParam1
, dwParam2
);
1106 case ACMDM_FORMAT_SUGGEST
:
1107 return G711_FormatSuggest((PACMDRVFORMATSUGGEST
)dwParam1
);
1109 case ACMDM_STREAM_OPEN
:
1110 return G711_StreamOpen((PACMDRVSTREAMINSTANCE
)dwParam1
);
1112 case ACMDM_STREAM_CLOSE
:
1113 return G711_StreamClose((PACMDRVSTREAMINSTANCE
)dwParam1
);
1115 case ACMDM_STREAM_SIZE
:
1116 return G711_StreamSize((PACMDRVSTREAMINSTANCE
)dwParam1
, (PACMDRVSTREAMSIZE
)dwParam2
);
1118 case ACMDM_STREAM_CONVERT
:
1119 return G711_StreamConvert((PACMDRVSTREAMINSTANCE
)dwParam1
, (PACMDRVSTREAMHEADER
)dwParam2
);
1121 case ACMDM_HARDWARE_WAVE_CAPS_INPUT
:
1122 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
:
1123 /* this converter is not a hardware driver */
1124 case ACMDM_FILTERTAG_DETAILS
:
1125 case ACMDM_FILTER_DETAILS
:
1126 /* this converter is not a filter */
1127 case ACMDM_STREAM_RESET
:
1128 /* only needed for asynchronous driver... we aren't, so just say it */
1129 return MMSYSERR_NOTSUPPORTED
;
1130 case ACMDM_STREAM_PREPARE
:
1131 case ACMDM_STREAM_UNPREPARE
:
1132 /* nothing special to do here... so don't do anything */
1133 return MMSYSERR_NOERROR
;
1136 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);