ReactOS 0.4.15-dev-5666-gc548b97
imaadp32.c
Go to the documentation of this file.
1/*
2 * IMA ADPCM handling
3 *
4 * Copyright (C) 2001,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/* see http://www.pcisys.net/~melanson/codecs/adpcm.txt for the details */
37
39
40/***********************************************************************
41 * ADPCM_drvClose
42 */
44{
45 return 1;
46}
47
48typedef struct tagAcmAdpcmData
49{
51 const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
52 /* IMA encoding only */
55 /* short sample; */
57
58/* table to list all supported formats... those are the basic ones. this
59 * also helps given a unique index to each of the supported formats
60 */
61typedef struct
62{
64 int nBits;
65 int rate;
66} Format;
67
68static const Format PCM_Formats[] =
69{
70 {1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000},
71 {1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025},
72 {1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050},
73 {1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100},
74};
75
76static const Format ADPCM_Formats[] =
77{
78 {1, 4, 8000}, {2, 4, 8000}, {1, 4, 11025}, {2, 4, 11025},
79 {1, 4, 22050}, {2, 4, 22050}, {1, 4, 44100}, {2, 4, 44100},
80};
81
82/***********************************************************************
83 * ADPCM_GetFormatIndex
84 */
86{
87 int i, hi;
88 const Format* fmts;
89
90 switch (wfx->wFormatTag)
91 {
92 case WAVE_FORMAT_PCM:
95 break;
99 break;
100 default:
101 return 0xFFFFFFFF;
102 }
103
104 for (i = 0; i < hi; i++)
105 {
106 if (wfx->nChannels == fmts[i].nChannels &&
107 wfx->nSamplesPerSec == fmts[i].rate &&
108 wfx->wBitsPerSample == fmts[i].nBits)
109 return i;
110 }
111
112 switch (wfx->wFormatTag)
113 {
114 case WAVE_FORMAT_PCM:
115 if(3 > wfx->nChannels &&
116 wfx->nChannels > 0 &&
117 wfx->nAvgBytesPerSec == 2 * wfx->nSamplesPerSec * wfx->nChannels &&
118 wfx->nBlockAlign == 2 * wfx->nChannels &&
119 wfx->wBitsPerSample == 16)
120 return hi;
121 break;
123 if(3 > wfx->nChannels &&
124 wfx->nChannels > 0 &&
125 wfx->wBitsPerSample == 4 &&
126 wfx->cbSize == 2)
127 return hi;
128 break;
129 }
130
131 return 0xFFFFFFFF;
132}
133
134static void init_wfx_ima_adpcm(IMAADPCMWAVEFORMAT* awfx/*, DWORD nba*/)
135{
136 WAVEFORMATEX* pwfx = &awfx->wfx;
137
138 /* we assume wFormatTag, nChannels, nSamplesPerSec and wBitsPerSample
139 * have been initialized... */
140
141 if (pwfx->wFormatTag != WAVE_FORMAT_IMA_ADPCM) {FIXME("wrong FT\n"); return;}
142 if (ADPCM_GetFormatIndex(pwfx) == 0xFFFFFFFF) {FIXME("wrong fmt\n"); return;}
143
144 switch (pwfx->nSamplesPerSec)
145 {
146 case 8000: pwfx->nBlockAlign = 256 * pwfx->nChannels; break;
147 case 11025: pwfx->nBlockAlign = 256 * pwfx->nChannels; break;
148 case 22050: pwfx->nBlockAlign = 512 * pwfx->nChannels; break;
149 case 44100: pwfx->nBlockAlign = 1024 * pwfx->nChannels; break;
150 default: /*pwfx->nBlockAlign = nba;*/ break;
151 }
152 pwfx->cbSize = sizeof(WORD);
153
154 awfx->wSamplesPerBlock = (pwfx->nBlockAlign - (4 * pwfx->nChannels)) * (2 / pwfx->nChannels) + 1;
155 pwfx->nAvgBytesPerSec = (pwfx->nSamplesPerSec * pwfx->nBlockAlign) / awfx->wSamplesPerBlock;
156}
157
158/***********************************************************************
159 * R16
160 *
161 * Read a 16 bit sample (correctly handles endianness)
162 */
163static inline short R16(const unsigned char* src)
164{
165 return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
166}
167
168/***********************************************************************
169 * W16
170 *
171 * Write a 16 bit sample (correctly handles endianness)
172 */
173static inline void W16(unsigned char* dst, short s)
174{
175 dst[0] = LOBYTE(s);
176 dst[1] = HIBYTE(s);
177}
178
179/***********************************************************************
180 * W8
181 *
182 * Write a 8 bit sample
183 */
184static inline void W8(unsigned char* dst, short s)
185{
186 dst[0] = (unsigned char)((s + 32768) >> 8);
187}
188
189
190static inline void W8_16(unsigned char* dst, short s, int bytes)
191{
192 if(bytes == 1)
193 W8(dst, s);
194 else
195 W16(dst, s);
196}
197
198/* IMA (or DVI) APDCM codec routines */
199
200static const unsigned IMA_StepTable[89] =
201{
202 7, 8, 9, 10, 11, 12, 13, 14,
203 16, 17, 19, 21, 23, 25, 28, 31,
204 34, 37, 41, 45, 50, 55, 60, 66,
205 73, 80, 88, 97, 107, 118, 130, 143,
206 157, 173, 190, 209, 230, 253, 279, 307,
207 337, 371, 408, 449, 494, 544, 598, 658,
208 724, 796, 876, 963, 1060, 1166, 1282, 1411,
209 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024,
210 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484,
211 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
212 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794,
213 32767
214};
215
216static const int IMA_IndexTable[16] =
217{
218 -1, -1, -1, -1, 2, 4, 6, 8,
219 -1, -1, -1, -1, 2, 4, 6, 8
220};
221
222static inline void clamp_step_index(int* stepIndex)
223{
224 if (*stepIndex < 0 ) *stepIndex = 0;
225 if (*stepIndex > 88) *stepIndex = 88;
226}
227
228static inline void clamp_sample(int* sample)
229{
230 if (*sample < -32768) *sample = -32768;
231 if (*sample > 32767) *sample = 32767;
232}
233
234static inline void process_nibble(unsigned char code, int* stepIndex, int* sample)
235{
236 unsigned step;
237 int diff;
238
239 code &= 0x0F;
240
241 step = IMA_StepTable[*stepIndex];
242 diff = step >> 3;
243 if (code & 1) diff += step >> 2;
244 if (code & 2) diff += step >> 1;
245 if (code & 4) diff += step;
246 if (code & 8) *sample -= diff;
247 else *sample += diff;
248 clamp_sample(sample);
249 *stepIndex += IMA_IndexTable[code];
250 clamp_step_index(stepIndex);
251}
252
253static inline unsigned char generate_nibble(int in, int* stepIndex, int* sample)
254{
255 int effdiff, diff = in - *sample;
256 unsigned step;
257 unsigned char code;
258
259 if (diff < 0)
260 {
261 diff = -diff;
262 code = 8;
263 }
264 else
265 {
266 code = 0;
267 }
268
269 step = IMA_StepTable[*stepIndex];
270 effdiff = (step >> 3);
271 if (diff >= step)
272 {
273 code |= 4;
274 diff -= step;
275 effdiff += step;
276 }
277 step >>= 1;
278 if (diff >= step)
279 {
280 code |= 2;
281 diff -= step;
282 effdiff += step;
283 }
284 step >>= 1;
285 if (diff >= step)
286 {
287 code |= 1;
288 effdiff += step;
289 }
290 if (code & 8) *sample -= effdiff;
291 else *sample += effdiff;
292 clamp_sample(sample);
293 *stepIndex += IMA_IndexTable[code];
294 clamp_step_index(stepIndex);
295 return code;
296}
297
299 const unsigned char* src, LPDWORD nsrc,
300 unsigned char* dst, LPDWORD ndst)
301{
302 int i;
303 int sampleL, sampleR;
304 int stepIndexL, stepIndexR;
305 int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
306 int nsamp;
307 /* compute the number of entire blocks we can decode...
308 * it's the min of the number of entire blocks in source buffer and the number
309 * of entire blocks in destination buffer
310 */
311 DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign,
312 *ndst / (nsamp_blk * 2 * 2));
313
314 *nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
315 *ndst = nblock * (nsamp_blk * 2 * 2);
316
317 nsamp_blk--; /* remove the sample in block header */
318 for (; nblock > 0; nblock--)
319 {
320 const unsigned char* in_src = src;
321
322 /* handle headers first */
323 sampleL = R16(src);
324 stepIndexL = (unsigned)*(src + 2);
325 clamp_step_index(&stepIndexL);
326 src += 4;
327 W16(dst, sampleL); dst += 2;
328
329 sampleR = R16(src);
330 stepIndexR = (unsigned)*(src + 2);
331 clamp_step_index(&stepIndexR);
332 src += 4;
333 W16(dst, sampleR); dst += 2;
334
335 for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8)
336 {
337 for (i = 0; i < 4; i++)
338 {
339 process_nibble(*src, &stepIndexL, &sampleL);
340 W16(dst + (2 * i + 0) * 4 + 0, sampleL);
341 process_nibble(*src++ >> 4, &stepIndexL, &sampleL);
342 W16(dst + (2 * i + 1) * 4 + 0, sampleL);
343 }
344 for (i = 0; i < 4; i++)
345 {
346 process_nibble(*src , &stepIndexR, &sampleR);
347 W16(dst + (2 * i + 0) * 4 + 2, sampleR);
348 process_nibble(*src++ >>4, &stepIndexR, &sampleR);
349 W16(dst + (2 * i + 1) * 4 + 2, sampleR);
350 }
351 dst += 32;
352 }
353 /* we have now to realign the source pointer on block */
354 src = in_src + adsi->pwfxSrc->nBlockAlign;
355 }
356}
357
359 const unsigned char* src, LPDWORD nsrc,
360 unsigned char* dst, LPDWORD ndst)
361{
362 int sample;
363 int stepIndex;
364 int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
365 int nsamp;
366 int bytesPerSample = adsi->pwfxDst->wBitsPerSample / 8;
367 /* compute the number of entire blocks we can decode...
368 * it's the min of the number of entire blocks in source buffer and the number
369 * of entire blocks in destination buffer
370 */
371 DWORD nblock = min(*nsrc / adsi->pwfxSrc->nBlockAlign, *ndst / (nsamp_blk * bytesPerSample));
372
373 *nsrc = nblock * adsi->pwfxSrc->nBlockAlign;
374 *ndst = nblock * nsamp_blk * bytesPerSample;
375
376 nsamp_blk--; /* remove the sample in block header */
377 for (; nblock > 0; nblock--)
378 {
379 const unsigned char* in_src = src;
380
381 /* handle header first */
382 sample = R16(src);
383 stepIndex = (unsigned)*(src + 2);
384 clamp_step_index(&stepIndex);
385 src += 4;
386 W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
387
388 for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
389 {
390 process_nibble(*src, &stepIndex, &sample);
391 W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
392 process_nibble(*src++ >> 4, &stepIndex, &sample);
393 W8_16(dst, sample, bytesPerSample); dst += bytesPerSample;
394 }
395 /* we have now to realign the source pointer on block */
396 src = in_src + adsi->pwfxSrc->nBlockAlign;
397 }
398}
399
401 const unsigned char* src, LPDWORD nsrc,
402 unsigned char* dst, LPDWORD ndst)
403{
404 int stepIndexL, stepIndexR;
405 int sampleL, sampleR;
406 BYTE code1, code2;
407 int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
408 int i, nsamp;
409 /* compute the number of entire blocks we can decode...
410 * it's the min of the number of entire blocks in source buffer and the number
411 * of entire blocks in destination buffer
412 */
413 DWORD nblock = min(*nsrc / (nsamp_blk * 2 * 2),
414 *ndst / adsi->pwfxDst->nBlockAlign);
415
416 *nsrc = nblock * (nsamp_blk * 2 * 2);
417 *ndst = nblock * adsi->pwfxDst->nBlockAlign;
418
419 stepIndexL = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL;
420 stepIndexR = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR;
421
422 nsamp_blk--; /* so that we won't count the sample in header while filling the block */
423
424 for (; nblock > 0; nblock--)
425 {
426 unsigned char* in_dst = dst;
427
428 /* generate header */
429 sampleL = R16(src); src += 2;
430 W16(dst, sampleL); dst += 2;
431 W16(dst, stepIndexL); dst += 2;
432
433 sampleR = R16(src); src += 2;
434 W16(dst, sampleR); dst += 2;
435 W16(dst, stepIndexR); dst += 2;
436
437 for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 8)
438 {
439 for (i = 0; i < 4; i++)
440 {
441 code1 = generate_nibble(R16(src + (4 * i + 0) * 2),
442 &stepIndexL, &sampleL);
443 code2 = generate_nibble(R16(src + (4 * i + 2) * 2),
444 &stepIndexL, &sampleL);
445 *dst++ = (code2 << 4) | code1;
446 }
447 for (i = 0; i < 4; i++)
448 {
449 code1 = generate_nibble(R16(src + (4 * i + 1) * 2),
450 &stepIndexR, &sampleR);
451 code2 = generate_nibble(R16(src + (4 * i + 3) * 2),
452 &stepIndexR, &sampleR);
453 *dst++ = (code2 << 4) | code1;
454 }
455 src += 32;
456 }
457 dst = in_dst + adsi->pwfxDst->nBlockAlign;
458 }
459 ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndexL;
460 ((AcmAdpcmData*)adsi->dwDriver)->stepIndexR = stepIndexR;
461}
462
464 const unsigned char* src, LPDWORD nsrc,
465 unsigned char* dst, LPDWORD ndst)
466{
467 int stepIndex;
468 int sample;
469 BYTE code1, code2;
470 int nsamp_blk = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
471 int nsamp;
472 /* compute the number of entire blocks we can decode...
473 * it's the min of the number of entire blocks in source buffer and the number
474 * of entire blocks in destination buffer
475 */
476 DWORD nblock = min(*nsrc / (nsamp_blk * 2),
477 *ndst / adsi->pwfxDst->nBlockAlign);
478
479 *nsrc = nblock * (nsamp_blk * 2);
480 *ndst = nblock * adsi->pwfxDst->nBlockAlign;
481
482 stepIndex = ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL;
483 nsamp_blk--; /* so that we won't count the sample in header while filling the block */
484
485 for (; nblock > 0; nblock--)
486 {
487 unsigned char* in_dst = dst;
488
489 /* generate header */
490 /* FIXME: what about the last effective sample from previous block ??? */
491 /* perhaps something like:
492 * sample += R16(src);
493 * clamp_sample(sample);
494 * and with :
495 * + saving the sample in adsi->dwDriver when all blocks are done
496 + + reset should set the field in adsi->dwDriver to 0 too
497 */
498 sample = R16(src); src += 2;
499 W16(dst, sample); dst += 2;
500 *dst = (unsigned char)(unsigned)stepIndex;
501 dst += 2;
502
503 for (nsamp = nsamp_blk; nsamp > 0; nsamp -= 2)
504 {
505 code1 = generate_nibble(R16(src), &stepIndex, &sample);
506 src += 2;
507 code2 = generate_nibble(R16(src), &stepIndex, &sample);
508 src += 2;
509 *dst++ = (code2 << 4) | code1;
510 }
511 dst = in_dst + adsi->pwfxDst->nBlockAlign;
512 }
513 ((AcmAdpcmData*)adsi->dwDriver)->stepIndexL = stepIndex;
514}
515
516/***********************************************************************
517 * ADPCM_DriverDetails
518 *
519 */
521{
524 add->wMid = MM_MICROSOFT;
526 add->vdwACM = 0x3320000;
527 add->vdwDriver = 0x04000000;
529 add->cFormatTags = 2; /* PCM, IMA ADPCM */
530 add->cFilterTags = 0;
531 add->hicon = NULL;
532 MultiByteToWideChar( CP_ACP, 0, "Microsoft IMA ADPCM", -1,
533 add->szShortName, ARRAY_SIZE(add->szShortName) );
534 MultiByteToWideChar( CP_ACP, 0, "Microsoft IMA ADPCM CODEC", -1,
535 add->szLongName, ARRAY_SIZE(add->szLongName) );
536 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
537 add->szCopyright, ARRAY_SIZE(add->szCopyright) );
538 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
539 add->szLicensing, ARRAY_SIZE(add->szLicensing) );
540 add->szFeatures[0] = 0;
541
542 return MMSYSERR_NOERROR;
543}
544
545/***********************************************************************
546 * ADPCM_FormatTagDetails
547 *
548 */
550{
551 static const WCHAR szPcm[]={'P','C','M',0};
552 static const WCHAR szImaAdPcm[]={'I','M','A',' ','A','D','P','C','M',0};
553
554 switch (dwQuery)
555 {
557 if (aftd->dwFormatTagIndex >= 2) return ACMERR_NOTPOSSIBLE;
558 break;
560 if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
561 {
562 aftd->dwFormatTagIndex = 1; /* WAVE_FORMAT_IMA_ADPCM is bigger than PCM */
563 break;
564 }
565 /* fall through */
567 switch (aftd->dwFormatTag)
568 {
569 case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
570 case WAVE_FORMAT_IMA_ADPCM: aftd->dwFormatTagIndex = 1; break;
571 default: return ACMERR_NOTPOSSIBLE;
572 }
573 break;
574 default:
575 WARN("Unsupported query %08x\n", dwQuery);
577 }
578
580 switch (aftd->dwFormatTagIndex)
581 {
582 case 0:
584 aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
586 lstrcpyW(aftd->szFormatTag, szPcm);
587 break;
588 case 1:
590 aftd->cbFormatSize = sizeof(IMAADPCMWAVEFORMAT);
592 lstrcpyW(aftd->szFormatTag, szImaAdPcm);
593 break;
594 }
595 return MMSYSERR_NOERROR;
596}
597
598/***********************************************************************
599 * ADPCM_FormatDetails
600 *
601 */
603{
604 switch (dwQuery)
605 {
607 if (ADPCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
608 break;
610 afd->pwfx->wFormatTag = afd->dwFormatTag;
611 switch (afd->dwFormatTag)
612 {
613 case WAVE_FORMAT_PCM:
618 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
619 * afd->pwfx->cbSize = 0;
620 */
621 afd->pwfx->nBlockAlign =
622 (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
623 afd->pwfx->nAvgBytesPerSec =
624 afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
625 break;
632 break;
633 default:
634 WARN("Unsupported tag %08x\n", afd->dwFormatTag);
635 return MMSYSERR_INVALPARAM;
636 }
637 break;
638 default:
639 WARN("Unsupported query %08x\n", dwQuery);
641 }
643 afd->szFormat[0] = 0; /* let MSACM format this for us... */
644
645 return MMSYSERR_NOERROR;
646}
647
648/***********************************************************************
649 * ADPCM_FormatSuggest
650 *
651 */
653{
654 /* some tests ... */
655 if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
656 adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
657 adfs->pwfxSrc->wFormatTag == adfs->pwfxDst->wFormatTag ||
658 ADPCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
659
660 /* If no suggestion for destination, then copy source value */
662 adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
665
667 {
668 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
669 adfs->pwfxDst->wBitsPerSample = 4;
670 else
671 adfs->pwfxDst->wBitsPerSample = 16;
672 }
674 {
675 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
677 else
679 }
680
681 /* recompute other values */
682 switch (adfs->pwfxDst->wFormatTag)
683 {
684 case WAVE_FORMAT_PCM:
685 if (adfs->cbwfxSrc < sizeof(IMAADPCMWAVEFORMAT)) return ACMERR_NOTPOSSIBLE;
686 adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
688 /* check if result is ok */
689 if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
690 break;
692 if (adfs->cbwfxDst < sizeof(IMAADPCMWAVEFORMAT)) return ACMERR_NOTPOSSIBLE;
694 /* FIXME: not handling header overhead */
695 TRACE("setting spb=%u\n", ((IMAADPCMWAVEFORMAT*)adfs->pwfxDst)->wSamplesPerBlock);
696 /* check if result is ok */
697 if (ADPCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
698 break;
699 default:
700 return ACMERR_NOTPOSSIBLE;
701 }
702
703 return MMSYSERR_NOERROR;
704}
705
706/***********************************************************************
707 * ADPCM_Reset
708 *
709 */
711{
712 aad->stepIndexL = aad->stepIndexR = 0;
713}
714
715/***********************************************************************
716 * ADPCM_StreamOpen
717 *
718 */
720{
721 AcmAdpcmData* aad;
722 unsigned nspb;
723
725
726 if (ADPCM_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
727 ADPCM_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
728 return ACMERR_NOTPOSSIBLE;
729
730 aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmAdpcmData));
731 if (aad == 0) return MMSYSERR_NOMEM;
732
733 adsi->dwDriver = (DWORD_PTR)aad;
734
735 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
737 {
738 goto theEnd;
739 }
740 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
742 {
743 /* resampling or mono <=> stereo not available
744 * ADPCM algo only define 16 bit per sample output
745 * (The API seems to still allow 8 bit per sample output)
746 */
747 if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
748 adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
749 (adsi->pwfxDst->wBitsPerSample != 16 && adsi->pwfxDst->wBitsPerSample != 8))
750 goto theEnd;
751
752 nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxSrc)->wSamplesPerBlock;
753 TRACE("spb=%u\n", nspb);
754
755 /* we check that in a block, after the header, samples are present on
756 * 4-sample packet pattern
757 * we also check that the block alignment is bigger than the expected size
758 */
759 if (((nspb - 1) & 3) != 0) goto theEnd;
760 if ((((nspb - 1) / 2) + 4) * adsi->pwfxSrc->nChannels < adsi->pwfxSrc->nBlockAlign)
761 goto theEnd;
762
763 /* adpcm decoding... */
764 if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 2)
765 aad->convert = cvtSSima16K;
766 if (adsi->pwfxDst->wBitsPerSample == 16 && adsi->pwfxDst->nChannels == 1)
767 aad->convert = cvtMMimaK;
768 if (adsi->pwfxDst->wBitsPerSample == 8 && adsi->pwfxDst->nChannels == 1)
769 aad->convert = cvtMMimaK;
770 /* FIXME: Stereo support for 8bit samples*/
771 if (adsi->pwfxDst->wBitsPerSample == 8 && adsi->pwfxDst->nChannels == 2)
772 goto theEnd;
773 }
774 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
776 {
777 if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
778 adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
779 adsi->pwfxSrc->wBitsPerSample != 16)
780 goto theEnd;
781
782 nspb = ((LPIMAADPCMWAVEFORMAT)adsi->pwfxDst)->wSamplesPerBlock;
783 TRACE("spb=%u\n", nspb);
784
785 /* we check that in a block, after the header, samples are present on
786 * 4-sample packet pattern
787 * we also check that the block alignment is bigger than the expected size
788 */
789 if (((nspb - 1) & 3) != 0) goto theEnd;
790 if ((((nspb - 1) / 2) + 4) * adsi->pwfxDst->nChannels < adsi->pwfxDst->nBlockAlign)
791 goto theEnd;
792
793 /* adpcm coding... */
794 if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 2)
795 aad->convert = cvtSS16imaK;
796 if (adsi->pwfxSrc->wBitsPerSample == 16 && adsi->pwfxSrc->nChannels == 1)
797 aad->convert = cvtMM16imaK;
798 }
799 else goto theEnd;
800 ADPCM_Reset(adsi, aad);
801
802 return MMSYSERR_NOERROR;
803
804 theEnd:
805 HeapFree(GetProcessHeap(), 0, aad);
806 adsi->dwDriver = 0L;
808}
809
810/***********************************************************************
811 * ADPCM_StreamClose
812 *
813 */
815{
816 HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
817 return MMSYSERR_NOERROR;
818}
819
820/***********************************************************************
821 * ADPCM_StreamSize
822 *
823 */
825{
826 DWORD nblocks;
827
828 switch (adss->fdwSize)
829 {
831 /* cbDstLength => cbSrcLength */
832 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
834 {
835 nblocks = adss->cbDstLength / adsi->pwfxDst->nBlockAlign;
836 if (nblocks == 0)
837 return ACMERR_NOTPOSSIBLE;
838 adss->cbSrcLength = nblocks * adsi->pwfxSrc->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock;
839 }
840 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
842 {
843 nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock);
844 if (nblocks == 0)
845 return ACMERR_NOTPOSSIBLE;
846 adss->cbSrcLength = nblocks * adsi->pwfxSrc->nBlockAlign;
847 }
848 else
849 {
851 }
852 break;
854 /* cbSrcLength => cbDstLength */
855 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
857 {
858 nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock);
859 if (nblocks == 0)
860 return ACMERR_NOTPOSSIBLE;
861 if (adss->cbSrcLength % (adsi->pwfxSrc->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxDst)->wSamplesPerBlock))
862 /* Round block count up. */
863 nblocks++;
864 adss->cbDstLength = nblocks * adsi->pwfxDst->nBlockAlign;
865 }
866 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_IMA_ADPCM &&
868 {
869 nblocks = adss->cbSrcLength / adsi->pwfxSrc->nBlockAlign;
870 if (nblocks == 0)
871 return ACMERR_NOTPOSSIBLE;
872 if (adss->cbSrcLength % adsi->pwfxSrc->nBlockAlign)
873 /* Round block count up. */
874 nblocks++;
875 adss->cbDstLength = nblocks * adsi->pwfxDst->nBlockAlign * ((IMAADPCMWAVEFORMAT*)adsi->pwfxSrc)->wSamplesPerBlock;
876 }
877 else
878 {
880 }
881 break;
882 default:
883 WARN("Unsupported query %08x\n", adss->fdwSize);
885 }
886 return MMSYSERR_NOERROR;
887}
888
889/***********************************************************************
890 * ADPCM_StreamConvert
891 *
892 */
894{
895 AcmAdpcmData* aad = (AcmAdpcmData*)adsi->dwDriver;
896 DWORD nsrc = adsh->cbSrcLength;
897 DWORD ndst = adsh->cbDstLength;
898
899 if (adsh->fdwConvert &
903 {
904 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
905 }
906 /* ACM_STREAMCONVERTF_BLOCKALIGN
907 * currently all conversions are block aligned, so do nothing for this flag
908 * ACM_STREAMCONVERTF_END
909 * no pending data, so do nothing for this flag
910 */
912 {
913 ADPCM_Reset(adsi, aad);
914 }
915
916 aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
917 adsh->cbSrcLengthUsed = nsrc;
918 adsh->cbDstLengthUsed = ndst;
919
920 return MMSYSERR_NOERROR;
921}
922
923/**************************************************************************
924 * ADPCM_DriverProc [exported]
925 */
926LRESULT CALLBACK ADPCM_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
927 LPARAM dwParam1, LPARAM dwParam2)
928{
929 TRACE("(%08lx %p %04x %08lx %08lx);\n",
930 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
931
932 switch (wMsg)
933 {
934 case DRV_LOAD: return 1;
935 case DRV_FREE: return 1;
936 case DRV_OPEN: return 1;
937 case DRV_CLOSE: return ADPCM_drvClose(dwDevID);
938 case DRV_ENABLE: return 1;
939 case DRV_DISABLE: return 1;
940 case DRV_QUERYCONFIGURE: return 1;
941 case DRV_CONFIGURE: MessageBoxA(0, "MSACM IMA ADPCM filter !", "Wine Driver", MB_OK); return 1;
942 case DRV_INSTALL: return DRVCNF_RESTART;
943 case DRV_REMOVE: return DRVCNF_RESTART;
944
946 /* no caching from other ACM drivers is done so far */
947 return MMSYSERR_NOERROR;
948
950 return ADPCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
951
953 return ADPCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
954
956 return ADPCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
957
960
962 return ADPCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
963
966
968 return ADPCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
969
972
975 /* this converter is not a hardware driver */
978 /* this converter is not a filter */
980 /* only needed for asynchronous driver... we aren't, so just say it */
984 /* nothing special to do here... so don't do anything */
985 return MMSYSERR_NOERROR;
986
987 default:
988 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
989 }
990}
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define WAVE_FORMAT_PCM
Definition: constants.h:425
#define ARRAY_SIZE(a)
Definition: main.h:24
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
unsigned char
Definition: typeof.h:29
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
#define assert(x)
Definition: debug.h:53
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
GLdouble s
Definition: gl.h:2039
GLenum src
Definition: glext.h:6340
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DRV_LOAD(x)
static void clamp_step_index(int *stepIndex)
Definition: imaadp32.c:222
LRESULT CALLBACK ADPCM_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
Definition: imaadp32.c:926
static void W8_16(unsigned char *dst, short s, int bytes)
Definition: imaadp32.c:190
static const unsigned IMA_StepTable[89]
Definition: imaadp32.c:200
struct tagAcmAdpcmData AcmAdpcmData
static LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
Definition: imaadp32.c:652
static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
Definition: imaadp32.c:814
static const Format ADPCM_Formats[]
Definition: imaadp32.c:76
static void cvtMMimaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:358
static void init_wfx_ima_adpcm(IMAADPCMWAVEFORMAT *awfx)
Definition: imaadp32.c:134
static void cvtSSima16K(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:298
static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
Definition: imaadp32.c:719
static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData *aad)
Definition: imaadp32.c:710
static void W8(unsigned char *dst, short s)
Definition: imaadp32.c:184
static LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
Definition: imaadp32.c:549
static void clamp_sample(int *sample)
Definition: imaadp32.c:228
static void W16(unsigned char *dst, short s)
Definition: imaadp32.c:173
static const int IMA_IndexTable[16]
Definition: imaadp32.c:216
static void process_nibble(unsigned char code, int *stepIndex, int *sample)
Definition: imaadp32.c:234
static unsigned char generate_nibble(int in, int *stepIndex, int *sample)
Definition: imaadp32.c:253
static void cvtMM16imaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:463
static LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
Definition: imaadp32.c:520
static void cvtSS16imaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:400
static LRESULT ADPCM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
Definition: imaadp32.c:824
static LRESULT ADPCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
Definition: imaadp32.c:893
static DWORD ADPCM_GetFormatIndex(const WAVEFORMATEX *wfx)
Definition: imaadp32.c:85
static LRESULT ADPCM_drvClose(DWORD_PTR dwDevID)
Definition: imaadp32.c:43
static const Format PCM_Formats[]
Definition: imaadp32.c:68
static LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
Definition: imaadp32.c:602
static short R16(const unsigned char *src)
Definition: imaadp32.c:163
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
if(dx< 0)
Definition: linetemp.h:194
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:191
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
struct ima_adpcmwaveformat_tag IMAADPCMWAVEFORMAT
#define MM_MSFT_ACM_IMAADPCM
Definition: mmreg.h:147
#define MM_MICROSOFT
Definition: mmreg.h:144
#define DRV_CLOSE
Definition: mmsystem.h:122
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define DRV_ENABLE
Definition: mmsystem.h:120
#define DRV_CONFIGURE
Definition: mmsystem.h:125
#define DRV_OPEN
Definition: mmsystem.h:121
struct pcmwaveformat_tag PCMWAVEFORMAT
#define DRV_INSTALL
Definition: mmsystem.h:127
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define DRV_FREE
Definition: mmsystem.h:124
#define DRV_DISABLE
Definition: mmsystem.h:123
static struct fmt fmts[]
static unsigned(__cdecl *hash_bstr)(bstr_t s)
#define min(a, b)
Definition: monoChain.cc:55
#define ACM_STREAMCONVERTF_START
Definition: msacm.h:206
#define ACM_FORMATTAGDETAILSF_FORMATTAG
Definition: msacm.h:183
#define ACM_STREAMCONVERTF_BLOCKALIGN
Definition: msacm.h:205
#define ACM_STREAMOPENF_ASYNC
Definition: msacm.h:214
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
Definition: msacm.h:59
#define ACM_FORMATSUGGESTF_WFORMATTAG
Definition: msacm.h:174
#define ACM_FORMATSUGGESTF_NCHANNELS
Definition: msacm.h:175
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
#define ACM_FORMATDETAILSF_FORMAT
Definition: msacm.h:161
#define ACM_STREAMSIZEF_SOURCE
Definition: msacm.h:217
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE
Definition: msacm.h:184
#define ACM_STREAMSIZEF_DESTINATION
Definition: msacm.h:218
#define ACM_FORMATDETAILSF_INDEX
Definition: msacm.h:160
#define ACM_FORMATTAGDETAILSF_INDEX
Definition: msacm.h:182
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE
Definition: msacm.h:177
#define ACM_STREAMCONVERTF_END
Definition: msacm.h:207
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
Definition: msacm.h:58
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC
Definition: msacm.h:176
#define ACMDM_STREAM_PREPARE
Definition: msacmdrv.h:63
#define ACMDM_STREAM_CLOSE
Definition: msacmdrv.h:59
#define ACMDM_STREAM_CONVERT
Definition: msacmdrv.h:61
#define ACMDM_FORMAT_SUGGEST
Definition: msacmdrv.h:53
#define ACMDM_FILTER_DETAILS
Definition: msacmdrv.h:56
#define ACMDM_HARDWARE_WAVE_CAPS_INPUT
Definition: msacmdrv.h:48
#define ACMDM_DRIVER_NOTIFY
Definition: msacmdrv.h:45
#define ACMDM_FORMAT_DETAILS
Definition: msacmdrv.h:52
#define ACMDM_STREAM_SIZE
Definition: msacmdrv.h:60
#define ACMDM_FILTERTAG_DETAILS
Definition: msacmdrv.h:55
#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
Definition: msacmdrv.h:49
#define ACMDM_FORMATTAG_DETAILS
Definition: msacmdrv.h:51
#define ACMDM_STREAM_UNPREPARE
Definition: msacmdrv.h:64
#define ACMDM_STREAM_OPEN
Definition: msacmdrv.h:58
#define ACMDM_DRIVER_DETAILS
Definition: msacmdrv.h:46
#define ACMDM_STREAM_RESET
Definition: msacmdrv.h:62
unsigned int UINT
Definition: ndis.h:50
#define LPDWORD
Definition: nt_native.h:46
#define L(x)
Definition: ntvdm.h:50
#define TRACE(s)
Definition: solgame.cpp:4
int nChannels
Definition: imaadp32.c:63
int nBits
Definition: imaadp32.c:64
int rate
Definition: imaadp32.c:65
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
WORD wBitsPerSample
Definition: audioclient.idl:45
DWORD nSamplesPerSec
Definition: audioclient.idl:42
DWORD cFilterTags
Definition: msacm.h:311
WCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]
Definition: msacm.h:317
WCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]
Definition: msacm.h:316
WCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]
Definition: msacm.h:315
FOURCC fccComp
Definition: msacm.h:301
WCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]
Definition: msacm.h:318
FOURCC fccType
Definition: msacm.h:300
WCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]
Definition: msacm.h:319
DWORD cFormatTags
Definition: msacm.h:310
DWORD fdwSupport
Definition: msacm.h:309
DWORD vdwDriver
Definition: msacm.h:307
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:151
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:153
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]
Definition: msacm.h:509
DWORD dwFormatTag
Definition: msacm.h:505
DWORD dwFormatIndex
Definition: msacm.h:504
DWORD fdwSupport
Definition: msacm.h:506
PWAVEFORMATEX pwfx
Definition: msacm.h:507
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
Definition: msacm.h:535
DWORD dwFormatTagIndex
Definition: msacm.h:530
DWORD cStandardFormats
Definition: msacm.h:534
WORD nBlockAlign
Definition: mmreg.h:82
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nChannels
Definition: mmreg.h:79
WORD wFormatTag
Definition: mmreg.h:78
WORD wBitsPerSample
Definition: mmreg.h:83
Definition: inflate.c:139
WAVEFORMATEX wfx
Definition: mmreg.h:187
BYTE stepIndexR
Definition: imaadp32.c:54
void(* convert)(PACMDRVSTREAMINSTANCE adsi, const unsigned char *, LPDWORD, unsigned char *, LPDWORD)
Definition: imaadp32.c:50
BYTE stepIndexL
Definition: imaadp32.c:53
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t * LPDWORD
Definition: typedefs.h:59
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
int WINAPI MessageBoxA(_In_opt_ HWND hWnd, _In_opt_ LPCSTR lpText, _In_opt_ LPCSTR lpCaption, _In_ UINT uType)
#define MB_OK
Definition: winuser.h:784
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193