[WINEMP3.ACM] Sync with Wine Staging 2.16. CORE-13762
[reactos.git] / reactos / 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 /* no encoding yet
275 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
276 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
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, sizeof(add->szShortName)/sizeof(WCHAR) );
693 MultiByteToWideChar( CP_ACP, 0, "Wine MPEG3 decoder", -1,
694 add->szLongName, sizeof(add->szLongName)/sizeof(WCHAR) );
695 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
696 add->szCopyright, sizeof(add->szCopyright)/sizeof(WCHAR) );
697 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
698 add->szLicensing, sizeof(add->szLicensing)/sizeof(WCHAR) );
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 = NUM_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 = NUM_MPEG3_FORMATS;
753 lstrcpyW(aftd->szFormatTag, szMpeg3);
754 break;
755 case 2:
756 aftd->dwFormatTag = WAVE_FORMAT_MPEG;
757 aftd->cbFormatSize = sizeof(MPEG1WAVEFORMAT);
758 aftd->cStandardFormats = NUM_MPEG3_FORMATS;
759 lstrcpyW(aftd->szFormatTag, szMpeg);
760 break;
761 }
762 return MMSYSERR_NOERROR;
763 }
764
765 static void fill_in_mp3(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate)
766 {
767 MPEGLAYER3WAVEFORMAT* mp3wfx = (MPEGLAYER3WAVEFORMAT*)wfx;
768
769 wfx->nAvgBytesPerSec = bit_rate / 8;
770 if (cbwfx >= sizeof(WAVEFORMATEX))
771 wfx->cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX);
772 if (cbwfx >= sizeof(MPEGLAYER3WAVEFORMAT))
773 {
774 mp3wfx->wID = MPEGLAYER3_ID_MPEG;
775 mp3wfx->fdwFlags = MPEGLAYER3_FLAG_PADDING_OFF;
776 mp3wfx->nBlockSize = (bit_rate * 144) / wfx->nSamplesPerSec;
777 mp3wfx->nFramesPerBlock = 1;
778 mp3wfx->nCodecDelay = 0x0571;
779 }
780 }
781
782 static void fill_in_mpeg(unsigned cbwfx, WAVEFORMATEX* wfx, unsigned bit_rate)
783 {
784 MPEG1WAVEFORMAT* mp3wfx = (MPEG1WAVEFORMAT*)wfx;
785
786 wfx->nAvgBytesPerSec = bit_rate / 8;
787 if (cbwfx >= sizeof(WAVEFORMATEX))
788 wfx->cbSize = sizeof(MPEG1WAVEFORMAT) - sizeof(WAVEFORMATEX);
789 if (cbwfx >= sizeof(MPEG1WAVEFORMAT))
790 {
791 mp3wfx->fwHeadLayer = ACM_MPEG_LAYER3;
792 mp3wfx->dwHeadBitrate = wfx->nAvgBytesPerSec * 8;
793 mp3wfx->fwHeadMode = ACM_MPEG_JOINTSTEREO;
794 mp3wfx->fwHeadModeExt = 0xf;
795 mp3wfx->wHeadEmphasis = 1;
796 mp3wfx->fwHeadFlags = ACM_MPEG_ID_MPEG1;
797 }
798 }
799
800 /***********************************************************************
801 * MPEG3_FormatDetails
802 *
803 */
804 static LRESULT MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
805 {
806 switch (dwQuery)
807 {
808 case ACM_FORMATDETAILSF_FORMAT:
809 if (MPEG3_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
810 break;
811 case ACM_FORMATDETAILSF_INDEX:
812 afd->pwfx->wFormatTag = afd->dwFormatTag;
813 switch (afd->dwFormatTag)
814 {
815 case WAVE_FORMAT_PCM:
816 if (afd->dwFormatIndex >= NUM_PCM_FORMATS) return ACMERR_NOTPOSSIBLE;
817 afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
818 afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
819 afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
820 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
821 * afd->pwfx->cbSize = 0;
822 */
823 afd->pwfx->nBlockAlign =
824 (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
825 afd->pwfx->nAvgBytesPerSec =
826 afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
827 break;
828 case WAVE_FORMAT_MPEGLAYER3:
829 case WAVE_FORMAT_MPEG:
830 if (afd->dwFormatIndex >= NUM_MPEG3_FORMATS) return ACMERR_NOTPOSSIBLE;
831 afd->pwfx->nChannels = MPEG3_Formats[afd->dwFormatIndex].nChannels;
832 afd->pwfx->nSamplesPerSec = MPEG3_Formats[afd->dwFormatIndex].rate;
833 afd->pwfx->wBitsPerSample = MPEG3_Formats[afd->dwFormatIndex].nBits;
834 afd->pwfx->nBlockAlign = 1;
835 if (afd->dwFormatTag == WAVE_FORMAT_MPEGLAYER3)
836 fill_in_mp3(afd->cbwfx, afd->pwfx, 192000);
837 else
838 fill_in_mpeg(afd->cbwfx, afd->pwfx, 192000);
839 break;
840 default:
841 WARN("Unsupported tag %08x\n", afd->dwFormatTag);
842 return MMSYSERR_INVALPARAM;
843 }
844 break;
845 default:
846 WARN("Unsupported query %08x\n", dwQuery);
847 return MMSYSERR_NOTSUPPORTED;
848 }
849 afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
850 afd->szFormat[0] = 0; /* let MSACM format this for us... */
851
852 return MMSYSERR_NOERROR;
853 }
854
855 /***********************************************************************
856 * MPEG3_FormatSuggest
857 *
858 */
859 static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
860 {
861 /* some tests ... */
862 if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
863 adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
864 MPEG3_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
865 /* FIXME: should do those tests against the real size (according to format tag */
866
867 /* If no suggestion for destination, then copy source value */
868 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
869 adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
870 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
871 adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
872
873 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
874 {
875 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
876 adfs->pwfxDst->wBitsPerSample = 4;
877 else
878 adfs->pwfxDst->wBitsPerSample = 16;
879 }
880 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
881 {
882 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
883 adfs->pwfxDst->wFormatTag = WAVE_FORMAT_MPEGLAYER3;
884 else
885 adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
886 }
887
888 /* check if result is ok */
889 if (MPEG3_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
890
891 /* recompute other values */
892 switch (adfs->pwfxDst->wFormatTag)
893 {
894 case WAVE_FORMAT_PCM:
895 adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
896 adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
897 break;
898 case WAVE_FORMAT_MPEG:
899 adfs->pwfxDst->nBlockAlign = 1;
900 fill_in_mpeg(adfs->cbwfxDst, adfs->pwfxDst, 192000);
901 break;
902 case WAVE_FORMAT_MPEGLAYER3:
903 adfs->pwfxDst->nBlockAlign = 1;
904 fill_in_mp3(adfs->cbwfxDst, adfs->pwfxDst, 192000);
905 break;
906 default:
907 FIXME("\n");
908 break;
909 }
910
911 return MMSYSERR_NOERROR;
912 }
913
914 /***********************************************************************
915 * MPEG3_StreamSize
916 *
917 */
918 static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
919 {
920 DWORD nblocks;
921
922 switch (adss->fdwSize)
923 {
924 case ACM_STREAMSIZEF_DESTINATION:
925 /* cbDstLength => cbSrcLength */
926 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
927 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
928 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
929 {
930 nblocks = (adss->cbDstLength - 3000) / (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
931 if (nblocks == 0)
932 return ACMERR_NOTPOSSIBLE;
933 adss->cbSrcLength = nblocks * 1152 * adsi->pwfxSrc->nBlockAlign;
934 }
935 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
936 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
937 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
938 {
939 nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * 1152);
940 if (nblocks == 0)
941 return ACMERR_NOTPOSSIBLE;
942 adss->cbSrcLength = nblocks * (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);
943 }
944 else
945 {
946 return MMSYSERR_NOTSUPPORTED;
947 }
948 break;
949 case ACM_STREAMSIZEF_SOURCE:
950 /* cbSrcLength => cbDstLength */
951 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
952 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
953 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
954 {
955 nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * 1152);
956 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nBlockAlign * 1152))
957 /* Round block count up. */
958 nblocks++;
959 if (nblocks == 0)
960 return ACMERR_NOTPOSSIBLE;
961 adss->cbDstLength = 3000 + nblocks * (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
962 }
963 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
964 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
965 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
966 {
967 nblocks = adss->cbSrcLength / (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);
968 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec))
969 /* Round block count up. */
970 nblocks++;
971 if (nblocks == 0)
972 return ACMERR_NOTPOSSIBLE;
973 adss->cbDstLength = nblocks * 1152 * adsi->pwfxDst->nBlockAlign;
974 }
975 else
976 {
977 return MMSYSERR_NOTSUPPORTED;
978 }
979 break;
980 default:
981 WARN("Unsupported query %08x\n", adss->fdwSize);
982 return MMSYSERR_NOTSUPPORTED;
983 }
984 return MMSYSERR_NOERROR;
985 }
986
987 /***********************************************************************
988 * MPEG3_StreamConvert
989 *
990 */
991 static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
992 {
993 AcmMpeg3Data* aad = (AcmMpeg3Data*)adsi->dwDriver;
994 DWORD nsrc = adsh->cbSrcLength;
995 DWORD ndst = adsh->cbDstLength;
996
997 if (adsh->fdwConvert &
998 ~(ACM_STREAMCONVERTF_BLOCKALIGN|
999 ACM_STREAMCONVERTF_END|
1000 ACM_STREAMCONVERTF_START))
1001 {
1002 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
1003 }
1004 /* ACM_STREAMCONVERTF_BLOCKALIGN
1005 * currently all conversions are block aligned, so do nothing for this flag
1006 * ACM_STREAMCONVERTF_END
1007 * no pending data, so do nothing for this flag
1008 */
1009 if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
1010 {
1011 MPEG3_Reset(adsi, aad);
1012 }
1013
1014 aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
1015 adsh->cbSrcLengthUsed = nsrc;
1016 adsh->cbDstLengthUsed = ndst;
1017
1018 return MMSYSERR_NOERROR;
1019 }
1020
1021 /**************************************************************************
1022 * MPEG3_DriverProc [exported]
1023 */
1024 LRESULT CALLBACK MPEG3_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
1025 LPARAM dwParam1, LPARAM dwParam2)
1026 {
1027 TRACE("(%08lx %p %04x %08lx %08lx);\n",
1028 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1029
1030 switch (wMsg)
1031 {
1032 case DRV_LOAD: return 1;
1033 case DRV_FREE: return 1;
1034 case DRV_OPEN: return MPEG3_drvOpen((LPSTR)dwParam1);
1035 case DRV_CLOSE: return MPEG3_drvClose(dwDevID);
1036 case DRV_ENABLE: return 1;
1037 case DRV_DISABLE: return 1;
1038 case DRV_QUERYCONFIGURE: return 1;
1039 case DRV_CONFIGURE: MessageBoxA(0, "MPEG3 filter !", "Wine Driver", MB_OK); return 1;
1040 case DRV_INSTALL: return DRVCNF_RESTART;
1041 case DRV_REMOVE: return DRVCNF_RESTART;
1042
1043 case ACMDM_DRIVER_NOTIFY:
1044 /* no caching from other ACM drivers is done so far */
1045 return MMSYSERR_NOERROR;
1046
1047 case ACMDM_DRIVER_DETAILS:
1048 return MPEG3_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1049
1050 case ACMDM_FORMATTAG_DETAILS:
1051 return MPEG3_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
1052
1053 case ACMDM_FORMAT_DETAILS:
1054 return MPEG3_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1055
1056 case ACMDM_FORMAT_SUGGEST:
1057 return MPEG3_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
1058
1059 case ACMDM_STREAM_OPEN:
1060 return MPEG3_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
1061
1062 case ACMDM_STREAM_CLOSE:
1063 return MPEG3_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
1064
1065 case ACMDM_STREAM_SIZE:
1066 return MPEG3_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
1067
1068 case ACMDM_STREAM_CONVERT:
1069 return MPEG3_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
1070
1071 case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
1072 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
1073 /* this converter is not a hardware driver */
1074 case ACMDM_FILTERTAG_DETAILS:
1075 case ACMDM_FILTER_DETAILS:
1076 /* this converter is not a filter */
1077 case ACMDM_STREAM_RESET:
1078 /* only needed for asynchronous driver... we aren't, so just say it */
1079 return MMSYSERR_NOTSUPPORTED;
1080 case ACMDM_STREAM_PREPARE:
1081 case ACMDM_STREAM_UNPREPARE:
1082 /* nothing special to do here... so don't do anything */
1083 return MMSYSERR_NOERROR;
1084
1085 default:
1086 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1087 }
1088 }