ReactOS  0.4.14-dev-606-g14ebc0b
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  */
59 typedef struct
60 {
61  int nChannels;
62  int nBits;
63  int rate;
64 } Format;
65 
66 static 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 
79 static 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:
103  hi = ARRAY_SIZE(PCM_Formats);
104  fmts = PCM_Formats;
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 
128 typedef struct tagAcmMpeg3Data
129 {
131  const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
132  mpg123_handle *mh;
133 } AcmMpeg3Data;
134 
135 /***********************************************************************
136  * MPEG3_drvOpen
137  */
138 static LRESULT MPEG3_drvOpen(LPCSTR str)
139 {
140  mpg123_init();
141  return 1;
142 }
143 
144 /***********************************************************************
145  * MPEG3_drvClose
146  */
147 static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
148 {
149  mpg123_exit();
150  return 1;
151 }
152 
153 
154 static 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  */
202 static 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  */
213 static 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 ||
236  adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
238  {
240  {
241  MPEGLAYER3WAVEFORMAT *formatmp3 = (MPEGLAYER3WAVEFORMAT *)adsi->pwfxSrc;
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  */
293 static 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 
303 static 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 
309 static const unsigned short Mp3SampleRates[2][4] =
310 {
311  {44100, 48000, 32000, 0},
312  {22050, 24000, 16000, 0}
313 };
314 
315 typedef 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  */
334 static LRESULT MPEG3_drvOpen(LPCSTR str)
335 {
336  return 1;
337 }
338 
339 /***********************************************************************
340  * MPEG3_drvClose
341  */
342 static 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  */
352 static 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  */
383 static 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  */
421 static 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  */
586 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
587 {
588  AudioConverterReset(aad->acr);
589 }
590 
591 /***********************************************************************
592  * MPEG3_StreamOpen
593  *
594  */
595 static 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 
610  if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
611  adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
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 
654  return MMSYSERR_NOTSUPPORTED;
655 }
656 
657 /***********************************************************************
658  * MPEG3_StreamClose
659  *
660  */
661 static 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;
687  add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
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);
737  return MMSYSERR_NOTSUPPORTED;
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);
804  return MMSYSERR_NOTSUPPORTED;
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 ||
887  adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
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  {
897  return MMSYSERR_NOTSUPPORTED;
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 ||
915  adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
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  {
928  return MMSYSERR_NOTSUPPORTED;
929  }
930  break;
931  default:
932  WARN("Unsupported query %08x\n", adss->fdwSize);
933  return MMSYSERR_NOTSUPPORTED;
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  */
960  if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
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  */
975 LRESULT 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 
994  case ACMDM_DRIVER_NOTIFY:
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 
1004  case ACMDM_FORMAT_DETAILS:
1005  return MPEG3_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1006 
1007  case ACMDM_FORMAT_SUGGEST:
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 
1019  case ACMDM_STREAM_CONVERT:
1020  return MPEG3_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
1021 
1024  /* this converter is not a hardware driver */
1026  case ACMDM_FILTER_DETAILS:
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;
1031  case ACMDM_STREAM_PREPARE:
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 }
PWAVEFORMATEX pwfx
Definition: msacm.h:507
#define DRV_DISABLE
Definition: mmsystem.h:123
LRESULT CALLBACK MPEG3_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg, LPARAM dwParam1, LPARAM dwParam2)
Definition: mpegl3.c:975
#define WAVE_FORMAT_UNKNOWN
Definition: mmreg.h:95
int add
Definition: i386-dis.c:3122
#define ACM_STREAMSIZEF_DESTINATION
Definition: msacm.h:218
MPG123_EXPORT int mpg123_open_feed(mpg123_handle *mh)
Definition: libmpg123.c:468
MPG123_EXPORT off_t mpg123_feedseek(mpg123_handle *mh, off_t sampleoff, int whence, off_t *input_offset)
Definition: lfs_wrap.c:291
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define ACM_FORMATSUGGESTF_NSAMPLESPERSEC
Definition: msacm.h:176
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define DWORD_PTR
Definition: treelist.c:76
#define error(str)
Definition: mkdosfs.c:1605
#define ACM_STREAMCONVERTF_BLOCKALIGN
Definition: msacm.h:205
WINE_DEFAULT_DEBUG_CHANNEL(mpeg3)
DWORD UInt32
Definition: chm_lib.c:104
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:153
#define MM_FHGIIS_MPEGLAYER3_DECODE
Definition: mmreg.h:153
#define MPEGLAYER3_WFX_EXTRA_BYTES
Definition: mmreg.h:439
#define CP_ACP
Definition: compat.h:99
DWORD nAvgBytesPerSec
Definition: mmreg.h:81
MPG123_EXPORT int mpg123_getformat(mpg123_handle *mh, long *rate, int *channels, int *encoding)
Definition: libmpg123.c:1066
WORD nChannels
Definition: mmreg.h:79
#define WARN(fmt,...)
Definition: debug.h:111
#define ACMDRIVERDETAILS_SUPPORTF_CODEC
Definition: msacm.h:61
#define ACMDM_STREAM_RESET
Definition: msacmdrv.h:62
#define CALLBACK
Definition: compat.h:27
#define ACM_FORMATSUGGESTF_WFORMATTAG
Definition: msacm.h:174
static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
Definition: mpegl3.c:816
int nChannels
Definition: imaadp32.c:63
#define assert(x)
Definition: debug.h:53
MPG123_EXPORT mpg123_handle * mpg123_new(const char *decoder, int *error)
Definition: libmpg123.c:55
#define DRV_CLOSE
Definition: mmsystem.h:122
int This channels
Definition: rdpsnd_libao.c:37
int nBits
Definition: imaadp32.c:64
int rate
Definition: pcmconverter.c:97
#define ACMDM_STREAM_OPEN
Definition: msacmdrv.h:58
#define ACMDM_FORMATTAG_DETAILS
Definition: msacmdrv.h:51
char * LPSTR
Definition: xmlstorage.h:182
#define ACMDM_STREAM_PREPARE
Definition: msacmdrv.h:63
struct pcmwaveformat_tag PCMWAVEFORMAT
int nChannels
Definition: pcmconverter.c:95
MPG123_EXPORT int mpg123_init(void)
Definition: libmpg123.c:22
#define DWORD
Definition: nt_native.h:44
#define ACM_STREAMCONVERTF_END
Definition: msacm.h:207
#define WAVE_FORMAT_MPEG
Definition: mmreg.h:126
#define ACMDM_STREAM_CLOSE
Definition: msacmdrv.h:59
#define DRV_QUERYCONFIGURE
Definition: mmsystem.h:126
#define DRV_OPEN
Definition: mmsystem.h:121
int WINAPI MessageBoxA(_In_opt_ HWND, _In_opt_ LPCSTR, _In_opt_ LPCSTR, _In_ UINT)
#define ACMDM_DRIVER_NOTIFY
Definition: msacmdrv.h:45
#define ACMDM_FORMAT_SUGGEST
Definition: msacmdrv.h:53
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
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 WAVE_FORMAT_PCM
Definition: constants.h:425
#define ACM_FORMATDETAILSF_FORMAT
Definition: msacm.h:161
MPG123_EXPORT int mpg123_param(mpg123_handle *mh, enum mpg123_parms type, long value, double fvalue)
Definition: libmpg123.c:125
static LRESULT MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
Definition: mpegl3.c:769
MPG123_EXPORT int mpg123_feed(mpg123_handle *mh, const unsigned char *in, size_t size)
Definition: libmpg123.c:873
#define ACMDM_DRIVER_DETAILS
Definition: msacmdrv.h:46
static const Format MPEG3_Formats[]
Definition: mpegl3.c:79
#define ACMDM_STREAM_CONVERT
Definition: msacmdrv.h:61
#define FIXME(fmt,...)
Definition: debug.h:110
MPG123_EXPORT int mpg123_close(mpg123_handle *mh)
Definition: libmpg123.c:1602
static struct fmt fmts[]
DWORD cStandardFormats
Definition: msacm.h:534
#define ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
Definition: msacm.h:59
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
#define ACM_FORMATSUGGESTF_NCHANNELS
Definition: msacm.h:175
#define DRV_LOAD(x)
struct mpeg1waveformat_tag MPEG1WAVEFORMAT
MPG123_EXPORT void mpg123_delete(mpg123_handle *mh)
Definition: libmpg123.c:1620
const char * LPCSTR
Definition: xmlstorage.h:183
int nBits
Definition: pcmconverter.c:96
#define DRVCNF_RESTART
Definition: mmsystem.h:135
#define DRV_REMOVE
Definition: mmsystem.h:128
#define ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
Definition: msacmdrv.h:49
#define ACMDM_HARDWARE_WAVE_CAPS_INPUT
Definition: msacmdrv.h:48
#define MPEGLAYER3_ID_MPEG
Definition: mmreg.h:442
PWAVEFORMATEX pwfxDst
Definition: msacmdrv.h:101
#define SEEK_SET
Definition: jmemansi.c:26
static LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add)
Definition: mpegl3.c:679
#define TRACE(s)
Definition: solgame.cpp:4
#define ACM_FORMATTAGDETAILSF_FORMATTAG
Definition: msacm.h:183
GLsizeiptr size
Definition: glext.h:5919
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define DRV_CONFIGURE
Definition: mmsystem.h:125
int convert
Definition: msacm.c:1374
const char * wine_dbgstr_an(const char *str, int n)
Definition: compat.c:288
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ACM_STREAMSIZEF_SOURCE
Definition: msacm.h:217
#define ACM_FORMATTAGDETAILSF_INDEX
Definition: msacm.h:182
static DWORD MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
Definition: mpegl3.c:95
#define MM_FRAUNHOFER_IIS
Definition: mmreg.h:152
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
Definition: mpegl3.c:708
WCHAR szFormat[ACMFORMATDETAILS_FORMAT_CHARS]
Definition: msacm.h:509
#define ACM_STREAMOPENF_ASYNC
Definition: msacm.h:214
#define DRV_FREE
Definition: mmsystem.h:124
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
WORD wFormatTag
Definition: mmreg.h:78
#define ACMDM_FILTERTAG_DETAILS
Definition: msacmdrv.h:55
DWORD dwFormatIndex
Definition: msacm.h:504
int ret
#define LPDWORD
Definition: nt_native.h:46
static const WCHAR L[]
Definition: oid.c:1250
MPG123_EXPORT int mpg123_read(mpg123_handle *mh, unsigned char *outmemory, size_t outmemsize, size_t *done)
Definition: libmpg123.c:868
#define WAVE_FORMAT_MPEGLAYER3
Definition: mmreg.h:127
#define LRESULT
Definition: ole.h:14
#define ACM_FORMATTAGDETAILSF_LARGESTSIZE
Definition: msacm.h:184
GLenum src
Definition: glext.h:6340
#define err(...)
struct mpeglayer3waveformat_tag MPEGLAYER3WAVEFORMAT
DWORD dwFormatTagIndex
Definition: msacm.h:530
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define ACMERR_NOTPOSSIBLE
Definition: msacm.h:36
#define ACMDM_STREAM_UNPREPARE
Definition: msacmdrv.h:64
#define DRV_ENABLE
Definition: mmsystem.h:120
#define ERR(fmt,...)
Definition: debug.h:109
#define ACM_STREAMCONVERTF_START
Definition: msacm.h:206
#define lstrcpyW
Definition: compat.h:414
GLuint in
Definition: glext.h:9616
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define ARRAY_SIZE(a)
Definition: main.h:24
static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
Definition: mpegl3.c:942
DWORD fdwSupport
Definition: msacm.h:506
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:151
#define HeapReAlloc
Definition: compat.h:401
WORD cbSize
Definition: mmreg.h:84
GLenum GLenum dst
Definition: glext.h:6340
DWORD_PTR dwDriver
Definition: msacmdrv.h:107
unsigned int UINT
Definition: ndis.h:50
#define MB_OK
Definition: winuser.h:784
WCHAR szFormatTag[ACMFORMATTAGDETAILS_FORMATTAG_CHARS]
Definition: msacm.h:535
#define MultiByteToWideChar
Definition: compat.h:100
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3706
MPG123_EXPORT void mpg123_exit(void)
Definition: libmpg123.c:49
DWORD nSamplesPerSec
Definition: mmreg.h:80
WORD nBlockAlign
Definition: mmreg.h:82
#define ACM_FORMATDETAILSF_INDEX
Definition: msacm.h:160
int rate
Definition: imaadp32.c:65
static const Format PCM_Formats[]
Definition: mpegl3.c:66
uint32_t * LPDWORD
Definition: typedefs.h:57
WORD wBitsPerSample
Definition: mmreg.h:83
PWAVEFORMATEX pwfxSrc
Definition: msacmdrv.h:100
#define DRV_INSTALL
Definition: mmsystem.h:127
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv, UINT Msg, LPARAM lParam1, LPARAM lParam2)
Definition: driver.c:554
LONG_PTR LRESULT
Definition: windef.h:209
DWORD dwFormatTag
Definition: msacm.h:505
#define HeapFree(x, y, z)
Definition: compat.h:402
#define ACM_FORMATSUGGESTF_WBITSPERSAMPLE
Definition: msacm.h:177
#define ACMDM_FORMAT_DETAILS
Definition: msacmdrv.h:52
static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
Definition: mpegl3.c:869
#define ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
Definition: msacm.h:58
ACPI_BUFFER *RetBuffer ACPI_BUFFER *RetBuffer char ACPI_WALK_RESOURCE_CALLBACK void *Context ACPI_BUFFER *RetBuffer UINT16 ACPI_RESOURCE **ResourcePtr ACPI_GENERIC_ADDRESS *Reg UINT32 *ReturnValue UINT8 UINT8 *Slp_TypB ACPI_PHYSICAL_ADDRESS PhysicalAddress64 UINT32 UINT32 *TimeElapsed UINT32 ACPI_STATUS const char * Format
Definition: acpixf.h:1212
#define ACMDM_STREAM_SIZE
Definition: msacmdrv.h:60
#define ACMDM_FILTER_DETAILS
Definition: msacmdrv.h:56