Create the AHCI branch for Aman's work
[reactos.git] / dll / win32 / 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 #define WIN32_NO_STATUS
23
24 #include <assert.h>
25 #include <stdarg.h>
26 //#include <string.h>
27 #include <windef.h>
28 #include <winbase.h>
29 #include <wingdi.h>
30 #include <winuser.h>
31 #include <winnls.h>
32 //#include "mmsystem.h"
33 //#include "mmreg.h"
34 //#include "msacm.h"
35 #include <msacmdrv.h>
36 #include <wine/debug.h>
37
38 WINE_DEFAULT_DEBUG_CHANNEL(g711);
39
40 /***********************************************************************
41 * G711_drvOpen
42 */
43 static LRESULT G711_drvOpen(LPCSTR str)
44 {
45 return 1;
46 }
47
48 /***********************************************************************
49 * G711_drvClose
50 */
51 static LRESULT G711_drvClose(DWORD_PTR dwDevID)
52 {
53 return 1;
54 }
55
56 typedef struct tagAcmG711Data
57 {
58 void (*convert)(PACMDRVSTREAMINSTANCE adsi,
59 const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
60 } AcmG711Data;
61
62 /* table to list all supported formats... those are the basic ones. this
63 * also helps given a unique index to each of the supported formats
64 */
65 typedef struct
66 {
67 int nChannels;
68 int nBits;
69 int rate;
70 } Format;
71
72 static const Format PCM_Formats[] =
73 {
74 /*{1, 8, 8000}, {2, 8, 8000}, */{1, 16, 8000}, {2, 16, 8000},
75 /*{1, 8, 11025}, {2, 8, 11025}, */{1, 16, 11025}, {2, 16, 11025},
76 /*{1, 8, 22050}, {2, 8, 22050}, */{1, 16, 22050}, {2, 16, 22050},
77 /*{1, 8, 44100}, {2, 8, 44100}, */{1, 16, 44100}, {2, 16, 44100},
78 };
79
80 static const Format ALaw_Formats[] =
81 {
82 {1, 8, 8000}, {2, 8, 8000}, {1, 8, 11025}, {2, 8, 11025},
83 {1, 8, 22050}, {2, 8, 22050}, {1, 8, 44100}, {2, 8, 44100},
84 };
85
86 static const Format ULaw_Formats[] =
87 {
88 {1, 8, 8000}, {2, 8, 8000}, {1, 8, 11025}, {2, 8, 11025},
89 {1, 8, 22050}, {2, 8, 22050}, {1, 8, 44100}, {2, 8, 44100},
90 };
91
92 #define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
93 #define NUM_ALAW_FORMATS (sizeof(ALaw_Formats) / sizeof(ALaw_Formats[0]))
94 #define NUM_ULAW_FORMATS (sizeof(ULaw_Formats) / sizeof(ULaw_Formats[0]))
95
96 /***********************************************************************
97 * G711_GetFormatIndex
98 */
99 static DWORD G711_GetFormatIndex(const WAVEFORMATEX *wfx)
100 {
101 int i, hi;
102 const Format* fmts;
103
104 switch (wfx->wFormatTag)
105 {
106 case WAVE_FORMAT_PCM:
107 hi = NUM_PCM_FORMATS;
108 fmts = PCM_Formats;
109 break;
110 case WAVE_FORMAT_ALAW:
111 hi = NUM_ALAW_FORMATS;
112 fmts = ALaw_Formats;
113 break;
114 case WAVE_FORMAT_MULAW:
115 hi = NUM_ULAW_FORMATS;
116 fmts = ULaw_Formats;
117 break;
118 default:
119 return 0xFFFFFFFF;
120 }
121
122 for (i = 0; i < hi; i++)
123 {
124 if (wfx->nChannels == fmts[i].nChannels &&
125 wfx->nSamplesPerSec == fmts[i].rate &&
126 wfx->wBitsPerSample == fmts[i].nBits)
127 return i;
128 }
129
130 return 0xFFFFFFFF;
131 }
132
133 /***********************************************************************
134 * R16
135 *
136 * Read a 16 bit sample (correctly handles endianness)
137 */
138 static inline short R16(const unsigned char* src)
139 {
140 return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
141 }
142
143 /***********************************************************************
144 * W16
145 *
146 * Write a 16 bit sample (correctly handles endianness)
147 */
148 static inline void W16(unsigned char* dst, short s)
149 {
150 dst[0] = LOBYTE(s);
151 dst[1] = HIBYTE(s);
152 }
153
154 /* You can uncomment this if you don't want the statically generated conversion
155 * table, but rather recompute the Xlaw => PCM conversion for each sample
156 #define NO_FASTDECODE
157 * Since the conversion tables are rather small (2k), I don't think it's really
158 * interesting not to use them, but keeping the actual conversion code around
159 * is helpful to regenerate the tables when needed.
160 */
161
162 /* -------------------------------------------------------------------------------*/
163
164 /*
165 * This source code is a product of Sun Microsystems, Inc. and is provided
166 * for unrestricted use. Users may copy or modify this source code without
167 * charge.
168 *
169 * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
170 * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
171 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
172 *
173 * Sun source code is provided with no support and without any obligation on
174 * the part of Sun Microsystems, Inc. to assist in its use, correction,
175 * modification or enhancement.
176 *
177 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
178 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
179 * OR ANY PART THEREOF.
180 *
181 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
182 * or profits or other special, indirect and consequential damages, even if
183 * Sun has been advised of the possibility of such damages.
184 *
185 * Sun Microsystems, Inc.
186 * 2550 Garcia Avenue
187 * Mountain View, California 94043
188 */
189
190 /*
191 * g711.c
192 *
193 * u-law, A-law and linear PCM conversions.
194 */
195
196 /*
197 * December 30, 1994:
198 * Functions linear2alaw, linear2ulaw have been updated to correctly
199 * convert unquantized 16 bit values.
200 * Tables for direct u- to A-law and A- to u-law conversions have been
201 * corrected.
202 * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
203 * bli@cpk.auc.dk
204 *
205 */
206
207 #define SIGN_BIT (0x80) /* Sign bit for an A-law byte. */
208 #define QUANT_MASK (0xf) /* Quantization field mask. */
209 #define NSEGS (8) /* Number of A-law segments. */
210 #define SEG_SHIFT (4) /* Left shift for segment number. */
211 #define SEG_MASK (0x70) /* Segment field mask. */
212
213 static const short seg_aend[8] = {0x1F, 0x3F, 0x7F, 0x0FF, 0x1FF, 0x3FF, 0x7FF, 0x0FFF};
214 static const short seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
215
216 /* copy from CCITT G.711 specifications */
217 static const 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 const 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 const 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 const 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 inline int
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 const 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 = MM_MICROSOFT;
659 add->wPid = MM_MSFT_ACM_G711;
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, "Microsoft CCITT G.711", -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 through */
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 %08x\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 %08x\n", afd->dwFormatTag);
783 return MMSYSERR_INVALPARAM;
784 }
785 break;
786 default:
787 WARN("Unsupported query %08x\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 * 2;
838 adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
839 break;
840 case WAVE_FORMAT_ALAW:
841 adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels;
842 adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels;
843 break;
844 case WAVE_FORMAT_MULAW:
845 adfs->pwfxDst->nBlockAlign = adfs->pwfxDst->nChannels;
846 adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxSrc->nChannels;
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_PTR)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_StreamSize
986 *
987 */
988 static LRESULT G711_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
989 {
990 switch (adss->fdwSize)
991 {
992 case ACM_STREAMSIZEF_DESTINATION:
993 /* cbDstLength => cbSrcLength */
994 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
995 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
996 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
997 {
998 adss->cbSrcLength = adss->cbDstLength * 2;
999 }
1000 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1001 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1002 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
1003 {
1004 adss->cbSrcLength = adss->cbDstLength / 2;
1005 }
1006 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1007 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1008 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
1009 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
1010 {
1011 adss->cbSrcLength = adss->cbDstLength;
1012 }
1013 else
1014 {
1015 return MMSYSERR_NOTSUPPORTED;
1016 }
1017 break;
1018 case ACM_STREAMSIZEF_SOURCE:
1019 /* cbSrcLength => cbDstLength */
1020 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
1021 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
1022 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
1023 {
1024 adss->cbDstLength = adss->cbSrcLength / 2;
1025 }
1026 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1027 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1028 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
1029 {
1030 adss->cbDstLength = adss->cbSrcLength * 2;
1031 }
1032 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_ALAW ||
1033 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MULAW) &&
1034 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_ALAW ||
1035 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MULAW))
1036 {
1037 adss->cbDstLength = adss->cbSrcLength;
1038 }
1039 else
1040 {
1041 return MMSYSERR_NOTSUPPORTED;
1042 }
1043 break;
1044 default:
1045 WARN("Unsupported query %08x\n", adss->fdwSize);
1046 return MMSYSERR_NOTSUPPORTED;
1047 }
1048 FIXME("\n");
1049 return MMSYSERR_NOERROR;
1050 }
1051
1052 /***********************************************************************
1053 * G711_StreamConvert
1054 *
1055 */
1056 static LRESULT G711_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
1057 {
1058 AcmG711Data* aad = (AcmG711Data*)adsi->dwDriver;
1059 DWORD nsrc = adsh->cbSrcLength;
1060 DWORD ndst = adsh->cbDstLength;
1061
1062 if (adsh->fdwConvert &
1063 ~(ACM_STREAMCONVERTF_BLOCKALIGN|
1064 ACM_STREAMCONVERTF_END|
1065 ACM_STREAMCONVERTF_START))
1066 {
1067 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
1068 }
1069 /* ACM_STREAMCONVERTF_BLOCKALIGN
1070 * currently all conversions are block aligned, so do nothing for this flag
1071 * ACM_STREAMCONVERTF_END
1072 * no pending data, so do nothing for this flag
1073 */
1074 if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
1075 {
1076 G711_Reset(adsi, aad);
1077 }
1078
1079 aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
1080 adsh->cbSrcLengthUsed = nsrc;
1081 adsh->cbDstLengthUsed = ndst;
1082
1083 return MMSYSERR_NOERROR;
1084 }
1085
1086 /**************************************************************************
1087 * G711_DriverProc [exported]
1088 */
1089 LRESULT CALLBACK G711_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
1090 LPARAM dwParam1, LPARAM dwParam2)
1091 {
1092 TRACE("(%08lx %p %04x %08lx %08lx);\n",
1093 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1094
1095 switch (wMsg)
1096 {
1097 case DRV_LOAD: return 1;
1098 case DRV_FREE: return 1;
1099 case DRV_OPEN: return G711_drvOpen((LPSTR)dwParam1);
1100 case DRV_CLOSE: return G711_drvClose(dwDevID);
1101 case DRV_ENABLE: return 1;
1102 case DRV_DISABLE: return 1;
1103 case DRV_QUERYCONFIGURE: return 1;
1104 case DRV_CONFIGURE: MessageBoxA(0, "MS G711 (a-Law & mu-Law) filter !", "Wine Driver", MB_OK); return 1;
1105 case DRV_INSTALL: return DRVCNF_RESTART;
1106 case DRV_REMOVE: return DRVCNF_RESTART;
1107
1108 case ACMDM_DRIVER_NOTIFY:
1109 /* no caching from other ACM drivers is done so far */
1110 return MMSYSERR_NOERROR;
1111
1112 case ACMDM_DRIVER_DETAILS:
1113 return G711_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1114
1115 case ACMDM_FORMATTAG_DETAILS:
1116 return G711_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
1117
1118 case ACMDM_FORMAT_DETAILS:
1119 return G711_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1120
1121 case ACMDM_FORMAT_SUGGEST:
1122 return G711_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
1123
1124 case ACMDM_STREAM_OPEN:
1125 return G711_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
1126
1127 case ACMDM_STREAM_CLOSE:
1128 return G711_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
1129
1130 case ACMDM_STREAM_SIZE:
1131 return G711_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
1132
1133 case ACMDM_STREAM_CONVERT:
1134 return G711_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
1135
1136 case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
1137 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
1138 /* this converter is not a hardware driver */
1139 case ACMDM_FILTERTAG_DETAILS:
1140 case ACMDM_FILTER_DETAILS:
1141 /* this converter is not a filter */
1142 case ACMDM_STREAM_RESET:
1143 /* only needed for asynchronous driver... we aren't, so just say it */
1144 return MMSYSERR_NOTSUPPORTED;
1145 case ACMDM_STREAM_PREPARE:
1146 case ACMDM_STREAM_UNPREPARE:
1147 /* nothing special to do here... so don't do anything */
1148 return MMSYSERR_NOERROR;
1149
1150 default:
1151 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1152 }
1153 }