xref: /reactos/dll/win32/winemp3.acm/mpegl3.c (revision 139a3d66)
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 
54 WINE_DEFAULT_DEBUG_CHANNEL(mpeg3);
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  */
95 static	DWORD	MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
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:
107     case WAVE_FORMAT_MPEGLAYER3:
108 	hi = ARRAY_SIZE(MPEG3_Formats);
109 	fmts = MPEG3_Formats;
110 	break;
111     default:
112 	return 0xFFFFFFFF;
113     }
114 
115     for (i = 0; i < hi; i++)
116     {
117 	if (wfx->nChannels == fmts[i].nChannels &&
118 	    wfx->nSamplesPerSec == fmts[i].rate &&
119 	    (wfx->wBitsPerSample == fmts[i].nBits || !fmts[i].nBits))
120 	    return i;
121     }
122 
123     return 0xFFFFFFFF;
124 }
125 
126 #ifdef HAVE_MPG123_H
127 
128 typedef struct tagAcmMpeg3Data
129 {
130     void (*convert)(PACMDRVSTREAMINSTANCE adsi,
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 {
215     LRESULT error = MMSYSERR_NOTSUPPORTED;
216     AcmMpeg3Data*	aad;
217     int err;
218 
219     assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
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 &&
231 	adsi->pwfxDst->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) &&
237              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
238     {
239         if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
240         {
241             MPEGLAYER3WAVEFORMAT *formatmp3 = (MPEGLAYER3WAVEFORMAT *)adsi->pwfxSrc;
242 
243             if (adsi->pwfxSrc->cbSize < MPEGLAYER3_WFX_EXTRA_BYTES ||
244                 formatmp3->wID != MPEGLAYER3_ID_MPEG)
245             {
246                 error = ACMERR_NOTPOSSIBLE;
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          */
268         mpg123_param(aad->mh, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0);
269 #endif
270     }
271     else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
272              (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
273               adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
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 
599     assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
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) &&
612         adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
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  */
679 static	LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add)
680 {
681     add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
682     add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
683     add->wMid = MM_FRAUNHOFER_IIS;
684     add->wPid = MM_FHGIIS_MPEGLAYER3_DECODE;
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  */
708 static	LRESULT	MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
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     {
716     case ACM_FORMATTAGDETAILSF_INDEX:
717 	if (aftd->dwFormatTagIndex > 2) return ACMERR_NOTPOSSIBLE;
718 	break;
719     case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
720 	if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
721         {
722             aftd->dwFormatTagIndex = 2; /* WAVE_FORMAT_MPEG is biggest */
723 	    break;
724 	}
725 	/* fall through */
726     case ACM_FORMATTAGDETAILSF_FORMATTAG:
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 
740     aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
741     switch (aftd->dwFormatTagIndex)
742     {
743     case 0:
744 	aftd->dwFormatTag = WAVE_FORMAT_PCM;
745 	aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
746 	aftd->cStandardFormats = ARRAY_SIZE(PCM_Formats);
747         lstrcpyW(aftd->szFormatTag, szPcm);
748         break;
749     case 1:
750 	aftd->dwFormatTag = WAVE_FORMAT_MPEGLAYER3;
751 	aftd->cbFormatSize = sizeof(MPEGLAYER3WAVEFORMAT);
752         aftd->cStandardFormats = 0;
753         lstrcpyW(aftd->szFormatTag, szMpeg3);
754 	break;
755     case 2:
756 	aftd->dwFormatTag = WAVE_FORMAT_MPEG;
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  */
769 static	LRESULT	MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
770 {
771     switch (dwQuery)
772     {
773     case ACM_FORMATDETAILSF_FORMAT:
774 	if (MPEG3_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
775 	break;
776     case ACM_FORMATDETAILSF_INDEX:
777 	afd->pwfx->wFormatTag = afd->dwFormatTag;
778 	switch (afd->dwFormatTag)
779         {
780 	case WAVE_FORMAT_PCM:
781 	    if (afd->dwFormatIndex >= ARRAY_SIZE(PCM_Formats)) return ACMERR_NOTPOSSIBLE;
782 	    afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
783 	    afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
784 	    afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
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;
793 	case WAVE_FORMAT_MPEGLAYER3:
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     }
806     afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
807     afd->szFormat[0] = 0; /* let MSACM format this for us... */
808 
809     return MMSYSERR_NOERROR;
810 }
811 
812 /***********************************************************************
813  *           MPEG3_FormatSuggest
814  *
815  */
816 static	LRESULT	MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
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 */
825     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
826 	adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
827     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
828         adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
829     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
830         adfs->pwfxDst->wBitsPerSample = 16;
831     if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
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
839             adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
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;
850         adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
851         break;
852     case WAVE_FORMAT_MPEG:
853     case WAVE_FORMAT_MPEGLAYER3:
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  */
869 static	LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
870 {
871     DWORD nblocks;
872 
873     switch (adss->fdwSize)
874     {
875     case ACM_STREAMSIZEF_DESTINATION:
876 	/* cbDstLength => cbSrcLength */
877 	if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
878             (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
879              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
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) &&
888                  adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
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;
900     case ACM_STREAMSIZEF_SOURCE:
901 	/* cbSrcLength => cbDstLength */
902 	if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
903             (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
904              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
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) &&
916                  adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
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  */
942 static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
943 {
944     AcmMpeg3Data*	aad = (AcmMpeg3Data*)adsi->dwDriver;
945     DWORD		nsrc = adsh->cbSrcLength;
946     DWORD		ndst = adsh->cbDstLength;
947 
948     if (adsh->fdwConvert &
949 	~(ACM_STREAMCONVERTF_BLOCKALIGN|
950 	  ACM_STREAMCONVERTF_END|
951 	  ACM_STREAMCONVERTF_START))
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 
998     case ACMDM_DRIVER_DETAILS:
999 	return MPEG3_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1000 
1001     case ACMDM_FORMATTAG_DETAILS:
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 
1022     case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
1023     case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
1024 	/* this converter is not a hardware driver */
1025     case ACMDM_FILTERTAG_DETAILS:
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:
1032     case ACMDM_STREAM_UNPREPARE:
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 }
1040