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