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