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