ReactOS 0.4.15-dev-8241-g63935f8
mpegl3.c
Go to the documentation of this file.
1/*
2 * MPEG Layer 3 handling
3 *
4 * Copyright (C) 2002 Eric Pouech
5 * Copyright (C) 2009 CodeWeavers, Aric Stewart
6 * Copyright (C) 2010 Kristofer Henriksson
7 *
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
24#include "config.h"
25#include "wine/port.h"
26
27#include <assert.h>
28#include <stdarg.h>
29#include <string.h>
30
31#ifdef HAVE_MPG123_H
32# include <mpg123.h>
33#else
34# ifdef HAVE_COREAUDIO_COREAUDIO_H
35# include <CoreFoundation/CoreFoundation.h>
36# include <CoreAudio/CoreAudio.h>
37# endif
38# ifdef HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H
39# include <AudioToolbox/AudioConverter.h>
40# endif
41#endif
42
43#include "windef.h"
44#include "winbase.h"
45#include "wingdi.h"
46#include "winuser.h"
47#include "winnls.h"
48#include "mmsystem.h"
49#include "mmreg.h"
50#include "msacm.h"
51#include "msacmdrv.h"
52#include "wine/debug.h"
53
55
56/* table to list all supported formats... those are the basic ones. this
57 * also helps given a unique index to each of the supported formats
58 */
59typedef struct
60{
61 int nChannels;
62 int nBits;
63 int rate;
64} Format;
65
66static const Format PCM_Formats[] =
67{
68 {1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000},
69 {1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025},
70 {1, 8, 12000}, {2, 8, 12000}, {1, 16, 12000}, {2, 16, 12000},
71 {1, 8, 16000}, {2, 8, 16000}, {1, 16, 16000}, {2, 16, 16000},
72 {1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050},
73 {1, 8, 24000}, {2, 8, 24000}, {1, 16, 24000}, {2, 16, 24000},
74 {1, 8, 32000}, {2, 8, 32000}, {1, 16, 32000}, {2, 16, 32000},
75 {1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100},
76 {1, 8, 48000}, {2, 8, 48000}, {1, 16, 48000}, {2, 16, 48000}
77};
78
79static const Format MPEG3_Formats[] =
80{
81 {1, 0, 8000}, {2, 0, 8000},
82 {1, 0, 11025}, {2, 0, 11025},
83 {1, 0, 12000}, {2, 0, 12000},
84 {1, 0, 16000}, {2, 0, 16000},
85 {1, 0, 22050}, {2, 0, 22050},
86 {1, 0, 24000}, {2, 0, 24000},
87 {1, 0, 32000}, {2, 0, 32000},
88 {1, 0, 44100}, {2, 0, 44100},
89 {1, 0, 48000}, {2, 0, 48000}
90};
91
92/***********************************************************************
93 * MPEG3_GetFormatIndex
94 */
96{
97 int i, hi;
98 const Format *fmts;
99
100 switch (wfx->wFormatTag)
101 {
102 case WAVE_FORMAT_PCM:
105 break;
106 case WAVE_FORMAT_MPEG:
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 || !fmts[i].nBits))
120 return i;
121 }
122
123 return 0xFFFFFFFF;
124}
125
126#ifdef HAVE_MPG123_H
127
128typedef struct tagAcmMpeg3Data
129{
131 const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
132 mpg123_handle *mh;
133} AcmMpeg3Data;
134
135/***********************************************************************
136 * MPEG3_drvOpen
137 */
138static LRESULT MPEG3_drvOpen(LPCSTR str)
139{
140 mpg123_init();
141 return 1;
142}
143
144/***********************************************************************
145 * MPEG3_drvClose
146 */
147static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
148{
149 mpg123_exit();
150 return 1;
151}
152
153
154static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
155 const unsigned char* src, LPDWORD nsrc,
156 unsigned char* dst, LPDWORD ndst)
157{
158 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
159 int ret;
160 size_t size;
161 DWORD dpos = 0;
162
163
164 if (*nsrc > 0)
165 {
166 ret = mpg123_feed(amd->mh, src, *nsrc);
167 if (ret != MPG123_OK)
168 {
169 ERR("Error feeding data\n");
170 *ndst = *nsrc = 0;
171 return;
172 }
173 }
174
175 do {
176 size = 0;
177 ret = mpg123_read(amd->mh, dst + dpos, *ndst - dpos, &size);
178 if (ret == MPG123_ERR)
179 {
180 FIXME("Error occurred during decoding!\n");
181 *ndst = *nsrc = 0;
182 return;
183 }
184
185 if (ret == MPG123_NEW_FORMAT)
186 {
187 long rate;
188 int channels, enc;
189 mpg123_getformat(amd->mh, &rate, &channels, &enc);
190 TRACE("New format: %li Hz, %i channels, encoding value %i\n", rate, channels, enc);
191 }
192 dpos += size;
193 if (dpos >= *ndst) break;
194 } while (ret != MPG123_ERR && ret != MPG123_NEED_MORE);
195 *ndst = dpos;
196}
197
198/***********************************************************************
199 * MPEG3_Reset
200 *
201 */
202static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
203{
204 mpg123_feedseek(aad->mh, 0, SEEK_SET, NULL);
205 mpg123_close(aad->mh);
206 mpg123_open_feed(aad->mh);
207}
208
209/***********************************************************************
210 * MPEG3_StreamOpen
211 *
212 */
213static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
214{
216 AcmMpeg3Data* aad;
217 int err;
218
220
221 if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
222 MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
223 return ACMERR_NOTPOSSIBLE;
224
225 aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data));
226 if (aad == 0) return MMSYSERR_NOMEM;
227
228 adsi->dwDriver = (DWORD_PTR)aad;
229
230 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
232 {
233 goto theEnd;
234 }
235 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
238 {
240 {
242
244 formatmp3->wID != MPEGLAYER3_ID_MPEG)
245 {
247 goto theEnd;
248 }
249 }
250
251 /* resampling or mono <=> stereo not available
252 * MPEG3 algo only define 16 bit per sample output
253 */
254 if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
255 adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
256 adsi->pwfxDst->wBitsPerSample != 16)
257 goto theEnd;
258 aad->convert = mp3_horse;
259 aad->mh = mpg123_new(NULL,&err);
260 mpg123_open_feed(aad->mh);
261
262#if MPG123_API_VERSION >= 31 /* needed for MPG123_IGNORE_FRAMEINFO enum value */
263 /* mpg123 may find a XING header in the mp3 and use that information
264 * to ask for seeks in order to read specific frames in the file.
265 * We cannot allow that since the caller application is feeding us.
266 * This fixes problems for mp3 files encoded with LAME (bug 42361)
267 */
269#endif
270 }
271 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
274 {
275 WARN("Encoding to MPEG is not supported\n");
276 goto theEnd;
277 }
278 else goto theEnd;
279 MPEG3_Reset(adsi, aad);
280
281 return MMSYSERR_NOERROR;
282
283 theEnd:
284 HeapFree(GetProcessHeap(), 0, aad);
285 adsi->dwDriver = 0L;
286 return error;
287}
288
289/***********************************************************************
290 * MPEG3_StreamClose
291 *
292 */
293static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)
294{
295 mpg123_close(((AcmMpeg3Data*)adsi->dwDriver)->mh);
296 mpg123_delete(((AcmMpeg3Data*)adsi->dwDriver)->mh);
297 HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
298 return MMSYSERR_NOERROR;
299}
300
301#elif defined(HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H)
302
303static const unsigned short Mp3BitRates[2][16] =
304{
305 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
306 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
307};
308
309static const unsigned short Mp3SampleRates[2][4] =
310{
311 {44100, 48000, 32000, 0},
312 {22050, 24000, 16000, 0}
313};
314
315typedef struct tagAcmMpeg3Data
316{
317 LRESULT (*convert)(PACMDRVSTREAMINSTANCE adsi, unsigned char*,
318 LPDWORD, unsigned char*, LPDWORD);
319 AudioConverterRef acr;
320 AudioStreamBasicDescription in,out;
321
322 AudioBufferList outBuffer;
323 AudioBuffer inBuffer;
324
325 SInt32 tagBytesLeft;
326
327 UInt32 NumberPackets;
328 AudioStreamPacketDescription *PacketDescriptions;
329} AcmMpeg3Data;
330
331/***********************************************************************
332 * MPEG3_drvOpen
333 */
334static LRESULT MPEG3_drvOpen(LPCSTR str)
335{
336 return 1;
337}
338
339/***********************************************************************
340 * MPEG3_drvClose
341 */
342static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
343{
344 return 1;
345}
346
347/*
348 When it asks for data, give it all we have. If we have no data, we assume
349 we will in the future, so give it no packets and return an error, which
350 signals that we will have more later.
351 */
352static OSStatus Mp3AudioConverterComplexInputDataProc(
353 AudioConverterRef inAudioConverter,
354 UInt32 *ioNumberDataPackets,
355 AudioBufferList *ioData,
356 AudioStreamPacketDescription **outDataPacketDescription,
357 void *inUserData
358)
359{
360 AcmMpeg3Data *amd = (AcmMpeg3Data*)inUserData;
361
362 if (amd->inBuffer.mDataByteSize > 0)
363 {
364 *ioNumberDataPackets = amd->NumberPackets;
365 ioData->mNumberBuffers = 1;
366 ioData->mBuffers[0] = amd->inBuffer;
367 amd->inBuffer.mDataByteSize = 0;
368 if (outDataPacketDescription)
369 *outDataPacketDescription = amd->PacketDescriptions;
370 return noErr;
371 }
372 else
373 {
374 *ioNumberDataPackets = 0;
375 return -74;
376 }
377}
378
379/*
380 Get the length of the current frame. We need to be at the start of a
381 frame now. The buffer must have at least the four bytes for the header.
382 */
383static SInt32 Mp3GetPacketLength(const unsigned char* src)
384{
385 unsigned char mpegv;
386 unsigned short brate, srate;
387 unsigned int size;
388
389 /*
390 Check that our position looks like an MP3 header and see which type
391 of MP3 file we have.
392 */
393 if (src[0] == 0xff && src[1] >> 1 == 0x7d) mpegv = 0; /* MPEG-1 File */
394 else if (src[0] == 0xff && src[1] >> 1 == 0x79) mpegv = 1; /* MPEG-2 File */
395 else return -1;
396
397 /* Fill in bit rate and sample rate. */
398 brate = Mp3BitRates[mpegv][(src[2] & 0xf0) >> 4];
399 srate = Mp3SampleRates[mpegv][(src[2] & 0xc) >> 2];
400
401 /* Certain values for bit rate and sample rate are invalid. */
402 if (brate == 0 || srate == 0) return -1;
403
404 /* Compute frame size, round down */
405 size = 72 * (2 - mpegv) * brate * 1000 / srate;
406
407 /* If there is padding, add one byte */
408 if (src[2] & 0x2) return size + 1;
409 else return size;
410}
411
412/*
413 Apple's AudioFileStream does weird things so we deal with parsing the
414 file ourselves. It was also designed for a different use case, so this
415 is not unexpected. We expect to have MP3 data as input (i.e. we can only
416 deal with MPEG-1 or MPEG-2 Layer III), which simplifies parsing a bit. We
417 understand the ID3v2 header and skip over it. Whenever we have data we
418 want to skip at the beginning of the input, we do this by setting *ndst=0
419 and *nsrc to the length of the unwanted data and return no error.
420 */
421static LRESULT mp3_leopard_horse(PACMDRVSTREAMINSTANCE adsi,
422 unsigned char* src, LPDWORD nsrc,
423 unsigned char* dst, LPDWORD ndst)
424{
425 OSStatus err;
426 UInt32 size, aspdi, synci, syncSkip;
427 short framelen[4];
428 const unsigned char* psrc;
429 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
430
431 TRACE("ndst %u %p <- %u %p\n", *ndst, dst, *nsrc, src);
432
433 TRACE("First 16 bytes to input: %s\n", wine_dbgstr_an((const char *)src, 16));
434
435 /* Parse ID3 tag */
436 if (!memcmp(src, "ID3", 3) && amd->tagBytesLeft == -1)
437 {
438 amd->tagBytesLeft = (src[6] << 21) + (src[7] << 14) + (src[8] << 7) + src[9];
439 if (src[5] & 0x10) amd->tagBytesLeft += 20; /* There is a footer */
440 else amd->tagBytesLeft += 10;
441 }
442
443 /* Consume the tag */
444 if (amd->tagBytesLeft >= (SInt32)*nsrc)
445 {
446 *ndst = 0;
447 amd->tagBytesLeft -= *nsrc;
448
449 TRACE("All %d bytes of source data is ID3 tag\n", *nsrc);
450 return MMSYSERR_NOERROR;
451 }
452 else if (amd->tagBytesLeft > 0)
453 {
454 src += amd->tagBytesLeft;
455 *nsrc -= amd->tagBytesLeft;
456 TRACE("Skipping %ld for ID3 tag\n", amd->tagBytesLeft);
457 }
458
459 /*
460 Sync to initial MP3 frame. The largest possible MP3 frame is 1440.
461 Thus, in the first 1440 bytes we must find the beginning of 3 valid
462 frames in a row unless we reach the end of the file first.
463 */
464 syncSkip = 0;
465 for (psrc = src; psrc <= src + *nsrc - 4 && psrc < src + 1440; psrc++)
466 {
467 framelen[0] = 0;
468 for (synci = 1;
469 synci < 4 && psrc + framelen[synci-1] < src + *nsrc - 4;
470 synci++)
471 {
472 framelen[synci] = Mp3GetPacketLength(psrc + framelen[synci-1]);
473 if (framelen[synci] == -1)
474 {
475 synci = 0;
476 break;
477 }
478 framelen[synci] += framelen[synci-1];
479 }
480 if (synci > 0) /* We synced successfully */
481 {
482 if (psrc - src > 0)
483 {
484 syncSkip = psrc - src;
485 src += syncSkip;
486 *nsrc -= syncSkip;
487 TRACE("Skipping %ld for frame sync\n", syncSkip);
488 }
489 break;
490 }
491 }
492
493 if (Mp3GetPacketLength(src) == -1)
494 {
495 *ndst = *nsrc = 0;
496 ERR("Frame sync failed. Cannot play file.\n");
497 return MMSYSERR_ERROR;
498 }
499
500 /*
501 Fill in frame descriptions for all frames. We use an extra pointer
502 to keep track of our position in the input.
503 */
504
505 amd->NumberPackets = 25; /* This is the initial array capacity */
506 amd->PacketDescriptions = HeapAlloc(GetProcessHeap(), 0, amd->NumberPackets * sizeof(AudioStreamPacketDescription));
507 if (amd->PacketDescriptions == 0) return MMSYSERR_NOMEM;
508
509 for (aspdi = 0, psrc = src;
510 psrc <= src + *nsrc - 4;
511 psrc += amd->PacketDescriptions[aspdi].mDataByteSize, aspdi++)
512 {
513 /* Return an error if we can't read the frame header */
514 if (Mp3GetPacketLength(psrc) == -1)
515 {
516 *ndst = *nsrc = 0;
517 ERR("Invalid header at %p.\n", psrc);
518 HeapFree(GetProcessHeap(), 0, amd->PacketDescriptions);
519 return MMSYSERR_ERROR;
520 }
521
522 /* If we run out of space, double size and reallocate */
523 if (aspdi >= amd->NumberPackets)
524 {
525 amd->NumberPackets *= 2;
526 amd->PacketDescriptions = HeapReAlloc(GetProcessHeap(), 0, amd->PacketDescriptions, amd->NumberPackets * sizeof(AudioStreamPacketDescription));
527 if (amd->PacketDescriptions == 0) return MMSYSERR_NOMEM;
528 }
529
530 /* Fill in packet data */
531 amd->PacketDescriptions[aspdi].mStartOffset = psrc - src;
532 amd->PacketDescriptions[aspdi].mVariableFramesInPacket = 0;
533 amd->PacketDescriptions[aspdi].mDataByteSize = Mp3GetPacketLength(psrc);
534
535 /* If this brings us past the end, the last one doesn't count */
536 if (psrc + amd->PacketDescriptions[aspdi].mDataByteSize > src + *nsrc) break;
537 }
538
539 /* Fill in correct number of frames */
540 amd->NumberPackets = aspdi;
541
542 /* Adjust nsrc to only include full frames */
543 *nsrc = psrc - src;
544
545 amd->inBuffer.mDataByteSize = *nsrc;
546 amd->inBuffer.mData = src;
547 amd->inBuffer.mNumberChannels = amd->in.mChannelsPerFrame;
548
549 amd->outBuffer.mNumberBuffers = 1;
550 amd->outBuffer.mBuffers[0].mDataByteSize = *ndst;
551 amd->outBuffer.mBuffers[0].mData = dst;
552 amd->outBuffer.mBuffers[0].mNumberChannels = amd->out.mChannelsPerFrame;
553
554 /* Convert the data */
555 size = amd->outBuffer.mBuffers[0].mDataByteSize / amd->out.mBytesPerPacket;
556 err = AudioConverterFillComplexBuffer(amd->acr, Mp3AudioConverterComplexInputDataProc, amd, &size, &amd->outBuffer, 0);
557
558 HeapFree(GetProcessHeap(), 0, amd->PacketDescriptions);
559
560 /* Add skipped bytes back into *nsrc */
561 if (amd->tagBytesLeft > 0)
562 {
563 *nsrc += amd->tagBytesLeft;
564 amd->tagBytesLeft = 0;
565 }
566 *nsrc += syncSkip;
567
568 if (err != noErr && err != -74)
569 {
570 *ndst = *nsrc = 0;
571 ERR("Feed Error: %ld\n", err);
572 return MMSYSERR_ERROR;
573 }
574
575 *ndst = amd->outBuffer.mBuffers[0].mDataByteSize;
576
577 TRACE("convert %d -> %d\n", *nsrc, *ndst);
578
579 return MMSYSERR_NOERROR;
580}
581
582/***********************************************************************
583 * MPEG3_Reset
584 *
585 */
586static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
587{
588 AudioConverterReset(aad->acr);
589}
590
591/***********************************************************************
592 * MPEG3_StreamOpen
593 *
594 */
595static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
596{
597 AcmMpeg3Data* aad;
598
600
601 if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
602 MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
603 return ACMERR_NOTPOSSIBLE;
604
605 aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data));
606 if (aad == 0) return MMSYSERR_NOMEM;
607
608 adsi->dwDriver = (DWORD_PTR)aad;
609
613 {
614 OSStatus err;
615
616 aad->in.mSampleRate = adsi->pwfxSrc->nSamplesPerSec;
617 aad->out.mSampleRate = adsi->pwfxDst->nSamplesPerSec;
618 aad->in.mBitsPerChannel = adsi->pwfxSrc->wBitsPerSample;
619 aad->out.mBitsPerChannel = adsi->pwfxDst->wBitsPerSample;
620 aad->in.mFormatID = kAudioFormatMPEGLayer3;
621 aad->out.mFormatID = kAudioFormatLinearPCM;
622 aad->in.mChannelsPerFrame = adsi->pwfxSrc->nChannels;
623 aad->out.mChannelsPerFrame = adsi->pwfxDst->nChannels;
624 aad->in.mFormatFlags = 0;
625 aad->out.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
626 aad->in.mBytesPerFrame = 0;
627 aad->out.mBytesPerFrame = (aad->out.mBitsPerChannel * aad->out.mChannelsPerFrame) / 8;
628 aad->in.mBytesPerPacket = 0;
629 aad->out.mBytesPerPacket = aad->out.mBytesPerFrame;
630 aad->in.mFramesPerPacket = 0;
631 aad->out.mFramesPerPacket = 1;
632 aad->in.mReserved = aad->out.mReserved = 0;
633
634 aad->tagBytesLeft = -1;
635
636 aad->convert = mp3_leopard_horse;
637
638 err = AudioConverterNew(&aad->in, &aad->out, &aad->acr);
639 if (err != noErr)
640 {
641 ERR("Create failed: %ld\n", err);
642 }
643 else
644 {
645 MPEG3_Reset(adsi, aad);
646
647 return MMSYSERR_NOERROR;
648 }
649 }
650
651 HeapFree(GetProcessHeap(), 0, aad);
652 adsi->dwDriver = 0;
653
655}
656
657/***********************************************************************
658 * MPEG3_StreamClose
659 *
660 */
661static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)
662{
663 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
664
665 AudioConverterDispose(amd->acr);
666
667 HeapFree(GetProcessHeap(), 0, amd);
668 adsi->dwDriver = 0;
669
670 return MMSYSERR_NOERROR;
671}
672
673#endif
674
675/***********************************************************************
676 * MPEG3_DriverDetails
677 *
678 */
680{
683 add->wMid = MM_FRAUNHOFER_IIS;
685 add->vdwACM = 0x01000000;
686 add->vdwDriver = 0x01000000;
688 add->cFormatTags = 3; /* PCM, MPEG3 */
689 add->cFilterTags = 0;
690 add->hicon = NULL;
691 MultiByteToWideChar( CP_ACP, 0, "MPEG Layer-3 Codec", -1,
692 add->szShortName, ARRAY_SIZE( add->szShortName ));
693 MultiByteToWideChar( CP_ACP, 0, "Wine MPEG3 decoder", -1,
694 add->szLongName, ARRAY_SIZE( add->szLongName ));
695 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
696 add->szCopyright, ARRAY_SIZE( add->szCopyright ));
697 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
698 add->szLicensing, ARRAY_SIZE( add->szLicensing ));
699 add->szFeatures[0] = 0;
700
701 return MMSYSERR_NOERROR;
702}
703
704/***********************************************************************
705 * MPEG3_FormatTagDetails
706 *
707 */
709{
710 static const WCHAR szPcm[]={'P','C','M',0};
711 static const WCHAR szMpeg3[]={'M','P','e','g','3',0};
712 static const WCHAR szMpeg[]={'M','P','e','g',0};
713
714 switch (dwQuery)
715 {
717 if (aftd->dwFormatTagIndex > 2) return ACMERR_NOTPOSSIBLE;
718 break;
720 if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
721 {
722 aftd->dwFormatTagIndex = 2; /* WAVE_FORMAT_MPEG is biggest */
723 break;
724 }
725 /* fall through */
727 switch (aftd->dwFormatTag)
728 {
729 case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
730 case WAVE_FORMAT_MPEGLAYER3: aftd->dwFormatTagIndex = 1; break;
731 case WAVE_FORMAT_MPEG: aftd->dwFormatTagIndex = 2; break;
732 default: return ACMERR_NOTPOSSIBLE;
733 }
734 break;
735 default:
736 WARN("Unsupported query %08x\n", dwQuery);
738 }
739
741 switch (aftd->dwFormatTagIndex)
742 {
743 case 0:
745 aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
747 lstrcpyW(aftd->szFormatTag, szPcm);
748 break;
749 case 1:
751 aftd->cbFormatSize = sizeof(MPEGLAYER3WAVEFORMAT);
752 aftd->cStandardFormats = 0;
753 lstrcpyW(aftd->szFormatTag, szMpeg3);
754 break;
755 case 2:
757 aftd->cbFormatSize = sizeof(MPEG1WAVEFORMAT);
758 aftd->cStandardFormats = 0;
759 lstrcpyW(aftd->szFormatTag, szMpeg);
760 break;
761 }
762 return MMSYSERR_NOERROR;
763}
764
765/***********************************************************************
766 * MPEG3_FormatDetails
767 *
768 */
770{
771 switch (dwQuery)
772 {
774 if (MPEG3_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
775 break;
777 afd->pwfx->wFormatTag = afd->dwFormatTag;
778 switch (afd->dwFormatTag)
779 {
780 case WAVE_FORMAT_PCM:
785 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
786 * afd->pwfx->cbSize = 0;
787 */
788 afd->pwfx->nBlockAlign =
789 (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
790 afd->pwfx->nAvgBytesPerSec =
791 afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
792 break;
794 case WAVE_FORMAT_MPEG:
795 WARN("Encoding to MPEG is not supported\n");
796 return ACMERR_NOTPOSSIBLE;
797 default:
798 WARN("Unsupported tag %08x\n", afd->dwFormatTag);
799 return MMSYSERR_INVALPARAM;
800 }
801 break;
802 default:
803 WARN("Unsupported query %08x\n", dwQuery);
805 }
807 afd->szFormat[0] = 0; /* let MSACM format this for us... */
808
809 return MMSYSERR_NOERROR;
810}
811
812/***********************************************************************
813 * MPEG3_FormatSuggest
814 *
815 */
817{
818 /* some tests ... */
819 if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
820 adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
821 MPEG3_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
822 /* FIXME: should do those tests against the real size (according to format tag */
823
824 /* If no suggestion for destination, then copy source value */
826 adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
830 adfs->pwfxDst->wBitsPerSample = 16;
832 {
833 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
834 {
835 WARN("Encoding to MPEG is not supported\n");
836 return ACMERR_NOTPOSSIBLE;
837 }
838 else
840 }
841
842 /* check if result is ok */
843 if (MPEG3_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
844
845 /* recompute other values */
846 switch (adfs->pwfxDst->wFormatTag)
847 {
848 case WAVE_FORMAT_PCM:
849 adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
851 break;
852 case WAVE_FORMAT_MPEG:
854 WARN("Encoding to MPEG is not supported\n");
855 return ACMERR_NOTPOSSIBLE;
856 break;
857 default:
858 FIXME("\n");
859 break;
860 }
861
862 return MMSYSERR_NOERROR;
863}
864
865/***********************************************************************
866 * MPEG3_StreamSize
867 *
868 */
870{
871 DWORD nblocks;
872
873 switch (adss->fdwSize)
874 {
876 /* cbDstLength => cbSrcLength */
877 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
880 {
881 nblocks = (adss->cbDstLength - 3000) / (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
882 if (nblocks == 0)
883 return ACMERR_NOTPOSSIBLE;
884 adss->cbSrcLength = nblocks * 1152 * adsi->pwfxSrc->nBlockAlign;
885 }
886 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
889 {
890 nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * 1152);
891 if (nblocks == 0)
892 return ACMERR_NOTPOSSIBLE;
893 adss->cbSrcLength = nblocks * (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);
894 }
895 else
896 {
898 }
899 break;
901 /* cbSrcLength => cbDstLength */
902 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
905 {
906 nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * 1152);
907 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nBlockAlign * 1152))
908 /* Round block count up. */
909 nblocks++;
910 if (nblocks == 0)
911 return ACMERR_NOTPOSSIBLE;
912 adss->cbDstLength = 3000 + nblocks * (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
913 }
914 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
917 {
918 nblocks = adss->cbSrcLength / (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);
919 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec))
920 /* Round block count up. */
921 nblocks++;
922 if (nblocks == 0)
923 return ACMERR_NOTPOSSIBLE;
924 adss->cbDstLength = nblocks * 1152 * adsi->pwfxDst->nBlockAlign;
925 }
926 else
927 {
929 }
930 break;
931 default:
932 WARN("Unsupported query %08x\n", adss->fdwSize);
934 }
935 return MMSYSERR_NOERROR;
936}
937
938/***********************************************************************
939 * MPEG3_StreamConvert
940 *
941 */
943{
944 AcmMpeg3Data* aad = (AcmMpeg3Data*)adsi->dwDriver;
945 DWORD nsrc = adsh->cbSrcLength;
946 DWORD ndst = adsh->cbDstLength;
947
948 if (adsh->fdwConvert &
952 {
953 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
954 }
955 /* ACM_STREAMCONVERTF_BLOCKALIGN
956 * currently all conversions are block aligned, so do nothing for this flag
957 * ACM_STREAMCONVERTF_END
958 * no pending data, so do nothing for this flag
959 */
961 {
962 MPEG3_Reset(adsi, aad);
963 }
964
965 aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
966 adsh->cbSrcLengthUsed = nsrc;
967 adsh->cbDstLengthUsed = ndst;
968
969 return MMSYSERR_NOERROR;
970}
971
972/**************************************************************************
973 * MPEG3_DriverProc [exported]
974 */
975LRESULT CALLBACK MPEG3_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
976 LPARAM dwParam1, LPARAM dwParam2)
977{
978 TRACE("(%08lx %p %04x %08lx %08lx);\n",
979 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
980
981 switch (wMsg)
982 {
983 case DRV_LOAD: return 1;
984 case DRV_FREE: return 1;
985 case DRV_OPEN: return MPEG3_drvOpen((LPSTR)dwParam1);
986 case DRV_CLOSE: return MPEG3_drvClose(dwDevID);
987 case DRV_ENABLE: return 1;
988 case DRV_DISABLE: return 1;
989 case DRV_QUERYCONFIGURE: return 1;
990 case DRV_CONFIGURE: MessageBoxA(0, "MPEG3 filter !", "Wine Driver", MB_OK); return 1;
991 case DRV_INSTALL: return DRVCNF_RESTART;
992 case DRV_REMOVE: return DRVCNF_RESTART;
993
995 /* no caching from other ACM drivers is done so far */
996 return MMSYSERR_NOERROR;
997
999 return MPEG3_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1000
1002 return MPEG3_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
1003
1005 return MPEG3_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1006
1008 return MPEG3_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
1009
1010 case ACMDM_STREAM_OPEN:
1011 return MPEG3_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
1012
1013 case ACMDM_STREAM_CLOSE:
1014 return MPEG3_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
1015
1016 case ACMDM_STREAM_SIZE:
1017 return MPEG3_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
1018
1021
1024 /* this converter is not a hardware driver */
1027 /* this converter is not a filter */
1028 case ACMDM_STREAM_RESET:
1029 /* only needed for asynchronous driver... we aren't, so just say it */
1030 return MMSYSERR_NOTSUPPORTED;
1033 /* nothing special to do here... so don't do anything */
1034 return MMSYSERR_NOERROR;
1035
1036 default:
1037 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1038 }
1039}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#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:114
#define WARN(fmt,...)
Definition: debug.h:115
#define ERR(fmt,...)
Definition: debug.h:113
DWORD UInt32
Definition: chm_lib.c:104
#define NULL
Definition: types.h:112
const char * wine_dbgstr_an(const char *str, int n)
Definition: compat.c:313
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CALLBACK
Definition: compat.h:35
#define lstrcpyW
Definition: compat.h:749
#define MultiByteToWideChar
Definition: compat.h:110
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
GLsizeiptr size
Definition: glext.h:5919
GLenum src
Definition: glext.h:6340
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
@ MPG123_NEED_MORE
Definition: mpg123.h:381
@ MPG123_ERR
Definition: mpg123.h:382
@ MPG123_NEW_FORMAT
Definition: mpg123.h:380
@ MPG123_OK
Definition: mpg123.h:383
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh)
Definition: libmpg123.c:1712
MPG123_EXPORT void mpg123_exit(void)
Definition: libmpg123.c:50
MPG123_EXPORT int mpg123_param(mpg123_handle *mh, enum mpg123_parms type, long value, double fvalue)
Definition: libmpg123.c:127
MPG123_EXPORT int mpg123_init(void)
Definition: libmpg123.c:23
MPG123_EXPORT mpg123_handle * mpg123_new(const char *decoder, int *error)
Definition: libmpg123.c:57
@ MPG123_IGNORE_INFOFRAME
Definition: mpg123.h:228
@ MPG123_ADD_FLAGS
Definition: mpg123.h:185
MPG123_EXPORT int mpg123_open_feed(mpg123_handle *mh)
Definition: libmpg123.c:535
MPG123_EXPORT int mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
Definition: libmpg123.c:947
MPG123_EXPORT int mpg123_close(mpg123_handle *mh)
Definition: libmpg123.c:1694
MPG123_EXPORT int mpg123_read(mpg123_handle *mh, void *outmemory, size_t outmemsize, size_t *done)
Definition: libmpg123.c:942
MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
Definition: libmpg123.c:1141
MPG123_EXPORT off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
Definition: lfs_wrap.c:291
#define DRV_LOAD(x)
#define SEEK_SET
Definition: jmemansi.c:26
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
#define MM_FRAUNHOFER_IIS
Definition: mmreg.h:152
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
#define MPEGLAYER3_ID_MPEG
Definition: mmreg.h:442
#define WAVE_FORMAT_MPEG
Definition: mmreg.h:126
#define MPEGLAYER3_WFX_EXTRA_BYTES
Definition: mmreg.h:439
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
struct mpeglayer3waveformat_tag MPEGLAYER3WAVEFORMAT
struct mpeg1waveformat_tag MPEG1WAVEFORMAT
#define MM_FHGIIS_MPEGLAYER3_DECODE
Definition: mmreg.h:153
#define DRV_CLOSE
Definition: mmsystem.h:122
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define DRV_ENABLE
Definition: mmsystem.h:120
#define DRV_CONFIGURE
Definition: mmsystem.h:125
#define DRV_OPEN
Definition: mmsystem.h:121
struct pcmwaveformat_tag PCMWAVEFORMAT
#define DRV_INSTALL
Definition: mmsystem.h:127
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define DRV_FREE
Definition: mmsystem.h:124
#define DRV_DISABLE
Definition: mmsystem.h:123
static struct fmt fmts[]
static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
Definition: mpegl3.c:942
static DWORD MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
Definition: mpegl3.c:95
static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
Definition: mpegl3.c:816
LRESULT CALLBACK MPEG3_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
Definition: mpegl3.c:975
static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
Definition: mpegl3.c:708
static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
Definition: mpegl3.c:869
static LRESULT MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
Definition: mpegl3.c:769
static const Format MPEG3_Formats[]
Definition: mpegl3.c:79
static LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add)
Definition: mpegl3.c:679
static const Format PCM_Formats[]
Definition: mpegl3.c:66
int convert
Definition: msacm.c:1374
#define ACM_STREAMCONVERTF_START
Definition: msacm.h:206
#define ACM_FORMATTAGDETAILSF_FORMATTAG
Definition: msacm.h:183
#define ACM_STREAMCONVERTF_BLOCKALIGN
Definition: msacm.h:205
#define ACM_STREAMOPENF_ASYNC
Definition: msacm.h:214
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
Definition: msacm.h:59
#define ACM_FORMATSUGGESTF_WFORMATTAG
Definition: msacm.h:174
#define ACM_FORMATSUGGESTF_NCHANNELS
Definition: msacm.h:175
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
#define ACM_FORMATDETAILSF_FORMAT
Definition: msacm.h:161
#define ACM_STREAMSIZEF_SOURCE
Definition: msacm.h:217
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE
Definition: msacm.h:184
#define ACM_STREAMSIZEF_DESTINATION
Definition: msacm.h:218
#define ACM_FORMATDETAILSF_INDEX
Definition: msacm.h:160
#define ACM_FORMATTAGDETAILSF_INDEX
Definition: msacm.h:182
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE
Definition: msacm.h:177
#define ACM_STREAMCONVERTF_END
Definition: msacm.h:207
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
Definition: msacm.h:58
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC
Definition: msacm.h:176
#define ACMDM_STREAM_PREPARE
Definition: msacmdrv.h:63
#define ACMDM_STREAM_CLOSE
Definition: msacmdrv.h:59
#define ACMDM_STREAM_CONVERT
Definition: msacmdrv.h:61
#define ACMDM_FORMAT_SUGGEST
Definition: msacmdrv.h:53
#define ACMDM_FILTER_DETAILS
Definition: msacmdrv.h:56
#define ACMDM_HARDWARE_WAVE_CAPS_INPUT
Definition: msacmdrv.h:48
#define ACMDM_DRIVER_NOTIFY
Definition: msacmdrv.h:45
#define ACMDM_FORMAT_DETAILS
Definition: msacmdrv.h:52
#define ACMDM_STREAM_SIZE
Definition: msacmdrv.h:60
#define ACMDM_FILTERTAG_DETAILS
Definition: msacmdrv.h:55
#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
Definition: msacmdrv.h:49
#define ACMDM_FORMATTAG_DETAILS
Definition: msacmdrv.h:51
#define ACMDM_STREAM_UNPREPARE
Definition: msacmdrv.h:64
#define ACMDM_STREAM_OPEN
Definition: msacmdrv.h:58
#define ACMDM_DRIVER_DETAILS
Definition: msacmdrv.h:46
#define ACMDM_STREAM_RESET
Definition: msacmdrv.h:62
unsigned int UINT
Definition: ndis.h:50
#define LPDWORD
Definition: nt_native.h:46
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
#define LRESULT
Definition: ole.h:14
int nBits
Definition: pcmconverter.c:96
int rate
Definition: pcmconverter.c:97
int nChannels
Definition: pcmconverter.c:95
int This channels
Definition: rdpsnd_libao.c:37
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
const WCHAR * str
PFIXED_SENSE_DATA outBuffer
Definition: scsi.h:4022
#define TRACE(s)
Definition: solgame.cpp:4
int nChannels
Definition: imaadp32.c:63
int nBits
Definition: imaadp32.c:64
int rate
Definition: imaadp32.c:65
DWORD cFilterTags
Definition: msacm.h:311
WCHAR szCopyright[ACMDRIVERDETAILS_COPYRIGHT_CHARS]
Definition: msacm.h:317
WCHAR szLongName[ACMDRIVERDETAILS_LONGNAME_CHARS]
Definition: msacm.h:316
WCHAR szShortName[ACMDRIVERDETAILS_SHORTNAME_CHARS]
Definition: msacm.h:315
FOURCC fccComp
Definition: msacm.h:301
WCHAR szLicensing[ACMDRIVERDETAILS_LICENSING_CHARS]
Definition: msacm.h:318
FOURCC fccType
Definition: msacm.h:300
WCHAR szFeatures[ACMDRIVERDETAILS_FEATURES_CHARS]
Definition: msacm.h:319
DWORD cFormatTags
Definition: msacm.h:310
DWORD fdwSupport
Definition: msacm.h:309
DWORD vdwDriver
Definition: msacm.h:307
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:151
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:153
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]
Definition: msacm.h:509
DWORD dwFormatTag
Definition: msacm.h:505
DWORD dwFormatIndex
Definition: msacm.h:504
DWORD fdwSupport
Definition: msacm.h:506
PWAVEFORMATEX pwfx
Definition: msacm.h:507
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
Definition: msacm.h:535
DWORD dwFormatTagIndex
Definition: msacm.h:530
DWORD cStandardFormats
Definition: msacm.h:534
WORD nBlockAlign
Definition: mmreg.h:82
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
#define DWORD_PTR
Definition: treelist.c:76
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t * LPDWORD
Definition: typedefs.h:59
int ret
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
__wchar_t WCHAR
Definition: xmlstorage.h:180