ReactOS 0.4.15-dev-7958-gcd0bb1a
pcmconverter.c
Go to the documentation of this file.
1/* -*- tab-width: 8; c-basic-offset: 4 -*- */
2
3/*
4 * MSACM32 library
5 *
6 * Copyright 2000 Eric Pouech
7 * Copyright 2004 Robert Reif
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 *
23 * FIXME / TODO list
24 * + get rid of hack for PCM_DriverProc (msacm32.dll shouldn't export
25 * a DriverProc, but this would require implementing a generic
26 * embedded driver handling scheme in msacm32.dll which isn't done yet
27 */
28
29
30#include <assert.h>
31#include <stdarg.h>
32#include <string.h>
33
34#include "windef.h"
35#include "winbase.h"
36#include "mmsystem.h"
37#define NOBITMAP
38#include "mmreg.h"
39#include "msacm.h"
40#include "wingdi.h"
41#include "winnls.h"
42#include "winuser.h"
43
44#include "msacmdrv.h"
45#include "wineacm.h"
46
47#include "wine/debug.h"
48
50
51/***********************************************************************
52 * PCM_drvOpen
53 */
55{
56 TRACE("(%p, %p)\n", str, adod);
57
58 return (adod == NULL) ||
61}
62
63/***********************************************************************
64 * PCM_drvClose
65 */
66static DWORD PCM_drvClose(DWORD dwDevID)
67{
68 TRACE("(%d)\n", dwDevID);
69
70 return 1;
71}
72
73#define NUM_OF(a,b) ((a)/(b))
74
75/* flags for fdwDriver */
76#define PCM_RESAMPLE 1
77
78typedef void (*PCM_CONVERT_KEEP_RATE)(const unsigned char*, int, unsigned char*);
79
80typedef void (*PCM_CONVERT_CHANGE_RATE)(const DWORD, const unsigned char*, DWORD*, const DWORD, unsigned char*, DWORD*);
81
82/* data used while converting */
83typedef struct tagAcmPcmData {
84 /* conversion routine, depending if rate conversion is required */
85 union {
88 } cvt;
90
91/* table to list all supported formats... those are the basic ones. this
92 * also helps given a unique index to each of the supported formats
93 */
94static const struct {
96 int nBits;
97 int rate;
98} PCM_Formats[] = {
99 {1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000}, {1, 24, 8000}, {2, 24, 8000},
100 {1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025}, {1, 24, 11025}, {2, 24, 11025},
101 {1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050}, {1, 24, 22050}, {2, 24, 22050},
102 {1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100}, {1, 24, 44100}, {2, 24, 44100},
103 {1, 8, 48000}, {2, 8, 48000}, {1, 16, 48000}, {2, 16, 48000}, {1, 24, 48000}, {2, 24, 48000},
104 {1, 8, 96000}, {2, 8, 96000}, {1, 16, 96000}, {2, 16, 96000}, {1, 24, 96000}, {2, 24, 96000},
106
107/***********************************************************************
108 * PCM_GetFormatIndex
109 */
111{
112 unsigned int i;
113 TRACE("(%p)\n", wfx);
114
115 for (i = 0; i < ARRAY_SIZE(PCM_Formats); i++) {
116 if (wfx->nChannels == PCM_Formats[i].nChannels &&
117 wfx->nSamplesPerSec == PCM_Formats[i].rate &&
118 wfx->wBitsPerSample == PCM_Formats[i].nBits)
119 return i;
120 }
121 return 0xFFFFFFFF;
122}
123
124/* PCM Conversions:
125 *
126 * parameters:
127 * + 8 bit unsigned vs 16 bit signed
128 * + mono vs stereo (1 or 2 channels)
129 * + sampling rate (8.0, 11.025, 22.05, 44.1 kHz are defined, but algo
130 * shall work in all cases)
131 *
132 * mono => stereo: copy the same sample on Left & Right channels
133 * stereo => mono: use the sum of Left & Right channels
134 */
135
136/***********************************************************************
137 * C816
138 *
139 * Converts a 8 bit sample to a 16 bit one
140 */
141static inline short C816(unsigned char b)
142{
143 return (b - 128) << 8;
144}
145
146/***********************************************************************
147 * C168
148 *
149 * Converts a 16 bit sample to a 8 bit one (data loss !!)
150 */
151static inline unsigned char C168(short s)
152{
153 return HIBYTE(s) ^ (unsigned char)0x80;
154}
155
156/***********************************************************************
157 * C248
158 *
159 * Converts a 24 bit sample to a 8 bit one (data loss !!)
160 */
161static inline unsigned char C248(int s)
162{
163 return HIBYTE(HIWORD(s)) ^ (unsigned char)0x80;
164}
165
166/***********************************************************************
167 * C2416
168 *
169 * Converts a 24 bit sample to a 16 bit one (data loss !!)
170 */
171static inline short C2416(int s)
172{
173 return HIWORD(s);
174}
175
176/***********************************************************************
177 * R16
178 *
179 * Read a 16 bit sample (correctly handles endianness)
180 */
181static inline short R16(const unsigned char* src)
182{
183 return (short)((unsigned short)src[0] | ((unsigned short)src[1] << 8));
184}
185
186/***********************************************************************
187 * R24
188 *
189 * Read a 24 bit sample (correctly handles endianness)
190 * Note, to support signed arithmetic, the values are shifted high in the int
191 * and low 8 bytes are unused.
192 */
193static inline int R24(const unsigned char* src)
194{
195 return ((int)src[0] | (int)src[1] << 8 | (int)src[2] << 16) << 8;
196}
197
198/***********************************************************************
199 * W16
200 *
201 * Write a 16 bit sample (correctly handles endianness)
202 */
203static inline void W16(unsigned char* dst, short s)
204{
205 dst[0] = LOBYTE(s);
206 dst[1] = HIBYTE(s);
207}
208
209/***********************************************************************
210 * W24
211 *
212 * Write a 24 bit sample (correctly handles endianness)
213 */
214static inline void W24(unsigned char* dst, int s)
215{
216 dst[0] = HIBYTE(LOWORD(s));
217 dst[1] = LOBYTE(HIWORD(s));
218 dst[2] = HIBYTE(HIWORD(s));
219}
220
221/***********************************************************************
222 * M24
223 *
224 * Convert the (l,r) 24 bit stereo sample into a 24 bit mono
225 * (takes the sum of the two values)
226 */
227static inline int M24(int l, int r)
228{
229 LONGLONG sum = l + r;
230
231 /* clip sum to saturation */
232 if (sum > 0x7fffff00)
233 sum = 0x7fffff00;
234 else if (sum < -0x7fffff00)
235 sum = -0x7fffff00;
236
237 return sum;
238}
239
240/***********************************************************************
241 * M16
242 *
243 * Convert the (l,r) 16 bit stereo sample into a 16 bit mono
244 * (takes the sum of the two values)
245 */
246static inline short M16(short l, short r)
247{
248 int sum = l + r;
249
250 /* clip sum to saturation */
251 if (sum > 32767)
252 sum = 32767;
253 else if (sum < -32768)
254 sum = -32768;
255
256 return sum;
257}
258
259/***********************************************************************
260 * M8
261 *
262 * Convert the (l,r) 8 bit stereo sample into a 8 bit mono
263 * (takes the sum of the two values)
264 */
265static inline unsigned char M8(unsigned char a, unsigned char b)
266{
267 int l = a - 128;
268 int r = b - 128;
269 int sum = (l + r) + 128;
270
271 /* clip sum to saturation */
272 if (sum > 0xff)
273 sum = 0xff;
274 else if (sum < 0)
275 sum = 0;
276
277 return sum;
278}
279
280/* the conversion routines without rate conversion are labelled cvt<X><Y><N><M>K
281 * where :
282 * <X> is the (M)ono/(S)tereo configuration of input channel
283 * <Y> is the (M)ono/(S)tereo configuration of output channel
284 * <N> is the number of bits of input channel (8 or 16)
285 * <M> is the number of bits of output channel (8 or 16)
286 *
287 * in the parameters, ns is always the number of samples, so the size of input
288 * buffer (resp output buffer) is ns * (<X> == 'Mono' ? 1:2) * (<N> == 8 ? 1:2)
289 */
290
291static void cvtMM88K(const unsigned char* src, int ns, unsigned char* dst)
292{
293 TRACE("(%p, %d, %p)\n", src, ns, dst);
294 memcpy(dst, src, ns);
295}
296
297static void cvtSS88K(const unsigned char* src, int ns, unsigned char* dst)
298{
299 TRACE("(%p, %d, %p)\n", src, ns, dst);
300 memcpy(dst, src, ns * 2);
301}
302
303static void cvtMM1616K(const unsigned char* src, int ns, unsigned char* dst)
304{
305 TRACE("(%p, %d, %p)\n", src, ns, dst);
306 memcpy(dst, src, ns * 2);
307}
308
309static void cvtSS1616K(const unsigned char* src, int ns, unsigned char* dst)
310{
311 TRACE("(%p, %d, %p)\n", src, ns, dst);
312 memcpy(dst, src, ns * 4);
313}
314
315static void cvtMS88K(const unsigned char* src, int ns, unsigned char* dst)
316{
317 TRACE("(%p, %d, %p)\n", src, ns, dst);
318
319 while (ns--) {
320 *dst++ = *src;
321 *dst++ = *src++;
322 }
323}
324
325static void cvtMS816K(const unsigned char* src, int ns, unsigned char* dst)
326{
327 short v;
328 TRACE("(%p, %d, %p)\n", src, ns, dst);
329
330 while (ns--) {
331 v = C816(*src++);
332 W16(dst, v); dst += 2;
333 W16(dst, v); dst += 2;
334 }
335}
336
337static void cvtMS168K(const unsigned char* src, int ns, unsigned char* dst)
338{
339 unsigned char v;
340 TRACE("(%p, %d, %p)\n", src, ns, dst);
341
342 while (ns--) {
343 v = C168(R16(src)); src += 2;
344 *dst++ = v;
345 *dst++ = v;
346 }
347}
348
349static void cvtMS1616K(const unsigned char* src, int ns, unsigned char* dst)
350{
351 short v;
352 TRACE("(%p, %d, %p)\n", src, ns, dst);
353
354 while (ns--) {
355 v = R16(src); src += 2;
356 W16(dst, v); dst += 2;
357 W16(dst, v); dst += 2;
358 }
359}
360
361static void cvtSM88K(const unsigned char* src, int ns, unsigned char* dst)
362{
363 TRACE("(%p, %d, %p)\n", src, ns, dst);
364
365 while (ns--) {
366 *dst++ = M8(src[0], src[1]);
367 src += 2;
368 }
369}
370
371static void cvtSM816K(const unsigned char* src, int ns, unsigned char* dst)
372{
373 short v;
374 TRACE("(%p, %d, %p)\n", src, ns, dst);
375
376 while (ns--) {
377 v = M16(C816(src[0]), C816(src[1]));
378 src += 2;
379 W16(dst, v); dst += 2;
380 }
381}
382
383static void cvtSM168K(const unsigned char* src, int ns, unsigned char* dst)
384{
385 TRACE("(%p, %d, %p)\n", src, ns, dst);
386
387 while (ns--) {
388 *dst++ = C168(M16(R16(src), R16(src + 2)));
389 src += 4;
390 }
391}
392
393static void cvtSM1616K(const unsigned char* src, int ns, unsigned char* dst)
394{
395 TRACE("(%p, %d, %p)\n", src, ns, dst);
396
397 while (ns--) {
398 W16(dst, M16(R16(src),R16(src+2))); dst += 2;
399 src += 4;
400 }
401}
402
403static void cvtMM816K(const unsigned char* src, int ns, unsigned char* dst)
404{
405 TRACE("(%p, %d, %p)\n", src, ns, dst);
406
407 while (ns--) {
408 W16(dst, C816(*src++)); dst += 2;
409 }
410}
411
412static void cvtSS816K(const unsigned char* src, int ns, unsigned char* dst)
413{
414 TRACE("(%p, %d, %p)\n", src, ns, dst);
415
416 while (ns--) {
417 W16(dst, C816(*src++)); dst += 2;
418 W16(dst, C816(*src++)); dst += 2;
419 }
420}
421
422static void cvtMM168K(const unsigned char* src, int ns, unsigned char* dst)
423{
424 TRACE("(%p, %d, %p)\n", src, ns, dst);
425
426 while (ns--) {
427 *dst++ = C168(R16(src)); src += 2;
428 }
429}
430
431static void cvtSS168K(const unsigned char* src, int ns, unsigned char* dst)
432{
433 TRACE("(%p, %d, %p)\n", src, ns, dst);
434
435 while (ns--) {
436 *dst++ = C168(R16(src)); src += 2;
437 *dst++ = C168(R16(src)); src += 2;
438 }
439}
440
441static void cvtMS248K(const unsigned char* src, int ns, unsigned char* dst)
442{
443 unsigned char v;
444 TRACE("(%p, %d, %p)\n", src, ns, dst);
445
446 while (ns--) {
447 v = C248(R24(src)); src += 3;
448 *dst++ = v;
449 *dst++ = v;
450 }
451}
452
453static void cvtSM248K(const unsigned char* src, int ns, unsigned char* dst)
454{
455 TRACE("(%p, %d, %p)\n", src, ns, dst);
456
457 while (ns--) {
458 *dst++ = C248(M24(R24(src), R24(src + 3)));
459 src += 6;
460 }
461}
462
463static void cvtMM248K(const unsigned char* src, int ns, unsigned char* dst)
464{
465 TRACE("(%p, %d, %p)\n", src, ns, dst);
466
467 while (ns--) {
468 *dst++ = C248(R24(src)); src += 3;
469 }
470}
471
472static void cvtSS248K(const unsigned char* src, int ns, unsigned char* dst)
473{
474 TRACE("(%p, %d, %p)\n", src, ns, dst);
475
476 while (ns--) {
477 *dst++ = C248(R24(src)); src += 3;
478 *dst++ = C248(R24(src)); src += 3;
479 }
480}
481
482static void cvtMS2416K(const unsigned char* src, int ns, unsigned char* dst)
483{
484 short v;
485 TRACE("(%p, %d, %p)\n", src, ns, dst);
486
487 while (ns--) {
488 v = C2416(R24(src)); src += 3;
489 W16(dst, v); dst += 2;
490 W16(dst, v); dst += 2;
491 }
492}
493
494static void cvtSM2416K(const unsigned char* src, int ns, unsigned char* dst)
495{
496 TRACE("(%p, %d, %p)\n", src, ns, dst);
497
498 while (ns--) {
499 W16(dst, C2416(M24(R24(src), R24(src + 3))));
500 dst += 2;
501 src += 6;
502 }
503}
504
505static void cvtMM2416K(const unsigned char* src, int ns, unsigned char* dst)
506{
507 TRACE("(%p, %d, %p)\n", src, ns, dst);
508
509 while (ns--) {
510 W16(dst, C2416(R24(src))); dst += 2; src += 3;
511 }
512}
513
514static void cvtSS2416K(const unsigned char* src, int ns, unsigned char* dst)
515{
516 TRACE("(%p, %d, %p)\n", src, ns, dst);
517
518 while (ns--) {
519 W16(dst, C2416(R24(src))); dst += 2; src += 3;
520 W16(dst, C2416(R24(src))); dst += 2; src += 3;
521 }
522}
523
524
528 NULL, NULL, NULL, NULL, /* TODO: 8->24 */
531 NULL, NULL, NULL, NULL, /* TODO: 16->24 */
534 NULL, NULL, NULL, NULL, /* TODO: 24->24 */
535};
536
537/* the conversion routines with rate conversion are labelled cvt<X><Y><N><M>C
538 * where :
539 * <X> is the (M)ono/(S)tereo configuration of input channel
540 * <Y> is the (M)ono/(S)tereo configuration of output channel
541 * <N> is the number of bits of input channel (8 or 16)
542 * <M> is the number of bits of output channel (8 or 16)
543 *
544 */
545
546static void cvtSS88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
547 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
548{
549 DWORD error = srcRate / 2;
550 DWORD maxSrc = *nsrc, maxDst = *ndst;
551 *ndst = 0;
552 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
553 error += dstRate;
554 while (error > srcRate) {
555 if (*ndst == maxDst)
556 return;
557 (*ndst)++;
558 error -= srcRate;
559
560 *dst++ = src[0];
561 *dst++ = src[1];
562 }
563 src += 2;
564 }
565}
566
567static void cvtSM88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
568 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
569{
570 DWORD error = srcRate / 2;
571 DWORD maxSrc = *nsrc, maxDst = *ndst;
572 *ndst = 0;
573 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
574 error += dstRate;
575 while (error > srcRate) {
576 if (*ndst == maxDst)
577 return;
578 (*ndst)++;
579 error -= srcRate;
580
581 *dst++ = M8(src[0], src[1]);
582 }
583 src += 2;
584 }
585}
586
587static void cvtMS88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
588 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
589{
590 DWORD error = srcRate / 2;
591 DWORD maxSrc = *nsrc, maxDst = *ndst;
592 *ndst = 0;
593 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
594 error += dstRate;
595 while (error > srcRate) {
596 if (*ndst == maxDst)
597 return;
598 (*ndst)++;
599 error -= srcRate;
600
601 *dst++ = src[0];
602 *dst++ = src[0];
603 }
604 src += 1;
605 }
606}
607
608static void cvtMM88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
609 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
610{
611 DWORD error = srcRate / 2;
612 DWORD maxSrc = *nsrc, maxDst = *ndst;
613 *ndst = 0;
614 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
615 error += dstRate;
616 while (error > srcRate) {
617 if (*ndst == maxDst)
618 return;
619 (*ndst)++;
620 error -= srcRate;
621
622 *dst++ = src[0];
623 }
624 src += 1;
625 }
626}
627
628static void cvtSS816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
629 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
630{
631 DWORD error = srcRate / 2;
632 DWORD maxSrc = *nsrc, maxDst = *ndst;
633 *ndst = 0;
634 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
635 error += dstRate;
636 while (error > srcRate) {
637 if (*ndst == maxDst)
638 return;
639 (*ndst)++;
640 error -= srcRate;
641
642 W16(dst, C816(src[0])); dst += 2;
643 W16(dst, C816(src[1])); dst += 2;
644 }
645 src += 2;
646 }
647}
648
649static void cvtSM816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
650 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
651{
652 DWORD error = srcRate / 2;
653 DWORD maxSrc = *nsrc, maxDst = *ndst;
654 *ndst = 0;
655 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
656 error += dstRate;
657 while (error > srcRate) {
658 if (*ndst == maxDst)
659 return;
660 (*ndst)++;
661 error -= srcRate;
662
663 W16(dst, M16(C816(src[0]), C816(src[1]))); dst += 2;
664 }
665 src += 2;
666 }
667}
668
669static void cvtMS816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
670 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
671{
672 DWORD error = srcRate / 2;
673 DWORD maxSrc = *nsrc, maxDst = *ndst;
674 *ndst = 0;
675 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
676 error += dstRate;
677 while (error > srcRate) {
678 if (*ndst == maxDst)
679 return;
680 (*ndst)++;
681 error -= srcRate;
682
683 W16(dst, C816(src[0])); dst += 2;
684 W16(dst, C816(src[0])); dst += 2;
685 }
686 src += 1;
687 }
688}
689
690static void cvtMM816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
691 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
692{
693 DWORD error = srcRate / 2;
694 DWORD maxSrc = *nsrc, maxDst = *ndst;
695 *ndst = 0;
696 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
697 error += dstRate;
698 while (error > srcRate) {
699 if (*ndst == maxDst)
700 return;
701 (*ndst)++;
702 error -= srcRate;
703
704 W16(dst, C816(src[0])); dst += 2;
705 }
706 src += 1;
707 }
708}
709
710static void cvtSS168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
711 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
712{
713 DWORD error = srcRate / 2;
714 DWORD maxSrc = *nsrc, maxDst = *ndst;
715 *ndst = 0;
716 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
717 error += dstRate;
718 while (error > srcRate) {
719 if (*ndst == maxDst)
720 return;
721 (*ndst)++;
722 error -= srcRate;
723
724 *dst++ = C168(R16(src));
725 *dst++ = C168(R16(src + 2));
726 }
727 src += 4;
728 }
729}
730
731static void cvtSM168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
732 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
733{
734 DWORD error = srcRate / 2;
735 DWORD maxSrc = *nsrc, maxDst = *ndst;
736 *ndst = 0;
737 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
738 error += dstRate;
739 while (error > srcRate) {
740 if (*ndst == maxDst)
741 return;
742 (*ndst)++;
743 error -= srcRate;
744
745 *dst++ = C168(M16(R16(src), R16(src + 2)));
746 }
747 src += 4;
748 }
749}
750
751static void cvtMS168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
752 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
753{
754 DWORD error = srcRate / 2;
755 DWORD maxSrc = *nsrc, maxDst = *ndst;
756 *ndst = 0;
757 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
758 error += dstRate;
759 while (error > srcRate) {
760 if (*ndst == maxDst)
761 return;
762 (*ndst)++;
763 error -= srcRate;
764
765 *dst++ = C168(R16(src));
766 *dst++ = C168(R16(src));
767 }
768 src += 2;
769 }
770}
771
772static void cvtMM168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
773 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
774{
775 DWORD error = srcRate / 2;
776 DWORD maxSrc = *nsrc, maxDst = *ndst;
777 *ndst = 0;
778 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
779 error += dstRate;
780 while (error > srcRate) {
781 if (*ndst == maxDst)
782 return;
783 (*ndst)++;
784 error -= srcRate;
785
786 *dst++ = C168(R16(src));
787 }
788 src += 2;
789 }
790}
791
792static void cvtSS1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
793 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
794{
795 DWORD error = srcRate / 2;
796 DWORD maxSrc = *nsrc, maxDst = *ndst;
797 *ndst = 0;
798 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
799 error += dstRate;
800 while (error > srcRate) {
801 if (*ndst == maxDst)
802 return;
803 (*ndst)++;
804 error -= srcRate;
805
806 W16(dst, R16(src)); dst += 2;
807 W16(dst, R16(src + 2)); dst += 2;
808 }
809 src += 4;
810 }
811}
812
813static void cvtSM1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
814 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
815{
816 DWORD error = srcRate / 2;
817 DWORD maxSrc = *nsrc, maxDst = *ndst;
818 *ndst = 0;
819 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
820 error += dstRate;
821 while (error > srcRate) {
822 if (*ndst == maxDst)
823 return;
824 (*ndst)++;
825 error -= srcRate;
826
827 W16(dst, M16(R16(src), R16(src + 2))); dst += 2;
828 }
829 src += 4;
830 }
831}
832
833static void cvtMS1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
834 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
835{
836 DWORD error = srcRate / 2;
837 DWORD maxSrc = *nsrc, maxDst = *ndst;
838 *ndst = 0;
839 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
840 error += dstRate;
841 while (error > srcRate) {
842 if (*ndst == maxDst)
843 return;
844 (*ndst)++;
845 error -= srcRate;
846
847 W16(dst, R16(src)); dst += 2;
848 W16(dst, R16(src)); dst += 2;
849 }
850 src += 2;
851 }
852}
853
854static void cvtMM1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
855 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
856{
857 DWORD error = srcRate / 2;
858 DWORD maxSrc = *nsrc, maxDst = *ndst;
859 *ndst = 0;
860 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
861 error += dstRate;
862 while (error > srcRate) {
863 if (*ndst == maxDst)
864 return;
865 (*ndst)++;
866 error -= srcRate;
867
868 W16(dst, R16(src)); dst += 2;
869 }
870 src += 2;
871 }
872}
873
874static void cvtSS2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
875 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
876{
877 DWORD error = srcRate / 2;
878 DWORD maxSrc = *nsrc, maxDst = *ndst;
879 *ndst = 0;
880 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
881 error += dstRate;
882 while (error > srcRate) {
883 if (*ndst == maxDst)
884 return;
885 (*ndst)++;
886 error -= srcRate;
887
888 W24(dst, R24(src)); dst += 3;
889 W24(dst, R24(src + 3)); dst += 3;
890 }
891 src += 6;
892 }
893}
894
895static void cvtSM2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
896 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
897{
898 DWORD error = srcRate / 2;
899 DWORD maxSrc = *nsrc, maxDst = *ndst;
900 *ndst = 0;
901 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
902 error += dstRate;
903 while (error > srcRate) {
904 if (*ndst == maxDst)
905 return;
906 (*ndst)++;
907 error -= srcRate;
908
909 W24(dst, M24(R24(src), R24(src + 3))); dst += 3;
910 }
911 src += 6;
912 }
913}
914
915static void cvtMS2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
916 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
917{
918 DWORD error = srcRate / 2;
919 DWORD maxSrc = *nsrc, maxDst = *ndst;
920 *ndst = 0;
921 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
922 error += dstRate;
923 while (error > srcRate) {
924 if (*ndst == maxDst)
925 return;
926 (*ndst)++;
927 error -= srcRate;
928
929 W24(dst, R24(src)); dst += 3;
930 W24(dst, R24(src)); dst += 3;
931 }
932 src += 3;
933 }
934}
935
936static void cvtMM2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc,
937 const DWORD dstRate, unsigned char *dst, DWORD *ndst)
938{
939 DWORD error = srcRate / 2;
940 DWORD maxSrc = *nsrc, maxDst = *ndst;
941 *ndst = 0;
942 for (*nsrc = 0; *nsrc < maxSrc; (*nsrc)++) {
943 error += dstRate;
944 while (error > srcRate) {
945 if (*ndst == maxDst)
946 return;
947 (*ndst)++;
948 error -= srcRate;
949
950 W24(dst, R24(src)); dst += 3;
951 }
952 src += 3;
953 }
954}
955
959 NULL, NULL, NULL, NULL, /* TODO: 8->24 */
962 NULL, NULL, NULL, NULL, /* TODO: 16->24 */
963 NULL, NULL, NULL, NULL, /* TODO: 24->8 */
964 NULL, NULL, NULL, NULL, /* TODO: 24->16 */
966};
967
968/***********************************************************************
969 * PCM_DriverDetails
970 *
971 */
973{
974 TRACE("(%p)\n", add);
975
978 add->wMid = MM_MICROSOFT;
979 add->wPid = MM_MSFT_ACM_PCM;
980 add->vdwACM = 0x01000000;
981 add->vdwDriver = 0x01000000;
983 add->cFormatTags = 1;
984 add->cFilterTags = 0;
985 add->hicon = NULL;
986 MultiByteToWideChar(CP_ACP, 0, "MS-PCM", -1, add->szShortName, ARRAY_SIZE(add->szShortName));
987 MultiByteToWideChar(CP_ACP, 0, "Wine PCM converter", -1,
988 add->szLongName, ARRAY_SIZE(add->szLongName));
989 MultiByteToWideChar(CP_ACP, 0, "Brought to you by the Wine team...", -1,
991 MultiByteToWideChar(CP_ACP, 0, "Refer to LICENSE file", -1,
992 add->szLicensing, ARRAY_SIZE(add->szLicensing) );
993 add->szFeatures[0] = 0;
994
995 return MMSYSERR_NOERROR;
996}
997
998/***********************************************************************
999 * PCM_FormatTagDetails
1000 *
1001 */
1003{
1004 TRACE("(%p, %08x)\n", aftd, dwQuery);
1005
1006 switch (dwQuery) {
1008 if (aftd->dwFormatTagIndex != 0) {
1009 WARN("not possible\n");
1010 return ACMERR_NOTPOSSIBLE;
1011 }
1012 break;
1014 if (aftd->dwFormatTag != WAVE_FORMAT_PCM) {
1015 WARN("not possible\n");
1016 return ACMERR_NOTPOSSIBLE;
1017 }
1018 break;
1020 if (aftd->dwFormatTag != WAVE_FORMAT_UNKNOWN &&
1021 aftd->dwFormatTag != WAVE_FORMAT_PCM) {
1022 WARN("not possible\n");
1023 return ACMERR_NOTPOSSIBLE;
1024 }
1025 break;
1026 default:
1027 WARN("Unsupported query %08x\n", dwQuery);
1028 return MMSYSERR_NOTSUPPORTED;
1029 }
1030
1031 aftd->dwFormatTagIndex = 0;
1033 aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
1036 aftd->szFormatTag[0] = 0;
1037
1038 return MMSYSERR_NOERROR;
1039}
1040
1041/***********************************************************************
1042 * PCM_FormatDetails
1043 *
1044 */
1046{
1047 TRACE("(%p, %08x)\n", afd, dwQuery);
1048
1049 switch (dwQuery) {
1051 if (PCM_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) {
1052 WARN("not possible\n");
1053 return ACMERR_NOTPOSSIBLE;
1054 }
1055 break;
1059 afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
1060 afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
1061 afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
1062 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not
1063 * accessible afd->pwfx->cbSize = 0;
1064 */
1065 afd->pwfx->nBlockAlign =
1066 (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
1067 afd->pwfx->nAvgBytesPerSec =
1068 afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
1069 break;
1070 default:
1071 WARN("Unsupported query %08x\n", dwQuery);
1072 return MMSYSERR_NOTSUPPORTED;
1073 }
1074
1077 afd->szFormat[0] = 0; /* let MSACM format this for us... */
1078 afd->cbwfx = sizeof(PCMWAVEFORMAT);
1079
1080 return MMSYSERR_NOERROR;
1081}
1082
1083/***********************************************************************
1084 * PCM_FormatSuggest
1085 *
1086 */
1088{
1089 TRACE("(%p)\n", adfs);
1090
1091 /* some tests ... */
1092 if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
1093 adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
1094 PCM_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) {
1095 WARN("not possible\n");
1096 return ACMERR_NOTPOSSIBLE;
1097 }
1098
1099 /* is no suggestion for destination, then copy source value */
1101 adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
1102 }
1105 }
1108 }
1110 if (adfs->pwfxSrc->wFormatTag != WAVE_FORMAT_PCM) {
1111 WARN("source format 0x%x not supported\n", adfs->pwfxSrc->wFormatTag);
1112 return ACMERR_NOTPOSSIBLE;
1113 }
1114 adfs->pwfxDst->wFormatTag = adfs->pwfxSrc->wFormatTag;
1115 } else {
1116 if (adfs->pwfxDst->wFormatTag != WAVE_FORMAT_PCM) {
1117 WARN("destination format 0x%x not supported\n", adfs->pwfxDst->wFormatTag);
1118 return ACMERR_NOTPOSSIBLE;
1119 }
1120 }
1121 /* check if result is ok */
1122 if (PCM_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) {
1123 WARN("not possible\n");
1124 return ACMERR_NOTPOSSIBLE;
1125 }
1126
1127 /* recompute other values */
1128 adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
1130
1131 return MMSYSERR_NOERROR;
1132}
1133
1134/***********************************************************************
1135 * PCM_StreamOpen
1136 *
1137 */
1139{
1140 AcmPcmData* apd;
1141 int idx;
1142 DWORD flags;
1143
1144 TRACE("(%p)\n", adsi);
1145
1147
1148 switch(adsi->pwfxSrc->wBitsPerSample){
1149 case 8:
1150 idx = 0;
1151 break;
1152 case 16:
1153 idx = 12;
1154 break;
1155 case 24:
1156 if (adsi->pwfxSrc->nBlockAlign != 3 * adsi->pwfxSrc->nChannels) {
1157 FIXME("Source: 24-bit samples must be packed\n");
1158 return MMSYSERR_NOTSUPPORTED;
1159 }
1160 idx = 24;
1161 break;
1162 default:
1163 FIXME("Unsupported source bit depth: %u\n", adsi->pwfxSrc->wBitsPerSample);
1164 return MMSYSERR_NOTSUPPORTED;
1165 }
1166
1167 switch(adsi->pwfxDst->wBitsPerSample){
1168 case 8:
1169 break;
1170 case 16:
1171 idx += 4;
1172 break;
1173 case 24:
1174 if (adsi->pwfxDst->nBlockAlign != 3 * adsi->pwfxDst->nChannels) {
1175 FIXME("Destination: 24-bit samples must be packed\n");
1176 return MMSYSERR_NOTSUPPORTED;
1177 }
1178 idx += 8;
1179 break;
1180 default:
1181 FIXME("Unsupported destination bit depth: %u\n", adsi->pwfxDst->wBitsPerSample);
1182 return MMSYSERR_NOTSUPPORTED;
1183 }
1184
1185 if (adsi->pwfxSrc->nChannels == 1) idx += 2;
1186
1187 if (adsi->pwfxDst->nChannels == 1) idx += 1;
1188
1189 apd = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmPcmData));
1190 if (!apd)
1191 return MMSYSERR_NOMEM;
1192
1193 if (adsi->pwfxSrc->nSamplesPerSec == adsi->pwfxDst->nSamplesPerSec) {
1194 flags = 0;
1196 } else {
1199 }
1200
1201 if(!apd->cvt.cvtChangeRate && !apd->cvt.cvtKeepRate){
1202 FIXME("Unimplemented conversion from %u -> %u bps\n",
1203 adsi->pwfxSrc->wBitsPerSample,
1204 adsi->pwfxDst->wBitsPerSample);
1205 HeapFree(GetProcessHeap(), 0, apd);
1206 return MMSYSERR_NOTSUPPORTED;
1207 }
1208
1209 adsi->dwDriver = (DWORD_PTR)apd;
1210 adsi->fdwDriver = flags;
1211
1212 return MMSYSERR_NOERROR;
1213}
1214
1215/***********************************************************************
1216 * PCM_StreamClose
1217 *
1218 */
1220{
1221 TRACE("(%p)\n", adsi);
1222
1223 HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
1224 return MMSYSERR_NOERROR;
1225}
1226
1227/***********************************************************************
1228 * PCM_round
1229 *
1230 */
1232{
1233 assert(c);
1234 /* to be sure, always return an entire number of c... */
1235 return ((double)a * (double)b + (double)c - 1) / (double)c;
1236}
1237
1238/***********************************************************************
1239 * PCM_StreamSize
1240 *
1241 */
1243{
1244 DWORD srcMask = ~(adsi->pwfxSrc->nBlockAlign - 1);
1245 DWORD dstMask = ~(adsi->pwfxDst->nBlockAlign - 1);
1246
1247 TRACE("(%p, %p)\n", adsi, adss);
1248
1249 switch (adss->fdwSize) {
1251 /* cbDstLength => cbSrcLength */
1252 adss->cbSrcLength = PCM_round(adss->cbDstLength & dstMask,
1253 adsi->pwfxSrc->nAvgBytesPerSec,
1254 adsi->pwfxDst->nAvgBytesPerSec) & srcMask;
1255 break;
1257 /* cbSrcLength => cbDstLength */
1258 adss->cbDstLength = PCM_round(adss->cbSrcLength & srcMask,
1259 adsi->pwfxDst->nAvgBytesPerSec,
1261 break;
1262 default:
1263 WARN("Unsupported query %08x\n", adss->fdwSize);
1264 return MMSYSERR_NOTSUPPORTED;
1265 }
1266 return MMSYSERR_NOERROR;
1267}
1268
1269/***********************************************************************
1270 * PCM_StreamConvert
1271 *
1272 */
1274{
1275 AcmPcmData* apd = (AcmPcmData*)adsi->dwDriver;
1276 DWORD nsrc = NUM_OF(adsh->cbSrcLength, adsi->pwfxSrc->nBlockAlign);
1277 DWORD ndst = NUM_OF(adsh->cbDstLength, adsi->pwfxDst->nBlockAlign);
1278
1279 TRACE("(%p, %p)\n", adsi, adsh);
1280
1281 TRACE("nsrc=%d,adsh->cbSrcLength=%d\n", nsrc, adsh->cbSrcLength);
1282 TRACE("ndst=%d,adsh->cbDstLength=%d\n", ndst, adsh->cbDstLength);
1283 TRACE("src [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%u, nAvgBytesPerSec=%u, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
1285 adsi->pwfxSrc->nBlockAlign, adsi->pwfxSrc->wBitsPerSample, adsi->pwfxSrc->cbSize);
1286 TRACE("dst [wFormatTag=%u, nChannels=%u, nSamplesPerSec=%u, nAvgBytesPerSec=%u, nBlockAlign=%u, wBitsPerSample=%u, cbSize=%u]\n",
1288 adsi->pwfxDst->nBlockAlign, adsi->pwfxDst->wBitsPerSample, adsi->pwfxDst->cbSize);
1289
1290 if (adsh->fdwConvert &
1294 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
1295 }
1296 /* ACM_STREAMCONVERTF_BLOCKALIGN
1297 * currently all conversions are block aligned, so do nothing for this flag
1298 * ACM_STREAMCONVERTF_END
1299 * no pending data, so do nothing for this flag
1300 */
1301 if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START) &&
1302 (adsi->fdwDriver & PCM_RESAMPLE)) {
1303 }
1304
1305 /* do the job */
1306 if (adsi->fdwDriver & PCM_RESAMPLE) {
1307 apd->cvt.cvtChangeRate(adsi->pwfxSrc->nSamplesPerSec, adsh->pbSrc, &nsrc,
1308 adsi->pwfxDst->nSamplesPerSec, adsh->pbDst, &ndst);
1309 } else {
1310 if (nsrc < ndst) ndst = nsrc; else nsrc = ndst;
1311
1312 /* nsrc is now equal to ndst */
1313 apd->cvt.cvtKeepRate(adsh->pbSrc, nsrc, adsh->pbDst);
1314 }
1315
1316 adsh->cbSrcLengthUsed = nsrc * adsi->pwfxSrc->nBlockAlign;
1317 adsh->cbDstLengthUsed = ndst * adsi->pwfxDst->nBlockAlign;
1318
1319 return MMSYSERR_NOERROR;
1320}
1321
1322/**************************************************************************
1323 * DriverProc (MSACM32.@)
1324 */
1325LRESULT CALLBACK PCM_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
1326 LPARAM dwParam1, LPARAM dwParam2)
1327{
1328 TRACE("(%08lx %p %u %08lx %08lx);\n",
1329 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1330
1331 switch (wMsg) {
1332 case DRV_LOAD: return 1;
1333 case DRV_FREE: return 1;
1334 case DRV_OPEN: return PCM_drvOpen((LPSTR)dwParam1, (PACMDRVOPENDESCW)dwParam2);
1335 case DRV_CLOSE: return PCM_drvClose(dwDevID);
1336 case DRV_ENABLE: return 1;
1337 case DRV_DISABLE: return 1;
1338 case DRV_QUERYCONFIGURE: return 1;
1339 case DRV_CONFIGURE: MessageBoxA(0, "MSACM PCM filter !", "Wine Driver", MB_OK); return 1;
1340 case DRV_INSTALL: return DRVCNF_RESTART;
1341 case DRV_REMOVE: return DRVCNF_RESTART;
1342
1344 /* no caching from other ACM drivers is done so far */
1345 return MMSYSERR_NOERROR;
1346
1348 return PCM_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1349
1351 return PCM_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
1352
1354 return PCM_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1355
1357 return PCM_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
1358
1359 case ACMDM_STREAM_OPEN:
1360 return PCM_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
1361
1362 case ACMDM_STREAM_CLOSE:
1363 return PCM_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
1364
1365 case ACMDM_STREAM_SIZE:
1366 return PCM_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
1367
1369 return PCM_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
1370
1373 /* this converter is not a hardware driver */
1376 /* this converter is not a filter */
1377 case ACMDM_STREAM_RESET:
1378 /* only needed for asynchronous driver... we aren't, so just say it */
1381 /* nothing special to do here... so don't do anything */
1382 return MMSYSERR_NOTSUPPORTED;
1383
1384 default:
1385 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1386 }
1387}
#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:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
unsigned int idx
Definition: utils.c:41
#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 MultiByteToWideChar
Definition: compat.h:110
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
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
const GLdouble * v
Definition: gl.h:2040
GLdouble s
Definition: gl.h:2039
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint GLuint dstMask
Definition: glext.h:9513
GLenum src
Definition: glext.h:6340
const GLubyte * c
Definition: glext.h:8905
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
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)
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
#define MM_MSFT_ACM_PCM
Definition: mmreg.h:150
#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_NOERROR
Definition: mmsystem.h:96
#define DRV_FREE
Definition: mmsystem.h:124
#define DRV_DISABLE
Definition: mmsystem.h:123
static const char mbstate_t *static wchar_t const char mbstate_t *static const wchar_t int *static double
Definition: string.c:80
#define ACMDRIVERDETAILS_SUPPORTF_CONVERTER
Definition: msacm.h:62
#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 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 DWORD
Definition: nt_native.h:44
static void cvtSS88K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:297
static void cvtMS816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:669
static void cvtSS88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:546
static const PCM_CONVERT_CHANGE_RATE PCM_ConvertChangeRate[]
Definition: pcmconverter.c:956
static void cvtMS168K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:337
static int R24(const unsigned char *src)
Definition: pcmconverter.c:193
static void cvtSM816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:649
static void cvtMS88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:587
static short M16(short l, short r)
Definition: pcmconverter.c:246
void(* PCM_CONVERT_CHANGE_RATE)(const DWORD, const unsigned char *, DWORD *, const DWORD, unsigned char *, DWORD *)
Definition: pcmconverter.c:80
static LRESULT PCM_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
static void cvtMM816K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:403
static DWORD PCM_GetFormatIndex(LPWAVEFORMATEX wfx)
Definition: pcmconverter.c:110
#define NUM_OF(a, b)
Definition: pcmconverter.c:73
static unsigned char C248(int s)
Definition: pcmconverter.c:161
static short C816(unsigned char b)
Definition: pcmconverter.c:141
static DWORD PCM_drvOpen(LPCSTR str, PACMDRVOPENDESCW adod)
Definition: pcmconverter.c:54
void(* PCM_CONVERT_KEEP_RATE)(const unsigned char *, int, unsigned char *)
Definition: pcmconverter.c:78
#define PCM_RESAMPLE
Definition: pcmconverter.c:76
LRESULT CALLBACK PCM_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
static void cvtSM2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:895
static void cvtSM1616K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:393
static void cvtSS248K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:472
static void cvtSS2416K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:514
static void cvtSS2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:874
static void cvtMM2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:936
static void W24(unsigned char *dst, int s)
Definition: pcmconverter.c:214
static void cvtMS2416K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:482
static void cvtMS168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:751
int nBits
Definition: pcmconverter.c:96
static void cvtMS1616K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:349
static LRESULT PCM_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
static void cvtSS816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:628
static void cvtSS1616K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:309
int rate
Definition: pcmconverter.c:97
static LRESULT PCM_DriverDetails(PACMDRIVERDETAILSW add)
Definition: pcmconverter.c:972
static void cvtSM248K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:453
static void cvtMM88K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:291
static void cvtSS168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:710
static void cvtSM2416K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:494
static void cvtMM168K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:422
int nChannels
Definition: pcmconverter.c:95
static void cvtSS168K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:431
static const struct @481 PCM_Formats[]
static LRESULT PCM_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
static void cvtMM1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:854
static unsigned char C168(short s)
Definition: pcmconverter.c:151
static LRESULT PCM_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
static void cvtSM168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:731
static LRESULT PCM_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
static void cvtSS1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:792
static void W16(unsigned char *dst, short s)
Definition: pcmconverter.c:203
static DWORD PCM_drvClose(DWORD dwDevID)
Definition: pcmconverter.c:66
static const PCM_CONVERT_KEEP_RATE PCM_ConvertKeepRate[]
Definition: pcmconverter.c:525
static void cvtMM248K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:463
static void cvtSS816K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:412
static unsigned char M8(unsigned char a, unsigned char b)
Definition: pcmconverter.c:265
static short C2416(int s)
Definition: pcmconverter.c:171
static int M24(int l, int r)
Definition: pcmconverter.c:227
static void cvtMS88K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:315
static void cvtMM168C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:772
static void cvtMM2416K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:505
static void cvtMM88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:608
static void cvtMS248K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:441
struct tagAcmPcmData AcmPcmData
static void cvtSM816K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:371
static void cvtSM168K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:383
static void cvtMM1616K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:303
static LRESULT PCM_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
static void cvtMS2424C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:915
static DWORD PCM_round(DWORD a, DWORD b, DWORD c)
static void cvtMM816C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:690
static void cvtMS1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:833
static void cvtSM88C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:567
static void cvtSM88K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:361
static void cvtSM1616C(const DWORD srcRate, const unsigned char *src, DWORD *nsrc, const DWORD dstRate, unsigned char *dst, DWORD *ndst)
Definition: pcmconverter.c:813
static void cvtMS816K(const unsigned char *src, int ns, unsigned char *dst)
Definition: pcmconverter.c:325
static short R16(const unsigned char *src)
Definition: pcmconverter.c:181
static LRESULT PCM_StreamClose(PACMDRVSTREAMINSTANCE adsi)
#define LOWORD(l)
Definition: pedump.c:82
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
const WCHAR * str
#define TRACE(s)
Definition: solgame.cpp:4
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
FOURCC fccType
Definition: msacmdrv.h:87
FOURCC fccComp
Definition: msacmdrv.h:88
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
WORD cbSize
Definition: mmreg.h:84
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: mxnamespace.c:45
PCM_CONVERT_KEEP_RATE cvtKeepRate
Definition: pcmconverter.c:86
PCM_CONVERT_CHANGE_RATE cvtChangeRate
Definition: pcmconverter.c:87
union tagAcmPcmData::@482 cvt
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
int64_t LONGLONG
Definition: typedefs.h:68
#define HIWORD(l)
Definition: typedefs.h:247
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:790
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182