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