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