xref: /reactos/dll/win32/msg711.acm/msg711.c (revision aad80191)
1 /*
2  * G711 handling (includes A-Law & MU-Law)
3  *
4  *      Copyright (C) 2002		Eric Pouech
5  *
6  *
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.
11  *
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.
16  *
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
20  */
21 
22 #include <assert.h>
23 #include <stdarg.h>
24 #include <string.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winuser.h"
29 #include "winnls.h"
30 #include "mmsystem.h"
31 #include "mmreg.h"
32 #include "msacm.h"
33 #include "msacmdrv.h"
34 #include "wine/debug.h"
35 
36 WINE_DEFAULT_DEBUG_CHANNEL(g711);
37 
38 /***********************************************************************
39  *           G711_drvOpen
40  */
41 static LRESULT G711_drvOpen(LPCSTR str)
42 {
43     return 1;
44 }
45 
46 /***********************************************************************
47  *           G711_drvClose
48  */
49 static LRESULT G711_drvClose(DWORD_PTR dwDevID)
50 {
51     return 1;
52 }
53 
54 typedef struct tagAcmG711Data
55 {
56     void (*convert)(PACMDRVSTREAMINSTANCE adsi,
57 		    const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
58 } AcmG711Data;
59 
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
62  */
63 typedef	struct
64 {
65     int		nChannels;
66     int		nBits;
67     int		rate;
68 } Format;
69 
70 static const Format PCM_Formats[] =
71 {
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},
76 };
77 
78 static const Format ALaw_Formats[] =
79 {
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},
82 };
83 
84 static const Format ULaw_Formats[] =
85 {
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},
88 };
89 
90 #define	NUM_PCM_FORMATS		(sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
91 #define	NUM_ALAW_FORMATS	(sizeof(ALaw_Formats) / sizeof(ALaw_Formats[0]))
92 #define	NUM_ULAW_FORMATS	(sizeof(ULaw_Formats) / sizeof(ULaw_Formats[0]))
93 
94 /***********************************************************************
95  *           G711_GetFormatIndex
96  */
97 static	DWORD	G711_GetFormatIndex(const WAVEFORMATEX *wfx)
98 {
99     int             i, hi;
100     const Format*   fmts;
101 
102     switch (wfx->wFormatTag)
103     {
104     case WAVE_FORMAT_PCM:
105 	hi = NUM_PCM_FORMATS;
106 	fmts = PCM_Formats;
107 	break;
108     case WAVE_FORMAT_ALAW:
109 	hi = NUM_ALAW_FORMATS;
110 	fmts = ALaw_Formats;
111 	break;
112     case WAVE_FORMAT_MULAW:
113 	hi = NUM_ULAW_FORMATS;
114 	fmts = ULaw_Formats;
115 	break;
116     default:
117 	return 0xFFFFFFFF;
118     }
119 
120     for (i = 0; i < hi; i++)
121     {
122 	if (wfx->nChannels == fmts[i].nChannels &&
123 	    wfx->nSamplesPerSec == fmts[i].rate &&
124 	    wfx->wBitsPerSample == fmts[i].nBits)
125 	    return i;
126     }
127 
128     return 0xFFFFFFFF;
129 }
130 
131 /***********************************************************************
132  *           R16
133  *
134  * Read a 16 bit sample (correctly handles endianness)
135  */
136 static inline short  R16(const unsigned char* src)
137 {
138     return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
139 }
140 
141 /***********************************************************************
142  *           W16
143  *
144  * Write a 16 bit sample (correctly handles endianness)
145  */
146 static inline void  W16(unsigned char* dst, short s)
147 {
148     dst[0] = LOBYTE(s);
149     dst[1] = HIBYTE(s);
150 }
151 
152 /* You can uncomment this if you don't want the statically generated conversion
153  * table, but rather recompute the Xlaw => PCM conversion for each sample
154 #define NO_FASTDECODE
155  * Since the conversion tables are rather small (2k), I don't think it's really
156  * interesting not to use them, but keeping the actual conversion code around
157  * is helpful to regenerate the tables when needed.
158  */
159 
160 /* -------------------------------------------------------------------------------*/
161 
162 /*
163  * This source code is a product of Sun Microsystems, Inc. and is provided
164  * for unrestricted use.  Users may copy or modify this source code without
165  * charge.
166  *
167  * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
168  * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
169  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
170  *
171  * Sun source code is provided with no support and without any obligation on
172  * the part of Sun Microsystems, Inc. to assist in its use, correction,
173  * modification or enhancement.
174  *
175  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
176  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
177  * OR ANY PART THEREOF.
178  *
179  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
180  * or profits or other special, indirect and consequential damages, even if
181  * Sun has been advised of the possibility of such damages.
182  *
183  * Sun Microsystems, Inc.
184  * 2550 Garcia Avenue
185  * Mountain View, California  94043
186  */
187 
188 /*
189  * g711.c
190  *
191  * u-law, A-law and linear PCM conversions.
192  */
193 
194 /*
195  * December 30, 1994:
196  * Functions linear2alaw, linear2ulaw have been updated to correctly
197  * convert unquantized 16 bit values.
198  * Tables for direct u- to A-law and A- to u-law conversions have been
199  * corrected.
200  * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
201  * bli@cpk.auc.dk
202  *
203  */
204 
205 #define	SIGN_BIT	(0x80)		/* Sign bit for an A-law byte. */
206 #define	QUANT_MASK	(0xf)		/* Quantization field mask. */
207 #define	NSEGS		(8)		/* Number of A-law segments. */
208 #define	SEG_SHIFT	(4)		/* Left shift for segment number. */
209 #define	SEG_MASK	(0x70)		/* Segment field mask. */
210 
211 static const short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0x0FF, 0x1FF, 0x3FF, 0x7FF, 0x0FFF};
212 static const short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
213 
214 /* copy from CCITT G.711 specifications */
215 static const unsigned char _u2a[128] = {		/* u- to A-law conversions */
216 	1,	1,	2,	2,	3,	3,	4,	4,
217 	5,	5,	6,	6,	7,	7,	8,	8,
218 	9,	10,	11,	12,	13,	14,	15,	16,
219 	17,	18,	19,	20,	21,	22,	23,	24,
220 	25,	27,	29,	31,	33,	34,	35,	36,
221 	37,	38,	39,	40,	41,	42,	43,	44,
222 	46,	48,	49,	50,	51,	52,	53,	54,
223 	55,	56,	57,	58,	59,	60,	61,	62,
224 	64,	65,	66,	67,	68,	69,	70,	71,
225 	72,	73,	74,	75,	76,	77,	78,	79,
226 /* corrected:
227 	81,	82,	83,	84,	85,	86,	87,	88,
228    should be: */
229 	80,	82,	83,	84,	85,	86,	87,	88,
230 	89,	90,	91,	92,	93,	94,	95,	96,
231 	97,	98,	99,	100,	101,	102,	103,	104,
232 	105,	106,	107,	108,	109,	110,	111,	112,
233 	113,	114,	115,	116,	117,	118,	119,	120,
234 	121,	122,	123,	124,	125,	126,	127,	128};
235 
236 static const unsigned char _a2u[128] = {		/* A- to u-law conversions */
237 	1,	3,	5,	7,	9,	11,	13,	15,
238 	16,	17,	18,	19,	20,	21,	22,	23,
239 	24,	25,	26,	27,	28,	29,	30,	31,
240 	32,	32,	33,	33,	34,	34,	35,	35,
241 	36,	37,	38,	39,	40,	41,	42,	43,
242 	44,	45,	46,	47,	48,	48,	49,	49,
243 	50,	51,	52,	53,	54,	55,	56,	57,
244 	58,	59,	60,	61,	62,	63,	64,	64,
245 	65,	66,	67,	68,	69,	70,	71,	72,
246 /* corrected:
247 	73,	74,	75,	76,	77,	78,	79,	79,
248    should be: */
249 	73,	74,	75,	76,	77,	78,	79,	80,
250 
251 	80,	81,	82,	83,	84,	85,	86,	87,
252 	88,	89,	90,	91,	92,	93,	94,	95,
253 	96,	97,	98,	99,	100,	101,	102,	103,
254 	104,	105,	106,	107,	108,	109,	110,	111,
255 	112,	113,	114,	115,	116,	117,	118,	119,
256 	120,	121,	122,	123,	124,	125,	126,	127};
257 
258 static short
259 search(
260     int		val,	        /* changed from "short" *drago* */
261     const short	*table,
262     int		size)	        /* changed from "short" *drago* */
263 {
264     int		i;	/* changed from "short" *drago* */
265 
266     for (i = 0; i < size; i++) {
267         if (val <= *table++)
268             return (i);
269     }
270     return (size);
271 }
272 
273 /*
274  * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law
275  *
276  * linear2alaw() accepts an 16-bit integer and encodes it as A-law data.
277  *
278  *		Linear Input Code	Compressed Code
279  *	------------------------	---------------
280  *	0000000wxyza			000wxyz
281  *	0000001wxyza			001wxyz
282  *	000001wxyzab			010wxyz
283  *	00001wxyzabc			011wxyz
284  *	0001wxyzabcd			100wxyz
285  *	001wxyzabcde			101wxyz
286  *	01wxyzabcdef			110wxyz
287  *	1wxyzabcdefg			111wxyz
288  *
289  * For further information see John C. Bellamy's Digital Telephony, 1982,
290  * John Wiley & Sons, pps 98-111 and 472-476.
291  */
292 static inline unsigned char
293 linear2alaw(int pcm_val)	/* 2's complement (16-bit range) */
294     /* changed from "short" *drago* */
295 {
296     int		mask;	/* changed from "short" *drago* */
297     int		seg;	/* changed from "short" *drago* */
298     unsigned char	aval;
299 
300     pcm_val = pcm_val >> 3;
301 
302     if (pcm_val >= 0) {
303         mask = 0xD5;		/* sign (7th) bit = 1 */
304     } else {
305         mask = 0x55;		/* sign bit = 0 */
306         pcm_val = -pcm_val - 1;
307     }
308 
309     /* Convert the scaled magnitude to segment number. */
310     seg = search(pcm_val, seg_aend, 8);
311 
312     /* Combine the sign, segment, and quantization bits. */
313 
314     if (seg >= 8)		/* out of range, return maximum value. */
315         return (unsigned char) (0x7F ^ mask);
316     else {
317         aval = (unsigned char) seg << SEG_SHIFT;
318         if (seg < 2)
319             aval |= (pcm_val >> 1) & QUANT_MASK;
320         else
321             aval |= (pcm_val >> seg) & QUANT_MASK;
322         return (aval ^ mask);
323     }
324 }
325 
326 #ifdef NO_FASTDECODE
327 /*
328  * alaw2linear() - Convert an A-law value to 16-bit linear PCM
329  *
330  */
331 static inline int
332 alaw2linear(unsigned char a_val)
333 {
334     int		t;	/* changed from "short" *drago* */
335     int		seg;	/* changed from "short" *drago* */
336 
337     a_val ^= 0x55;
338 
339     t = (a_val & QUANT_MASK) << 4;
340     seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
341     switch (seg) {
342     case 0:
343         t += 8;
344         break;
345     case 1:
346         t += 0x108;
347         break;
348     default:
349         t += 0x108;
350         t <<= seg - 1;
351     }
352     return ((a_val & SIGN_BIT) ? t : -t);
353 }
354 #else
355 /* EPP (for Wine):
356  * this array has been statically generated from the above routine
357  */
358 static const unsigned short _a2l[] = {
359 0xEA80, 0xEB80, 0xE880, 0xE980, 0xEE80, 0xEF80, 0xEC80, 0xED80,
360 0xE280, 0xE380, 0xE080, 0xE180, 0xE680, 0xE780, 0xE480, 0xE580,
361 0xF540, 0xF5C0, 0xF440, 0xF4C0, 0xF740, 0xF7C0, 0xF640, 0xF6C0,
362 0xF140, 0xF1C0, 0xF040, 0xF0C0, 0xF340, 0xF3C0, 0xF240, 0xF2C0,
363 0xAA00, 0xAE00, 0xA200, 0xA600, 0xBA00, 0xBE00, 0xB200, 0xB600,
364 0x8A00, 0x8E00, 0x8200, 0x8600, 0x9A00, 0x9E00, 0x9200, 0x9600,
365 0xD500, 0xD700, 0xD100, 0xD300, 0xDD00, 0xDF00, 0xD900, 0xDB00,
366 0xC500, 0xC700, 0xC100, 0xC300, 0xCD00, 0xCF00, 0xC900, 0xCB00,
367 0xFEA8, 0xFEB8, 0xFE88, 0xFE98, 0xFEE8, 0xFEF8, 0xFEC8, 0xFED8,
368 0xFE28, 0xFE38, 0xFE08, 0xFE18, 0xFE68, 0xFE78, 0xFE48, 0xFE58,
369 0xFFA8, 0xFFB8, 0xFF88, 0xFF98, 0xFFE8, 0xFFF8, 0xFFC8, 0xFFD8,
370 0xFF28, 0xFF38, 0xFF08, 0xFF18, 0xFF68, 0xFF78, 0xFF48, 0xFF58,
371 0xFAA0, 0xFAE0, 0xFA20, 0xFA60, 0xFBA0, 0xFBE0, 0xFB20, 0xFB60,
372 0xF8A0, 0xF8E0, 0xF820, 0xF860, 0xF9A0, 0xF9E0, 0xF920, 0xF960,
373 0xFD50, 0xFD70, 0xFD10, 0xFD30, 0xFDD0, 0xFDF0, 0xFD90, 0xFDB0,
374 0xFC50, 0xFC70, 0xFC10, 0xFC30, 0xFCD0, 0xFCF0, 0xFC90, 0xFCB0,
375 0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280,
376 0x1D80, 0x1C80, 0x1F80, 0x1E80, 0x1980, 0x1880, 0x1B80, 0x1A80,
377 0x0AC0, 0x0A40, 0x0BC0, 0x0B40, 0x08C0, 0x0840, 0x09C0, 0x0940,
378 0x0EC0, 0x0E40, 0x0FC0, 0x0F40, 0x0CC0, 0x0C40, 0x0DC0, 0x0D40,
379 0x5600, 0x5200, 0x5E00, 0x5A00, 0x4600, 0x4200, 0x4E00, 0x4A00,
380 0x7600, 0x7200, 0x7E00, 0x7A00, 0x6600, 0x6200, 0x6E00, 0x6A00,
381 0x2B00, 0x2900, 0x2F00, 0x2D00, 0x2300, 0x2100, 0x2700, 0x2500,
382 0x3B00, 0x3900, 0x3F00, 0x3D00, 0x3300, 0x3100, 0x3700, 0x3500,
383 0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128,
384 0x01D8, 0x01C8, 0x01F8, 0x01E8, 0x0198, 0x0188, 0x01B8, 0x01A8,
385 0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028,
386 0x00D8, 0x00C8, 0x00F8, 0x00E8, 0x0098, 0x0088, 0x00B8, 0x00A8,
387 0x0560, 0x0520, 0x05E0, 0x05A0, 0x0460, 0x0420, 0x04E0, 0x04A0,
388 0x0760, 0x0720, 0x07E0, 0x07A0, 0x0660, 0x0620, 0x06E0, 0x06A0,
389 0x02B0, 0x0290, 0x02F0, 0x02D0, 0x0230, 0x0210, 0x0270, 0x0250,
390 0x03B0, 0x0390, 0x03F0, 0x03D0, 0x0330, 0x0310, 0x0370, 0x0350,
391 };
392 static inline int
393 alaw2linear(unsigned char a_val)
394 {
395     return (short)_a2l[a_val];
396 }
397 #endif
398 
399 #define	BIAS		(0x84)		/* Bias for linear code. */
400 #define CLIP            8159
401 
402 /*
403  * linear2ulaw() - Convert a linear PCM value to u-law
404  *
405  * In order to simplify the encoding process, the original linear magnitude
406  * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
407  * (33 - 8191). The result can be seen in the following encoding table:
408  *
409  *	Biased Linear Input Code	Compressed Code
410  *	------------------------	---------------
411  *	00000001wxyza			000wxyz
412  *	0000001wxyzab			001wxyz
413  *	000001wxyzabc			010wxyz
414  *	00001wxyzabcd			011wxyz
415  *	0001wxyzabcde			100wxyz
416  *	001wxyzabcdef			101wxyz
417  *	01wxyzabcdefg			110wxyz
418  *	1wxyzabcdefgh			111wxyz
419  *
420  * Each biased linear code has a leading 1 which identifies the segment
421  * number. The value of the segment number is equal to 7 minus the number
422  * of leading 0's. The quantization interval is directly available as the
423  * four bits wxyz.  * The trailing bits (a - h) are ignored.
424  *
425  * Ordinarily the complement of the resulting code word is used for
426  * transmission, and so the code word is complemented before it is returned.
427  *
428  * For further information see John C. Bellamy's Digital Telephony, 1982,
429  * John Wiley & Sons, pps 98-111 and 472-476.
430  */
431 static inline unsigned char
432 linear2ulaw(short pcm_val)	/* 2's complement (16-bit range) */
433 {
434     short		mask;
435     short		seg;
436     unsigned char	uval;
437 
438     /* Get the sign and the magnitude of the value. */
439     pcm_val = pcm_val >> 2;
440     if (pcm_val < 0) {
441         pcm_val = -pcm_val;
442         mask = 0x7F;
443     } else {
444         mask = 0xFF;
445     }
446     if ( pcm_val > CLIP ) pcm_val = CLIP;		/* clip the magnitude */
447     pcm_val += (BIAS >> 2);
448 
449     /* Convert the scaled magnitude to segment number. */
450     seg = search(pcm_val, seg_uend, 8);
451 
452     /*
453      * Combine the sign, segment, quantization bits;
454      * and complement the code word.
455      */
456     if (seg >= 8)		/* out of range, return maximum value. */
457         return (unsigned char) (0x7F ^ mask);
458     else {
459         uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
460         return (uval ^ mask);
461     }
462 }
463 
464 #ifdef NO_FASTDECODE
465 /*
466  * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
467  *
468  * First, a biased linear code is derived from the code word. An unbiased
469  * output can then be obtained by subtracting 33 from the biased code.
470  *
471  * Note that this function expects to be passed the complement of the
472  * original code word. This is in keeping with ISDN conventions.
473  */
474 static inline short
475 ulaw2linear(unsigned char u_val)
476 {
477     short		t;
478 
479     /* Complement to obtain normal u-law value. */
480     u_val = ~u_val;
481 
482     /*
483      * Extract and bias the quantization bits. Then
484      * shift up by the segment number and subtract out the bias.
485      */
486     t = ((u_val & QUANT_MASK) << 3) + BIAS;
487     t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
488 
489     return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
490 }
491 #else
492 /* EPP (for Wine):
493  * this array has been statically generated from the above routine
494  */
495 static const unsigned short _u2l[] = {
496 0x8284, 0x8684, 0x8A84, 0x8E84, 0x9284, 0x9684, 0x9A84, 0x9E84,
497 0xA284, 0xA684, 0xAA84, 0xAE84, 0xB284, 0xB684, 0xBA84, 0xBE84,
498 0xC184, 0xC384, 0xC584, 0xC784, 0xC984, 0xCB84, 0xCD84, 0xCF84,
499 0xD184, 0xD384, 0xD584, 0xD784, 0xD984, 0xDB84, 0xDD84, 0xDF84,
500 0xE104, 0xE204, 0xE304, 0xE404, 0xE504, 0xE604, 0xE704, 0xE804,
501 0xE904, 0xEA04, 0xEB04, 0xEC04, 0xED04, 0xEE04, 0xEF04, 0xF004,
502 0xF0C4, 0xF144, 0xF1C4, 0xF244, 0xF2C4, 0xF344, 0xF3C4, 0xF444,
503 0xF4C4, 0xF544, 0xF5C4, 0xF644, 0xF6C4, 0xF744, 0xF7C4, 0xF844,
504 0xF8A4, 0xF8E4, 0xF924, 0xF964, 0xF9A4, 0xF9E4, 0xFA24, 0xFA64,
505 0xFAA4, 0xFAE4, 0xFB24, 0xFB64, 0xFBA4, 0xFBE4, 0xFC24, 0xFC64,
506 0xFC94, 0xFCB4, 0xFCD4, 0xFCF4, 0xFD14, 0xFD34, 0xFD54, 0xFD74,
507 0xFD94, 0xFDB4, 0xFDD4, 0xFDF4, 0xFE14, 0xFE34, 0xFE54, 0xFE74,
508 0xFE8C, 0xFE9C, 0xFEAC, 0xFEBC, 0xFECC, 0xFEDC, 0xFEEC, 0xFEFC,
509 0xFF0C, 0xFF1C, 0xFF2C, 0xFF3C, 0xFF4C, 0xFF5C, 0xFF6C, 0xFF7C,
510 0xFF88, 0xFF90, 0xFF98, 0xFFA0, 0xFFA8, 0xFFB0, 0xFFB8, 0xFFC0,
511 0xFFC8, 0xFFD0, 0xFFD8, 0xFFE0, 0xFFE8, 0xFFF0, 0xFFF8, 0x0000,
512 0x7D7C, 0x797C, 0x757C, 0x717C, 0x6D7C, 0x697C, 0x657C, 0x617C,
513 0x5D7C, 0x597C, 0x557C, 0x517C, 0x4D7C, 0x497C, 0x457C, 0x417C,
514 0x3E7C, 0x3C7C, 0x3A7C, 0x387C, 0x367C, 0x347C, 0x327C, 0x307C,
515 0x2E7C, 0x2C7C, 0x2A7C, 0x287C, 0x267C, 0x247C, 0x227C, 0x207C,
516 0x1EFC, 0x1DFC, 0x1CFC, 0x1BFC, 0x1AFC, 0x19FC, 0x18FC, 0x17FC,
517 0x16FC, 0x15FC, 0x14FC, 0x13FC, 0x12FC, 0x11FC, 0x10FC, 0x0FFC,
518 0x0F3C, 0x0EBC, 0x0E3C, 0x0DBC, 0x0D3C, 0x0CBC, 0x0C3C, 0x0BBC,
519 0x0B3C, 0x0ABC, 0x0A3C, 0x09BC, 0x093C, 0x08BC, 0x083C, 0x07BC,
520 0x075C, 0x071C, 0x06DC, 0x069C, 0x065C, 0x061C, 0x05DC, 0x059C,
521 0x055C, 0x051C, 0x04DC, 0x049C, 0x045C, 0x041C, 0x03DC, 0x039C,
522 0x036C, 0x034C, 0x032C, 0x030C, 0x02EC, 0x02CC, 0x02AC, 0x028C,
523 0x026C, 0x024C, 0x022C, 0x020C, 0x01EC, 0x01CC, 0x01AC, 0x018C,
524 0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
525 0x00F4, 0x00E4, 0x00D4, 0x00C4, 0x00B4, 0x00A4, 0x0094, 0x0084,
526 0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
527 0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000,
528 };
529 static inline short ulaw2linear(unsigned char u_val)
530 {
531     return (short)_u2l[u_val];
532 }
533 #endif
534 
535 /* A-law to u-law conversion */
536 static inline unsigned char
537 alaw2ulaw(unsigned char aval)
538 {
539     aval &= 0xff;
540     return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
541                             (0x7F ^ _a2u[aval ^ 0x55]));
542 }
543 
544 /* u-law to A-law conversion */
545 static inline unsigned char
546 ulaw2alaw(unsigned char uval)
547 {
548     uval &= 0xff;
549     return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
550                             (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
551 }
552 
553 /* -------------------------------------------------------------------------------*/
554 
555 static void cvtXXalaw16K(PACMDRVSTREAMINSTANCE adsi,
556                          const unsigned char* src, LPDWORD srcsize,
557                          unsigned char* dst, LPDWORD dstsize)
558 {
559     DWORD       len = min(*srcsize, *dstsize / 2);
560     DWORD       i;
561     short       w;
562 
563     *srcsize = len;
564     *dstsize = len * 2;
565     for (i = 0; i < len; i++)
566     {
567         w = alaw2linear(*src++);
568         W16(dst, w);    dst += 2;
569     }
570 }
571 
572 static void cvtXX16alawK(PACMDRVSTREAMINSTANCE adsi,
573                          const unsigned char* src, LPDWORD srcsize,
574                          unsigned char* dst, LPDWORD dstsize)
575 {
576     DWORD       len = min(*srcsize / 2, *dstsize);
577     DWORD       i;
578 
579     *srcsize = len * 2;
580     *dstsize = len;
581     for (i = 0; i < len; i++)
582     {
583         *dst++ = linear2alaw(R16(src)); src += 2;
584     }
585 }
586 
587 static void cvtXXulaw16K(PACMDRVSTREAMINSTANCE adsi,
588                          const unsigned char* src, LPDWORD srcsize,
589                          unsigned char* dst, LPDWORD dstsize)
590 {
591     DWORD       len = min(*srcsize, *dstsize / 2);
592     DWORD       i;
593     short       w;
594 
595     *srcsize = len;
596     *dstsize = len * 2;
597     for (i = 0; i < len; i++)
598     {
599         w = ulaw2linear(*src++);
600         W16(dst, w);    dst += 2;
601     }
602 }
603 
604 static void cvtXX16ulawK(PACMDRVSTREAMINSTANCE adsi,
605                          const unsigned char* src, LPDWORD srcsize,
606                          unsigned char* dst, LPDWORD dstsize)
607 {
608     DWORD       len = min(*srcsize / 2, *dstsize);
609     DWORD       i;
610 
611     *srcsize = len * 2;
612     *dstsize = len;
613     for (i = 0; i < len; i++)
614     {
615         *dst++ = linear2ulaw(R16(src)); src += 2;
616     }
617 }
618 
619 static void cvtXXalawulawK(PACMDRVSTREAMINSTANCE adsi,
620                            const unsigned char* src, LPDWORD srcsize,
621                            unsigned char* dst, LPDWORD dstsize)
622 {
623     DWORD       len = min(*srcsize, *dstsize);
624     DWORD       i;
625 
626     *srcsize = len;
627     *dstsize = len;
628 
629     for (i = 0; i < len; i++)
630         *dst++ = alaw2ulaw(*src++);
631 }
632 
633 
634 static void cvtXXulawalawK(PACMDRVSTREAMINSTANCE adsi,
635                            const unsigned char* src, LPDWORD srcsize,
636                            unsigned char* dst, LPDWORD dstsize)
637 {
638     DWORD       len = min(*srcsize, *dstsize);
639     DWORD       i;
640 
641     *srcsize = len;
642     *dstsize = len;
643 
644     for (i = 0; i < len; i++)
645         *dst++ = ulaw2alaw(*src++);
646 }
647 
648 /***********************************************************************
649  *           G711_DriverDetails
650  *
651  */
652 static	LRESULT G711_DriverDetails(PACMDRIVERDETAILSW add)
653 {
654     add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
655     add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
656     add->wMid = MM_MICROSOFT;
657     add->wPid = MM_MSFT_ACM_G711;
658     add->vdwACM = 0x01000000;
659     add->vdwDriver = 0x01000000;
660     add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
661     add->cFormatTags = 3; /* PCM, G711 A-LAW & MU-LAW */
662     add->cFilterTags = 0;
663     add->hicon = NULL;
664     MultiByteToWideChar( CP_ACP, 0, "Microsoft CCITT G.711", -1,
665                          add->szShortName, sizeof(add->szShortName)/sizeof(WCHAR) );
666     MultiByteToWideChar( CP_ACP, 0, "Wine G711 converter", -1,
667                          add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
668     MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
669                          add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
670     MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
671                          add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
672     add->szFeatures[0] = 0;
673 
674     return MMSYSERR_NOERROR;
675 }
676 
677 /***********************************************************************
678  *           G711_FormatTagDetails
679  *
680  */
681 static	LRESULT	G711_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
682 {
683     static const WCHAR szPcm[]={'P','C','M',0};
684     static const WCHAR szALaw[]={'A','-','L','a','w',0};
685     static const WCHAR szULaw[]={'U','-','L','a','w',0};
686 
687     switch (dwQuery)
688     {
689     case ACM_FORMATTAGDETAILSF_INDEX:
690 	if (aftd->dwFormatTagIndex >= 3) return ACMERR_NOTPOSSIBLE;
691 	break;
692     case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
693 	if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
694         {
695             aftd->dwFormatTagIndex = 1;
696 	    break;
697 	}
698 	/* fall through */
699     case ACM_FORMATTAGDETAILSF_FORMATTAG:
700 	switch (aftd->dwFormatTag)
701         {
702 	case WAVE_FORMAT_PCM:	aftd->dwFormatTagIndex = 0; break;
703 	case WAVE_FORMAT_ALAW:  aftd->dwFormatTagIndex = 1; break;
704 	case WAVE_FORMAT_MULAW: aftd->dwFormatTagIndex = 2; break;
705 	default:		return ACMERR_NOTPOSSIBLE;
706 	}
707 	break;
708     default:
709 	WARN("Unsupported query %08x\n", dwQuery);
710 	return MMSYSERR_NOTSUPPORTED;
711     }
712 
713     aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
714     switch (aftd->dwFormatTagIndex)
715     {
716     case 0:
717 	aftd->dwFormatTag = WAVE_FORMAT_PCM;
718 	aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
719 	aftd->cStandardFormats = NUM_PCM_FORMATS;
720         lstrcpyW(aftd->szFormatTag, szPcm);
721         break;
722     case 1:
723 	aftd->dwFormatTag = WAVE_FORMAT_ALAW;
724 	aftd->cbFormatSize = sizeof(WAVEFORMATEX);
725 	aftd->cStandardFormats = NUM_ALAW_FORMATS;
726         lstrcpyW(aftd->szFormatTag, szALaw);
727 	break;
728     case 2:
729 	aftd->dwFormatTag = WAVE_FORMAT_MULAW;
730 	aftd->cbFormatSize = sizeof(WAVEFORMATEX);
731 	aftd->cStandardFormats = NUM_ULAW_FORMATS;
732         lstrcpyW(aftd->szFormatTag, szULaw);
733 	break;
734     }
735     return MMSYSERR_NOERROR;
736 }
737 
738 /***********************************************************************
739  *           G711_FormatDetails
740  *
741  */
742 static	LRESULT	G711_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
743 {
744     switch (dwQuery)
745     {
746     case ACM_FORMATDETAILSF_FORMAT:
747 	if (G711_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
748 	break;
749     case ACM_FORMATDETAILSF_INDEX:
750 	afd->pwfx->wFormatTag = afd->dwFormatTag;
751 	switch (afd->dwFormatTag)
752         {
753 	case WAVE_FORMAT_PCM:
754 	    if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE;
755 	    afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
756 	    afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
757 	    afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
758 	    afd->pwfx->nBlockAlign = afd->pwfx->nChannels * 2;
759 	    afd->pwfx->nAvgBytesPerSec = afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
760 	    break;
761 	case WAVE_FORMAT_ALAW:
762 	    if (afd->dwFormatIndex >= NUM_ALAW_FORMATS) return ACMERR_NOTPOSSIBLE;
763 	    afd->pwfx->nChannels = ALaw_Formats[afd->dwFormatIndex].nChannels;
764 	    afd->pwfx->nSamplesPerSec = ALaw_Formats[afd->dwFormatIndex].rate;
765 	    afd->pwfx->wBitsPerSample = ALaw_Formats[afd->dwFormatIndex].nBits;
766 	    afd->pwfx->nBlockAlign = ALaw_Formats[afd->dwFormatIndex].nChannels;
767 	    afd->pwfx->nAvgBytesPerSec = afd->pwfx->nSamplesPerSec * afd->pwfx->nChannels;
768             afd->pwfx->cbSize = 0;
769 	    break;
770 	case WAVE_FORMAT_MULAW:
771 	    if (afd->dwFormatIndex >= NUM_ULAW_FORMATS) return ACMERR_NOTPOSSIBLE;
772 	    afd->pwfx->nChannels = ULaw_Formats[afd->dwFormatIndex].nChannels;
773 	    afd->pwfx->nSamplesPerSec = ULaw_Formats[afd->dwFormatIndex].rate;
774 	    afd->pwfx->wBitsPerSample = ULaw_Formats[afd->dwFormatIndex].nBits;
775 	    afd->pwfx->nBlockAlign = ULaw_Formats[afd->dwFormatIndex].nChannels;
776 	    afd->pwfx->nAvgBytesPerSec = afd->pwfx->nSamplesPerSec * afd->pwfx->nChannels;
777             afd->pwfx->cbSize = 0;
778 	    break;
779 	default:
780             WARN("Unsupported tag %08x\n", afd->dwFormatTag);
781 	    return MMSYSERR_INVALPARAM;
782 	}
783 	break;
784     default:
785 	WARN("Unsupported query %08x\n", dwQuery);
786 	return MMSYSERR_NOTSUPPORTED;
787     }
788     afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
789     afd->szFormat[0] = 0; /* let MSACM format this for us... */
790 
791     return MMSYSERR_NOERROR;
792 }
793 
794 /***********************************************************************
795  *           G711_FormatSuggest
796  *
797  */
798 static	LRESULT	G711_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
799 {
800     /* some tests ... */
801     if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
802 	adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
803 	G711_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
804     /* FIXME: should do those tests against the real size (according to format tag */
805 
806     /* If no suggestion for destination, then copy source value */
807     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
808 	adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
809     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
810         adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
811 
812     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
813     {
814 	if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
815             adfs->pwfxDst->wBitsPerSample = 8;
816         else
817             adfs->pwfxDst->wBitsPerSample = 16;
818     }
819     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
820     {
821 	switch (adfs->pwfxSrc->wFormatTag)
822         {
823         case WAVE_FORMAT_PCM:   adfs->pwfxDst->wFormatTag = WAVE_FORMAT_ALAW; break;
824         case WAVE_FORMAT_ALAW:  adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; break;
825         case WAVE_FORMAT_MULAW: adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM; break;
826         }
827     }
828     /* check if result is ok */
829     if (G711_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
830 
831     /* recompute other values */
832     switch (adfs->pwfxDst->wFormatTag)
833     {
834     case WAVE_FORMAT_PCM:
835         adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels * 2;
836         adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
837         break;
838     case WAVE_FORMAT_ALAW:
839         adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels;
840         adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels;
841         break;
842     case WAVE_FORMAT_MULAW:
843         adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels;
844         adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels;
845         break;
846     }
847 
848     return MMSYSERR_NOERROR;
849 }
850 
851 /***********************************************************************
852  *           G711_Reset
853  *
854  */
855 static	void	G711_Reset(PACMDRVSTREAMINSTANCE adsi, AcmG711Data* aad)
856 {
857 }
858 
859 /***********************************************************************
860  *           G711_StreamOpen
861  *
862  */
863 static	LRESULT	G711_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
864 {
865     AcmG711Data*	aad;
866 
867     assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
868 
869     if (G711_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
870 	G711_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
871 	return ACMERR_NOTPOSSIBLE;
872 
873     aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmG711Data));
874     if (aad == 0) return MMSYSERR_NOMEM;
875 
876     adsi->dwDriver = (DWORD_PTR)aad;
877 
878     if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
879 	adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
880     {
881 	goto theEnd;
882     }
883     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW &&
884              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
885     {
886 	/* resampling or mono <=> stereo not available
887          * G711 algo only define 16 bit per sample output
888          */
889 	if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
890 	    adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
891             adsi->pwfxDst->wBitsPerSample != 16)
892 	    goto theEnd;
893 
894 	/* g711 A-Law decoding... */
895 	if (adsi->pwfxDst->wBitsPerSample == 16)
896 	    aad->convert = cvtXXalaw16K;
897     }
898     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
899              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW)
900     {
901 	if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
902 	    adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
903             adsi->pwfxSrc->wBitsPerSample != 16)
904 	    goto theEnd;
905 
906 	/* g711 coding... */
907 	if (adsi->pwfxSrc->wBitsPerSample == 16)
908 	    aad->convert = cvtXX16alawK;
909     }
910     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW &&
911              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
912     {
913 	/* resampling or mono <=> stereo not available
914          * G711 algo only define 16 bit per sample output
915          */
916 	if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
917 	    adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
918             adsi->pwfxDst->wBitsPerSample != 16)
919 	    goto theEnd;
920 
921 	/* g711 MU-Law decoding... */
922 	if (adsi->pwfxDst->wBitsPerSample == 16)
923 	    aad->convert = cvtXXulaw16K;
924     }
925     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
926              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW)
927     {
928 	if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
929 	    adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
930             adsi->pwfxSrc->wBitsPerSample != 16)
931 	    goto theEnd;
932 
933 	/* g711 coding... */
934 	if (adsi->pwfxSrc->wBitsPerSample == 16)
935 	    aad->convert = cvtXX16ulawK;
936     }
937     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW &&
938              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW)
939     {
940 	if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
941 	    adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels)
942 	    goto theEnd;
943 
944 	/* MU-Law => A-Law... */
945         aad->convert = cvtXXulawalawK;
946     }
947     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW &&
948              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW)
949     {
950 	if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
951 	    adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels)
952 	    goto theEnd;
953 
954 	/* A-Law => MU-Law... */
955         aad->convert = cvtXXalawulawK;
956     }
957     else goto theEnd;
958 
959     G711_Reset(adsi, aad);
960 
961     return MMSYSERR_NOERROR;
962 
963  theEnd:
964     HeapFree(GetProcessHeap(), 0, aad);
965     adsi->dwDriver = 0L;
966     return MMSYSERR_NOTSUPPORTED;
967 }
968 
969 /***********************************************************************
970  *           G711_StreamClose
971  *
972  */
973 static	LRESULT	G711_StreamClose(PACMDRVSTREAMINSTANCE adsi)
974 {
975     HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
976     return MMSYSERR_NOERROR;
977 }
978 
979 /***********************************************************************
980  *           G711_StreamSize
981  *
982  */
983 static	LRESULT G711_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
984 {
985     switch (adss->fdwSize)
986     {
987     case ACM_STREAMSIZEF_DESTINATION:
988 	/* cbDstLength => cbSrcLength */
989 	if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
990 	    (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
991              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
992         {
993 	    adss->cbSrcLength = adss->cbDstLength * 2;
994 	}
995         else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
996                   adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
997                  adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
998         {
999 	    adss->cbSrcLength = adss->cbDstLength / 2;
1000 	}
1001         else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1002                   adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1003                  (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
1004                   adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
1005         {
1006 	    adss->cbSrcLength = adss->cbDstLength;
1007         }
1008         else
1009         {
1010 	    return MMSYSERR_NOTSUPPORTED;
1011 	}
1012 	break;
1013     case ACM_STREAMSIZEF_SOURCE:
1014 	/* cbSrcLength => cbDstLength */
1015 	if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
1016 	    (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
1017              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
1018         {
1019 	    adss->cbDstLength = adss->cbSrcLength / 2;
1020 	}
1021         else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1022                   adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1023                  adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
1024         {
1025 	    adss->cbDstLength = adss->cbSrcLength * 2;
1026 	}
1027         else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1028                   adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1029                  (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
1030                   adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
1031         {
1032 	    adss->cbDstLength = adss->cbSrcLength;
1033         }
1034         else
1035         {
1036 	    return MMSYSERR_NOTSUPPORTED;
1037 	}
1038 	break;
1039     default:
1040 	WARN("Unsupported query %08x\n", adss->fdwSize);
1041 	return MMSYSERR_NOTSUPPORTED;
1042     }
1043     return MMSYSERR_NOERROR;
1044 }
1045 
1046 /***********************************************************************
1047  *           G711_StreamConvert
1048  *
1049  */
1050 static LRESULT G711_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
1051 {
1052     AcmG711Data*	aad = (AcmG711Data*)adsi->dwDriver;
1053     DWORD		nsrc = adsh->cbSrcLength;
1054     DWORD		ndst = adsh->cbDstLength;
1055 
1056     if (adsh->fdwConvert &
1057 	~(ACM_STREAMCONVERTF_BLOCKALIGN|
1058 	  ACM_STREAMCONVERTF_END|
1059 	  ACM_STREAMCONVERTF_START))
1060     {
1061 	FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
1062     }
1063     /* ACM_STREAMCONVERTF_BLOCKALIGN
1064      *	currently all conversions are block aligned, so do nothing for this flag
1065      * ACM_STREAMCONVERTF_END
1066      *	no pending data, so do nothing for this flag
1067      */
1068     if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
1069     {
1070 	G711_Reset(adsi, aad);
1071     }
1072 
1073     aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
1074     adsh->cbSrcLengthUsed = nsrc;
1075     adsh->cbDstLengthUsed = ndst;
1076 
1077     return MMSYSERR_NOERROR;
1078 }
1079 
1080 /**************************************************************************
1081  * 			G711_DriverProc			[exported]
1082  */
1083 LRESULT CALLBACK G711_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
1084 					 LPARAM dwParam1, LPARAM dwParam2)
1085 {
1086     TRACE("(%08lx %p %04x %08lx %08lx);\n",
1087           dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1088 
1089     switch (wMsg)
1090     {
1091     case DRV_LOAD:		return 1;
1092     case DRV_FREE:		return 1;
1093     case DRV_OPEN:		return G711_drvOpen((LPSTR)dwParam1);
1094     case DRV_CLOSE:		return G711_drvClose(dwDevID);
1095     case DRV_ENABLE:		return 1;
1096     case DRV_DISABLE:		return 1;
1097     case DRV_QUERYCONFIGURE:	return 1;
1098     case DRV_CONFIGURE:		MessageBoxA(0, "MS G711 (a-Law & mu-Law) filter !", "Wine Driver", MB_OK); return 1;
1099     case DRV_INSTALL:		return DRVCNF_RESTART;
1100     case DRV_REMOVE:		return DRVCNF_RESTART;
1101 
1102     case ACMDM_DRIVER_NOTIFY:
1103 	/* no caching from other ACM drivers is done so far */
1104 	return MMSYSERR_NOERROR;
1105 
1106     case ACMDM_DRIVER_DETAILS:
1107 	return G711_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1108 
1109     case ACMDM_FORMATTAG_DETAILS:
1110 	return G711_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
1111 
1112     case ACMDM_FORMAT_DETAILS:
1113 	return G711_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1114 
1115     case ACMDM_FORMAT_SUGGEST:
1116 	return G711_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
1117 
1118     case ACMDM_STREAM_OPEN:
1119 	return G711_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
1120 
1121     case ACMDM_STREAM_CLOSE:
1122 	return G711_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
1123 
1124     case ACMDM_STREAM_SIZE:
1125 	return G711_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
1126 
1127     case ACMDM_STREAM_CONVERT:
1128 	return G711_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
1129 
1130     case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
1131     case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
1132 	/* this converter is not a hardware driver */
1133     case ACMDM_FILTERTAG_DETAILS:
1134     case ACMDM_FILTER_DETAILS:
1135 	/* this converter is not a filter */
1136     case ACMDM_STREAM_RESET:
1137 	/* only needed for asynchronous driver... we aren't, so just say it */
1138 	return MMSYSERR_NOTSUPPORTED;
1139     case ACMDM_STREAM_PREPARE:
1140     case ACMDM_STREAM_UNPREPARE:
1141 	/* nothing special to do here... so don't do anything */
1142 	return MMSYSERR_NOERROR;
1143 
1144     default:
1145 	return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1146     }
1147 }
1148