ReactOS  0.4.12-dev-375-g61fed54
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 
48 typedef struct tagAcmAdpcmData
49 {
51  const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
52  /* IMA encoding only */
55  /* short sample; */
56 } AcmAdpcmData;
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  */
61 typedef struct
62 {
63  int nChannels;
64  int nBits;
65  int rate;
66 } Format;
67 
68 static 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 
76 static 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:
93  hi = ARRAY_SIZE(PCM_Formats);
94  fmts = PCM_Formats;
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 
134 static 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  */
163 static 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  */
173 static 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  */
184 static inline void W8(unsigned char* dst, short s)
185 {
186  dst[0] = (unsigned char)((s + 32768) >> 8);
187 }
188 
189 
190 static 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 
200 static 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 
216 static 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 
222 static inline void clamp_step_index(int* stepIndex)
223 {
224  if (*stepIndex < 0 ) *stepIndex = 0;
225  if (*stepIndex > 88) *stepIndex = 88;
226 }
227 
228 static inline void clamp_sample(int* sample)
229 {
230  if (*sample < -32768) *sample = -32768;
231  if (*sample > 32767) *sample = 32767;
232 }
233 
234 static 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 
253 static 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;
525  add->wPid = MM_MSFT_ACM_IMAADPCM;
526  add->vdwACM = 0x3320000;
527  add->vdwDriver = 0x04000000;
528  add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
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, sizeof(add->szShortName)/sizeof(WCHAR) );
534  MultiByteToWideChar( CP_ACP, 0, "Microsoft IMA ADPCM CODEC", -1,
535  add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
536  MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
537  add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
538  MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
539  add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
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);
576  return MMSYSERR_NOTSUPPORTED;
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);
640  return MMSYSERR_NOTSUPPORTED;
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;
807  return MMSYSERR_NOTSUPPORTED;
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  {
850  return MMSYSERR_NOTSUPPORTED;
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  {
879  return MMSYSERR_NOTSUPPORTED;
880  }
881  break;
882  default:
883  WARN("Unsupported query %08x\n", adss->fdwSize);
884  return MMSYSERR_NOTSUPPORTED;
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  */
911  if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
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  */
926 LRESULT 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 
945  case ACMDM_DRIVER_NOTIFY:
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 
959  return ADPCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
960 
961  case ACMDM_STREAM_OPEN:
962  return ADPCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
963 
964  case ACMDM_STREAM_CLOSE:
965  return ADPCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
966 
967  case ACMDM_STREAM_SIZE:
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 */
979  case ACMDM_STREAM_RESET:
980  /* only needed for asynchronous driver... we aren't, so just say it */
981  return MMSYSERR_NOTSUPPORTED;
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 }
PWAVEFORMATEX pwfx
Definition: msacm.h:507
#define DRV_DISABLE
Definition: mmsystem.h:123
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
int add
Definition: i386-dis.c:3122
static void ADPCM_Reset(PACMDRVSTREAMINSTANCE adsi, AcmAdpcmData *aad)
Definition: imaadp32.c:710
static void process_nibble(unsigned char code, int *stepIndex, int *sample)
Definition: imaadp32.c:234
#define ACM_STREAMSIZEF_DESTINATION
Definition: msacm.h:218
static LRESULT ADPCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
Definition: imaadp32.c:602
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC
Definition: msacm.h:176
#define DWORD_PTR
Definition: treelist.c:76
#define ACM_STREAMCONVERTF_BLOCKALIGN
Definition: msacm.h:205
struct tagAcmAdpcmData AcmAdpcmData
#define LOBYTE(W)
Definition: jmemdos.c:487
LRESULT CALLBACK ADPCM_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
Definition: imaadp32.c:926
__wchar_t WCHAR
Definition: xmlstorage.h:180
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:153
static void clamp_sample(int *sample)
Definition: imaadp32.c:228
#define CP_ACP
Definition: compat.h:99
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
static void cvtMM16imaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:463
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:111
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
static void cvtSSima16K(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:298
IMAADPCMWAVEFORMAT * LPIMAADPCMWAVEFORMAT
Definition: mmreg.h:190
#define ACMDM_STREAM_RESET
Definition: msacmdrv.h:62
static const unsigned IMA_StepTable[89]
Definition: imaadp32.c:200
#define CALLBACK
Definition: compat.h:27
#define HIBYTE(W)
Definition: jmemdos.c:486
#define ACM_FORMATSUGGESTF_WFORMATTAG
Definition: msacm.h:174
int nChannels
Definition: imaadp32.c:63
#define assert(x)
Definition: debug.h:53
#define DRV_CLOSE
Definition: mmsystem.h:122
int nBits
Definition: imaadp32.c:64
WINE_DEFAULT_DEBUG_CHANNEL(adpcm)
#define ACMDM_STREAM_OPEN
Definition: msacmdrv.h:58
static void init_wfx_ima_adpcm(IMAADPCMWAVEFORMAT *awfx)
Definition: imaadp32.c:134
#define ACMDM_FORMATTAG_DETAILS
Definition: msacmdrv.h:51
static const Format ADPCM_Formats[]
Definition: imaadp32.c:76
#define ACMDM_STREAM_PREPARE
Definition: msacmdrv.h:63
struct pcmwaveformat_tag PCMWAVEFORMAT
#define ACM_STREAMCONVERTF_END
Definition: msacm.h:207
#define ACMDM_STREAM_CLOSE
Definition: msacmdrv.h:59
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_OPEN
Definition: mmsystem.h:121
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
static unsigned char generate_nibble(int in, int *stepIndex, int *sample)
Definition: imaadp32.c:253
#define ACMDM_DRIVER_NOTIFY
Definition: msacmdrv.h:45
#define ACMDM_FORMAT_SUGGEST
Definition: msacmdrv.h:53
GLuint const GLubyte GLvoid * src
Definition: s_context.h:57
static LRESULT ADPCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
Definition: imaadp32.c:652
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:91
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define WAVE_FORMAT_PCM
Definition: constants.h:425
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define ACM_FORMATDETAILSF_FORMAT
Definition: msacm.h:161
#define ACMDM_DRIVER_DETAILS
Definition: msacmdrv.h:46
LONG_PTR LPARAM
Definition: windef.h:208
#define ACMDM_STREAM_CONVERT
Definition: msacmdrv.h:61
#define FIXME(fmt,...)
Definition: debug.h:110
WORD wBitsPerSample
Definition: audioclient.idl:45
static const int IMA_IndexTable[16]
Definition: imaadp32.c:216
static struct fmt fmts[]
DWORD cStandardFormats
Definition: msacm.h:534
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
Definition: msacm.h:59
smooth NULL
Definition: ftsmooth.c:416
unsigned char
Definition: typeof.h:27
#define ACM_FORMATSUGGESTF_NCHANNELS
Definition: msacm.h:175
#define DRV_LOAD(x)
static void cvtMMimaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:358
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
DWORD nSamplesPerSec
Definition: audioclient.idl:42
#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
Definition: msacmdrv.h:49
#define ACMDM_HARDWARE_WAVE_CAPS_INPUT
Definition: msacmdrv.h:48
static LRESULT ADPCM_DriverDetails(PACMDRIVERDETAILSW add)
Definition: imaadp32.c:520
void(* convert)(PACMDRVSTREAMINSTANCE adsi, const unsigned char *, LPDWORD, unsigned char *, LPDWORD)
Definition: imaadp32.c:50
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
#define TRACE(s)
Definition: solgame.cpp:4
#define ACM_FORMATTAGDETAILSF_FORMATTAG
Definition: msacm.h:183
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static void W16(unsigned char *dst, short s)
Definition: imaadp32.c:173
#define DRV_CONFIGURE
Definition: mmsystem.h:125
if(!(yy_init))
Definition: macro.lex.yy.c:717
#define WAVE_FORMAT_IMA_ADPCM
Definition: mmreg.h:103
#define ACM_STREAMSIZEF_SOURCE
Definition: msacm.h:217
#define ACM_FORMATTAGDETAILSF_INDEX
Definition: msacm.h:182
static LRESULT ADPCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
Definition: imaadp32.c:814
unsigned int UINT
Definition: ndis.h:50
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned long DWORD
Definition: ntddk_ex.h:95
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]
Definition: msacm.h:509
#define ACM_STREAMOPENF_ASYNC
Definition: msacm.h:214
static void cvtSS16imaK(PACMDRVSTREAMINSTANCE adsi, const unsigned char *src, LPDWORD nsrc, unsigned char *dst, LPDWORD ndst)
Definition: imaadp32.c:400
#define DRV_FREE
Definition: mmsystem.h:124
BYTE stepIndexL
Definition: imaadp32.c:53
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MM_MSFT_ACM_IMAADPCM
Definition: mmreg.h:147
WORD wFormatTag
Definition: mmreg.h:78
#define ACMDM_FILTERTAG_DETAILS
Definition: msacmdrv.h:55
DWORD dwFormatIndex
Definition: msacm.h:504
#define LPDWORD
Definition: nt_native.h:46
static const WCHAR L[]
Definition: oid.c:1087
#define MM_MICROSOFT
Definition: mmreg.h:144
static LRESULT ADPCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
Definition: imaadp32.c:549
static void clamp_step_index(int *stepIndex)
Definition: imaadp32.c:222
unsigned char BYTE
Definition: mem.h:68
GLdouble s
Definition: gl.h:2039
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE
Definition: msacm.h:184
DWORD dwFormatTagIndex
Definition: msacm.h:530
uint32_t DWORD_PTR
Definition: typedefs.h:63
int code
Definition: i386-dis.c:3591
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
#define ACMDM_STREAM_UNPREPARE
Definition: msacmdrv.h:64
static void W8(unsigned char *dst, short s)
Definition: imaadp32.c:184
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
#define DRV_ENABLE
Definition: mmsystem.h:120
struct ima_adpcmwaveformat_tag IMAADPCMWAVEFORMAT
BYTE stepIndexR
Definition: imaadp32.c:54
static LRESULT ADPCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
Definition: imaadp32.c:893
#define ACM_STREAMCONVERTF_START
Definition: msacm.h:206
#define lstrcpyW
Definition: compat.h:406
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define ARRAY_SIZE(a)
Definition: main.h:24
DWORD fdwSupport
Definition: msacm.h:506
static LRESULT ADPCM_drvClose(DWORD_PTR dwDevID)
Definition: imaadp32.c:43
DWORD nAvgBytesPerSec
Definition: audioclient.idl:43
static const Format PCM_Formats[]
Definition: imaadp32.c:68
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:151
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
#define min(a, b)
Definition: monoChain.cc:55
#define MB_OK
Definition: winuser.h:784
static DWORD ADPCM_GetFormatIndex(const WAVEFORMATEX *wfx)
Definition: imaadp32.c:85
GLuint const GLubyte GLvoid const GLvoid * dst
Definition: s_context.h:57
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
Definition: msacm.h:535
#define MultiByteToWideChar
Definition: compat.h:100
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
#define ACM_FORMATDETAILSF_INDEX
Definition: msacm.h:160
int rate
Definition: imaadp32.c:65
static LRESULT ADPCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
Definition: imaadp32.c:719
uint32_t * LPDWORD
Definition: typedefs.h:57
WORD wBitsPerSample
Definition: mmreg.h:83
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
#define DRV_INSTALL
Definition: mmsystem.h:127
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
static short R16(const unsigned char *src)
Definition: imaadp32.c:163
LONG_PTR LRESULT
Definition: windef.h:209
DWORD dwFormatTag
Definition: msacm.h:505
static LRESULT ADPCM_StreamSize(const ACMDRVSTREAMINSTANCE *adsi, PACMDRVSTREAMSIZE adss)
Definition: imaadp32.c:824
#define HeapFree(x, y, z)
Definition: compat.h:394
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE
Definition: msacm.h:177
#define ACMDM_FORMAT_DETAILS
Definition: msacmdrv.h:52
WAVEFORMATEX wfx
Definition: mmreg.h:187
static void W8_16(unsigned char *dst, short s, int bytes)
Definition: imaadp32.c:190
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
Definition: msacm.h:58
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char * Format
Definition: acpixf.h:1202
#define ACMDM_STREAM_SIZE
Definition: msacmdrv.h:60
#define ACMDM_FILTER_DETAILS
Definition: msacmdrv.h:56