1 /*
2 * MPEG Layer 3 handling
3 *
4 * Copyright (C) 2002 Eric Pouech
5 * Copyright (C) 2009 CodeWeavers, Aric Stewart
6 * Copyright (C) 2010 Kristofer Henriksson
7 *
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24 #include "config.h"
25 #include "wine/port.h"
26
27 #include <assert.h>
28 #include <stdarg.h>
29 #include <string.h>
30
31 #ifdef HAVE_MPG123_H
32 # include <mpg123.h>
33 #else
34 # ifdef HAVE_COREAUDIO_COREAUDIO_H
35 # include <CoreFoundation/CoreFoundation.h>
36 # include <CoreAudio/CoreAudio.h>
37 # endif
38 # ifdef HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H
39 # include <AudioToolbox/AudioConverter.h>
40 # endif
41 #endif
42
43 #include "windef.h"
44 #include "winbase.h"
45 #include "wingdi.h"
46 #include "winuser.h"
47 #include "winnls.h"
48 #include "mmsystem.h"
49 #include "mmreg.h"
50 #include "msacm.h"
51 #include "msacmdrv.h"
52 #include "wine/debug.h"
53
54 WINE_DEFAULT_DEBUG_CHANNEL(mpeg3);
55
56 /* table to list all supported formats... those are the basic ones. this
57 * also helps given a unique index to each of the supported formats
58 */
59 typedef struct
60 {
61 int nChannels;
62 int nBits;
63 int rate;
64 } Format;
65
66 static const Format PCM_Formats[] =
67 {
68 {1, 8, 8000}, {2, 8, 8000}, {1, 16, 8000}, {2, 16, 8000},
69 {1, 8, 11025}, {2, 8, 11025}, {1, 16, 11025}, {2, 16, 11025},
70 {1, 8, 12000}, {2, 8, 12000}, {1, 16, 12000}, {2, 16, 12000},
71 {1, 8, 16000}, {2, 8, 16000}, {1, 16, 16000}, {2, 16, 16000},
72 {1, 8, 22050}, {2, 8, 22050}, {1, 16, 22050}, {2, 16, 22050},
73 {1, 8, 24000}, {2, 8, 24000}, {1, 16, 24000}, {2, 16, 24000},
74 {1, 8, 32000}, {2, 8, 32000}, {1, 16, 32000}, {2, 16, 32000},
75 {1, 8, 44100}, {2, 8, 44100}, {1, 16, 44100}, {2, 16, 44100},
76 {1, 8, 48000}, {2, 8, 48000}, {1, 16, 48000}, {2, 16, 48000}
77 };
78
79 static const Format MPEG3_Formats[] =
80 {
81 {1, 0, 8000}, {2, 0, 8000},
82 {1, 0, 11025}, {2, 0, 11025},
83 {1, 0, 12000}, {2, 0, 12000},
84 {1, 0, 16000}, {2, 0, 16000},
85 {1, 0, 22050}, {2, 0, 22050},
86 {1, 0, 24000}, {2, 0, 24000},
87 {1, 0, 32000}, {2, 0, 32000},
88 {1, 0, 44100}, {2, 0, 44100},
89 {1, 0, 48000}, {2, 0, 48000}
90 };
91
92 /***********************************************************************
93 * MPEG3_GetFormatIndex
94 */
MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)95 static DWORD MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
96 {
97 int i, hi;
98 const Format *fmts;
99
100 switch (wfx->wFormatTag)
101 {
102 case WAVE_FORMAT_PCM:
103 hi = ARRAY_SIZE(PCM_Formats);
104 fmts = PCM_Formats;
105 break;
106 case WAVE_FORMAT_MPEG:
107 case WAVE_FORMAT_MPEGLAYER3:
108 hi = ARRAY_SIZE(MPEG3_Formats);
109 fmts = MPEG3_Formats;
110 break;
111 default:
112 return 0xFFFFFFFF;
113 }
114
115 for (i = 0; i < hi; i++)
116 {
117 if (wfx->nChannels == fmts[i].nChannels &&
118 wfx->nSamplesPerSec == fmts[i].rate &&
119 (wfx->wBitsPerSample == fmts[i].nBits || !fmts[i].nBits))
120 return i;
121 }
122
123 return 0xFFFFFFFF;
124 }
125
126 #ifdef HAVE_MPG123_H
127
128 typedef struct tagAcmMpeg3Data
129 {
130 void (*convert)(PACMDRVSTREAMINSTANCE adsi,
131 const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
132 mpg123_handle *mh;
133 } AcmMpeg3Data;
134
135 /***********************************************************************
136 * MPEG3_drvOpen
137 */
MPEG3_drvOpen(LPCSTR str)138 static LRESULT MPEG3_drvOpen(LPCSTR str)
139 {
140 mpg123_init();
141 return 1;
142 }
143
144 /***********************************************************************
145 * MPEG3_drvClose
146 */
MPEG3_drvClose(DWORD_PTR dwDevID)147 static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
148 {
149 mpg123_exit();
150 return 1;
151 }
152
153
mp3_horse(PACMDRVSTREAMINSTANCE adsi,const unsigned char * src,LPDWORD nsrc,unsigned char * dst,LPDWORD ndst)154 static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
155 const unsigned char* src, LPDWORD nsrc,
156 unsigned char* dst, LPDWORD ndst)
157 {
158 AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
159 int ret;
160 size_t size;
161 DWORD dpos = 0;
162
163
164 if (*nsrc > 0)
165 {
166 ret = mpg123_feed(amd->mh, src, *nsrc);
167 if (ret != MPG123_OK)
168 {
169 ERR("Error feeding data\n");
170 *ndst = *nsrc = 0;
171 return;
172 }
173 }
174
175 do {
176 size = 0;
177 ret = mpg123_read(amd->mh, dst + dpos, *ndst - dpos, &size);
178 if (ret == MPG123_ERR)
179 {
180 FIXME("Error occurred during decoding!\n");
181 *ndst = *nsrc = 0;
182 return;
183 }
184
185 if (ret == MPG123_NEW_FORMAT)
186 {
187 long rate;
188 int channels, enc;
189 mpg123_getformat(amd->mh, &rate, &channels, &enc);
190 TRACE("New format: %li Hz, %i channels, encoding value %i\n", rate, channels, enc);
191 }
192 dpos += size;
193 if (dpos >= *ndst) break;
194 } while (ret != MPG123_ERR && ret != MPG123_NEED_MORE);
195 *ndst = dpos;
196 }
197
198 /***********************************************************************
199 * MPEG3_Reset
200 *
201 */
MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi,AcmMpeg3Data * aad)202 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
203 {
204 mpg123_feedseek(aad->mh, 0, SEEK_SET, NULL);
205 mpg123_close(aad->mh);
206 mpg123_open_feed(aad->mh);
207 }
208
209 /***********************************************************************
210 * MPEG3_StreamOpen
211 *
212 */
MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)213 static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
214 {
215 LRESULT error = MMSYSERR_NOTSUPPORTED;
216 AcmMpeg3Data* aad;
217 int err;
218
219 assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
220
221 if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
222 MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
223 return ACMERR_NOTPOSSIBLE;
224
225 aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data));
226 if (aad == 0) return MMSYSERR_NOMEM;
227
228 adsi->dwDriver = (DWORD_PTR)aad;
229
230 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
231 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
232 {
233 goto theEnd;
234 }
235 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
236 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
237 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
238 {
239 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
240 {
241 MPEGLAYER3WAVEFORMAT *formatmp3 = (MPEGLAYER3WAVEFORMAT *)adsi->pwfxSrc;
242
243 if (adsi->pwfxSrc->cbSize < MPEGLAYER3_WFX_EXTRA_BYTES ||
244 formatmp3->wID != MPEGLAYER3_ID_MPEG)
245 {
246 error = ACMERR_NOTPOSSIBLE;
247 goto theEnd;
248 }
249 }
250
251 /* resampling or mono <=> stereo not available
252 * MPEG3 algo only define 16 bit per sample output
253 */
254 if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
255 adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
256 adsi->pwfxDst->wBitsPerSample != 16)
257 goto theEnd;
258 aad->convert = mp3_horse;
259 aad->mh = mpg123_new(NULL,&err);
260 mpg123_open_feed(aad->mh);
261
262 #if MPG123_API_VERSION >= 31 /* needed for MPG123_IGNORE_FRAMEINFO enum value */
263 /* mpg123 may find a XING header in the mp3 and use that information
264 * to ask for seeks in order to read specific frames in the file.
265 * We cannot allow that since the caller application is feeding us.
266 * This fixes problems for mp3 files encoded with LAME (bug 42361)
267 */
268 mpg123_param(aad->mh, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0);
269 #endif
270 }
271 else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
272 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
273 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
274 {
275 WARN("Encoding to MPEG is not supported\n");
276 goto theEnd;
277 }
278 else goto theEnd;
279 MPEG3_Reset(adsi, aad);
280
281 return MMSYSERR_NOERROR;
282
283 theEnd:
284 HeapFree(GetProcessHeap(), 0, aad);
285 adsi->dwDriver = 0L;
286 return error;
287 }
288
289 /***********************************************************************
290 * MPEG3_StreamClose
291 *
292 */
MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)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 */
MPEG3_drvOpen(LPCSTR str)334 static LRESULT MPEG3_drvOpen(LPCSTR str)
335 {
336 return 1;
337 }
338
339 /***********************************************************************
340 * MPEG3_drvClose
341 */
MPEG3_drvClose(DWORD_PTR dwDevID)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 */
Mp3AudioConverterComplexInputDataProc(AudioConverterRef inAudioConverter,UInt32 * ioNumberDataPackets,AudioBufferList * ioData,AudioStreamPacketDescription ** outDataPacketDescription,void * inUserData)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 */
Mp3GetPacketLength(const unsigned char * src)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 */
mp3_leopard_horse(PACMDRVSTREAMINSTANCE adsi,unsigned char * src,LPDWORD nsrc,unsigned char * dst,LPDWORD ndst)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 */
MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi,AcmMpeg3Data * aad)586 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
587 {
588 AudioConverterReset(aad->acr);
589 }
590
591 /***********************************************************************
592 * MPEG3_StreamOpen
593 *
594 */
MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)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 */
MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)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 */
MPEG3_DriverDetails(PACMDRIVERDETAILSW add)679 static LRESULT MPEG3_DriverDetails(PACMDRIVERDETAILSW add)
680 {
681 add->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC;
682 add->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED;
683 add->wMid = MM_FRAUNHOFER_IIS;
684 add->wPid = MM_FHGIIS_MPEGLAYER3_DECODE;
685 add->vdwACM = 0x01000000;
686 add->vdwDriver = 0x01000000;
687 add->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
688 add->cFormatTags = 3; /* PCM, MPEG3 */
689 add->cFilterTags = 0;
690 add->hicon = NULL;
691 MultiByteToWideChar( CP_ACP, 0, "MPEG Layer-3 Codec", -1,
692 add->szShortName, ARRAY_SIZE( add->szShortName ));
693 MultiByteToWideChar( CP_ACP, 0, "Wine MPEG3 decoder", -1,
694 add->szLongName, ARRAY_SIZE( add->szLongName ));
695 MultiByteToWideChar( CP_ACP, 0, "Brought to you by the Wine team...", -1,
696 add->szCopyright, ARRAY_SIZE( add->szCopyright ));
697 MultiByteToWideChar( CP_ACP, 0, "Refer to LICENSE file", -1,
698 add->szLicensing, ARRAY_SIZE( add->szLicensing ));
699 add->szFeatures[0] = 0;
700
701 return MMSYSERR_NOERROR;
702 }
703
704 /***********************************************************************
705 * MPEG3_FormatTagDetails
706 *
707 */
MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd,DWORD dwQuery)708 static LRESULT MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd, DWORD dwQuery)
709 {
710 static const WCHAR szPcm[]={'P','C','M',0};
711 static const WCHAR szMpeg3[]={'M','P','e','g','3',0};
712 static const WCHAR szMpeg[]={'M','P','e','g',0};
713
714 switch (dwQuery)
715 {
716 case ACM_FORMATTAGDETAILSF_INDEX:
717 if (aftd->dwFormatTagIndex > 2) return ACMERR_NOTPOSSIBLE;
718 break;
719 case ACM_FORMATTAGDETAILSF_LARGESTSIZE:
720 if (aftd->dwFormatTag == WAVE_FORMAT_UNKNOWN)
721 {
722 aftd->dwFormatTagIndex = 2; /* WAVE_FORMAT_MPEG is biggest */
723 break;
724 }
725 /* fall through */
726 case ACM_FORMATTAGDETAILSF_FORMATTAG:
727 switch (aftd->dwFormatTag)
728 {
729 case WAVE_FORMAT_PCM: aftd->dwFormatTagIndex = 0; break;
730 case WAVE_FORMAT_MPEGLAYER3: aftd->dwFormatTagIndex = 1; break;
731 case WAVE_FORMAT_MPEG: aftd->dwFormatTagIndex = 2; break;
732 default: return ACMERR_NOTPOSSIBLE;
733 }
734 break;
735 default:
736 WARN("Unsupported query %08x\n", dwQuery);
737 return MMSYSERR_NOTSUPPORTED;
738 }
739
740 aftd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
741 switch (aftd->dwFormatTagIndex)
742 {
743 case 0:
744 aftd->dwFormatTag = WAVE_FORMAT_PCM;
745 aftd->cbFormatSize = sizeof(PCMWAVEFORMAT);
746 aftd->cStandardFormats = ARRAY_SIZE(PCM_Formats);
747 lstrcpyW(aftd->szFormatTag, szPcm);
748 break;
749 case 1:
750 aftd->dwFormatTag = WAVE_FORMAT_MPEGLAYER3;
751 aftd->cbFormatSize = sizeof(MPEGLAYER3WAVEFORMAT);
752 aftd->cStandardFormats = 0;
753 lstrcpyW(aftd->szFormatTag, szMpeg3);
754 break;
755 case 2:
756 aftd->dwFormatTag = WAVE_FORMAT_MPEG;
757 aftd->cbFormatSize = sizeof(MPEG1WAVEFORMAT);
758 aftd->cStandardFormats = 0;
759 lstrcpyW(aftd->szFormatTag, szMpeg);
760 break;
761 }
762 return MMSYSERR_NOERROR;
763 }
764
765 /***********************************************************************
766 * MPEG3_FormatDetails
767 *
768 */
MPEG3_FormatDetails(PACMFORMATDETAILSW afd,DWORD dwQuery)769 static LRESULT MPEG3_FormatDetails(PACMFORMATDETAILSW afd, DWORD dwQuery)
770 {
771 switch (dwQuery)
772 {
773 case ACM_FORMATDETAILSF_FORMAT:
774 if (MPEG3_GetFormatIndex(afd->pwfx) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
775 break;
776 case ACM_FORMATDETAILSF_INDEX:
777 afd->pwfx->wFormatTag = afd->dwFormatTag;
778 switch (afd->dwFormatTag)
779 {
780 case WAVE_FORMAT_PCM:
781 if (afd->dwFormatIndex >= ARRAY_SIZE(PCM_Formats)) return ACMERR_NOTPOSSIBLE;
782 afd->pwfx->nChannels = PCM_Formats[afd->dwFormatIndex].nChannels;
783 afd->pwfx->nSamplesPerSec = PCM_Formats[afd->dwFormatIndex].rate;
784 afd->pwfx->wBitsPerSample = PCM_Formats[afd->dwFormatIndex].nBits;
785 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
786 * afd->pwfx->cbSize = 0;
787 */
788 afd->pwfx->nBlockAlign =
789 (afd->pwfx->nChannels * afd->pwfx->wBitsPerSample) / 8;
790 afd->pwfx->nAvgBytesPerSec =
791 afd->pwfx->nSamplesPerSec * afd->pwfx->nBlockAlign;
792 break;
793 case WAVE_FORMAT_MPEGLAYER3:
794 case WAVE_FORMAT_MPEG:
795 WARN("Encoding to MPEG is not supported\n");
796 return ACMERR_NOTPOSSIBLE;
797 default:
798 WARN("Unsupported tag %08x\n", afd->dwFormatTag);
799 return MMSYSERR_INVALPARAM;
800 }
801 break;
802 default:
803 WARN("Unsupported query %08x\n", dwQuery);
804 return MMSYSERR_NOTSUPPORTED;
805 }
806 afd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC;
807 afd->szFormat[0] = 0; /* let MSACM format this for us... */
808
809 return MMSYSERR_NOERROR;
810 }
811
812 /***********************************************************************
813 * MPEG3_FormatSuggest
814 *
815 */
MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)816 static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
817 {
818 /* some tests ... */
819 if (adfs->cbwfxSrc < sizeof(PCMWAVEFORMAT) ||
820 adfs->cbwfxDst < sizeof(PCMWAVEFORMAT) ||
821 MPEG3_GetFormatIndex(adfs->pwfxSrc) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
822 /* FIXME: should do those tests against the real size (according to format tag */
823
824 /* If no suggestion for destination, then copy source value */
825 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NCHANNELS))
826 adfs->pwfxDst->nChannels = adfs->pwfxSrc->nChannels;
827 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_NSAMPLESPERSEC))
828 adfs->pwfxDst->nSamplesPerSec = adfs->pwfxSrc->nSamplesPerSec;
829 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WBITSPERSAMPLE))
830 adfs->pwfxDst->wBitsPerSample = 16;
831 if (!(adfs->fdwSuggest & ACM_FORMATSUGGESTF_WFORMATTAG))
832 {
833 if (adfs->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM)
834 {
835 WARN("Encoding to MPEG is not supported\n");
836 return ACMERR_NOTPOSSIBLE;
837 }
838 else
839 adfs->pwfxDst->wFormatTag = WAVE_FORMAT_PCM;
840 }
841
842 /* check if result is ok */
843 if (MPEG3_GetFormatIndex(adfs->pwfxDst) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE;
844
845 /* recompute other values */
846 switch (adfs->pwfxDst->wFormatTag)
847 {
848 case WAVE_FORMAT_PCM:
849 adfs->pwfxDst->nBlockAlign = (adfs->pwfxDst->nChannels * adfs->pwfxDst->wBitsPerSample) / 8;
850 adfs->pwfxDst->nAvgBytesPerSec = adfs->pwfxDst->nSamplesPerSec * adfs->pwfxDst->nBlockAlign;
851 break;
852 case WAVE_FORMAT_MPEG:
853 case WAVE_FORMAT_MPEGLAYER3:
854 WARN("Encoding to MPEG is not supported\n");
855 return ACMERR_NOTPOSSIBLE;
856 break;
857 default:
858 FIXME("\n");
859 break;
860 }
861
862 return MMSYSERR_NOERROR;
863 }
864
865 /***********************************************************************
866 * MPEG3_StreamSize
867 *
868 */
MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi,PACMDRVSTREAMSIZE adss)869 static LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE adss)
870 {
871 DWORD nblocks;
872
873 switch (adss->fdwSize)
874 {
875 case ACM_STREAMSIZEF_DESTINATION:
876 /* cbDstLength => cbSrcLength */
877 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
878 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
879 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
880 {
881 nblocks = (adss->cbDstLength - 3000) / (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
882 if (nblocks == 0)
883 return ACMERR_NOTPOSSIBLE;
884 adss->cbSrcLength = nblocks * 1152 * adsi->pwfxSrc->nBlockAlign;
885 }
886 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
887 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
888 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
889 {
890 nblocks = adss->cbDstLength / (adsi->pwfxDst->nBlockAlign * 1152);
891 if (nblocks == 0)
892 return ACMERR_NOTPOSSIBLE;
893 adss->cbSrcLength = nblocks * (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);
894 }
895 else
896 {
897 return MMSYSERR_NOTSUPPORTED;
898 }
899 break;
900 case ACM_STREAMSIZEF_SOURCE:
901 /* cbSrcLength => cbDstLength */
902 if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
903 (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
904 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
905 {
906 nblocks = adss->cbSrcLength / (adsi->pwfxSrc->nBlockAlign * 1152);
907 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nBlockAlign * 1152))
908 /* Round block count up. */
909 nblocks++;
910 if (nblocks == 0)
911 return ACMERR_NOTPOSSIBLE;
912 adss->cbDstLength = 3000 + nblocks * (DWORD)(adsi->pwfxDst->nAvgBytesPerSec * 1152 / adsi->pwfxDst->nSamplesPerSec + 0.5);
913 }
914 else if ((adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
915 adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
916 adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
917 {
918 nblocks = adss->cbSrcLength / (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec);
919 if (adss->cbSrcLength % (DWORD)(adsi->pwfxSrc->nAvgBytesPerSec * 1152 / adsi->pwfxSrc->nSamplesPerSec))
920 /* Round block count up. */
921 nblocks++;
922 if (nblocks == 0)
923 return ACMERR_NOTPOSSIBLE;
924 adss->cbDstLength = nblocks * 1152 * adsi->pwfxDst->nBlockAlign;
925 }
926 else
927 {
928 return MMSYSERR_NOTSUPPORTED;
929 }
930 break;
931 default:
932 WARN("Unsupported query %08x\n", adss->fdwSize);
933 return MMSYSERR_NOTSUPPORTED;
934 }
935 return MMSYSERR_NOERROR;
936 }
937
938 /***********************************************************************
939 * MPEG3_StreamConvert
940 *
941 */
MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi,PACMDRVSTREAMHEADER adsh)942 static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
943 {
944 AcmMpeg3Data* aad = (AcmMpeg3Data*)adsi->dwDriver;
945 DWORD nsrc = adsh->cbSrcLength;
946 DWORD ndst = adsh->cbDstLength;
947
948 if (adsh->fdwConvert &
949 ~(ACM_STREAMCONVERTF_BLOCKALIGN|
950 ACM_STREAMCONVERTF_END|
951 ACM_STREAMCONVERTF_START))
952 {
953 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh->fdwConvert);
954 }
955 /* ACM_STREAMCONVERTF_BLOCKALIGN
956 * currently all conversions are block aligned, so do nothing for this flag
957 * ACM_STREAMCONVERTF_END
958 * no pending data, so do nothing for this flag
959 */
960 if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
961 {
962 MPEG3_Reset(adsi, aad);
963 }
964
965 aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
966 adsh->cbSrcLengthUsed = nsrc;
967 adsh->cbDstLengthUsed = ndst;
968
969 return MMSYSERR_NOERROR;
970 }
971
972 /**************************************************************************
973 * MPEG3_DriverProc [exported]
974 */
MPEG3_DriverProc(DWORD_PTR dwDevID,HDRVR hDriv,UINT wMsg,LPARAM dwParam1,LPARAM dwParam2)975 LRESULT CALLBACK MPEG3_DriverProc(DWORD_PTR dwDevID, HDRVR hDriv, UINT wMsg,
976 LPARAM dwParam1, LPARAM dwParam2)
977 {
978 TRACE("(%08lx %p %04x %08lx %08lx);\n",
979 dwDevID, hDriv, wMsg, dwParam1, dwParam2);
980
981 switch (wMsg)
982 {
983 case DRV_LOAD: return 1;
984 case DRV_FREE: return 1;
985 case DRV_OPEN: return MPEG3_drvOpen((LPSTR)dwParam1);
986 case DRV_CLOSE: return MPEG3_drvClose(dwDevID);
987 case DRV_ENABLE: return 1;
988 case DRV_DISABLE: return 1;
989 case DRV_QUERYCONFIGURE: return 1;
990 case DRV_CONFIGURE: MessageBoxA(0, "MPEG3 filter !", "Wine Driver", MB_OK); return 1;
991 case DRV_INSTALL: return DRVCNF_RESTART;
992 case DRV_REMOVE: return DRVCNF_RESTART;
993
994 case ACMDM_DRIVER_NOTIFY:
995 /* no caching from other ACM drivers is done so far */
996 return MMSYSERR_NOERROR;
997
998 case ACMDM_DRIVER_DETAILS:
999 return MPEG3_DriverDetails((PACMDRIVERDETAILSW)dwParam1);
1000
1001 case ACMDM_FORMATTAG_DETAILS:
1002 return MPEG3_FormatTagDetails((PACMFORMATTAGDETAILSW)dwParam1, dwParam2);
1003
1004 case ACMDM_FORMAT_DETAILS:
1005 return MPEG3_FormatDetails((PACMFORMATDETAILSW)dwParam1, dwParam2);
1006
1007 case ACMDM_FORMAT_SUGGEST:
1008 return MPEG3_FormatSuggest((PACMDRVFORMATSUGGEST)dwParam1);
1009
1010 case ACMDM_STREAM_OPEN:
1011 return MPEG3_StreamOpen((PACMDRVSTREAMINSTANCE)dwParam1);
1012
1013 case ACMDM_STREAM_CLOSE:
1014 return MPEG3_StreamClose((PACMDRVSTREAMINSTANCE)dwParam1);
1015
1016 case ACMDM_STREAM_SIZE:
1017 return MPEG3_StreamSize((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMSIZE)dwParam2);
1018
1019 case ACMDM_STREAM_CONVERT:
1020 return MPEG3_StreamConvert((PACMDRVSTREAMINSTANCE)dwParam1, (PACMDRVSTREAMHEADER)dwParam2);
1021
1022 case ACMDM_HARDWARE_WAVE_CAPS_INPUT:
1023 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT:
1024 /* this converter is not a hardware driver */
1025 case ACMDM_FILTERTAG_DETAILS:
1026 case ACMDM_FILTER_DETAILS:
1027 /* this converter is not a filter */
1028 case ACMDM_STREAM_RESET:
1029 /* only needed for asynchronous driver... we aren't, so just say it */
1030 return MMSYSERR_NOTSUPPORTED;
1031 case ACMDM_STREAM_PREPARE:
1032 case ACMDM_STREAM_UNPREPARE:
1033 /* nothing special to do here... so don't do anything */
1034 return MMSYSERR_NOERROR;
1035
1036 default:
1037 return DefDriverProc(dwDevID, hDriv, wMsg, dwParam1, dwParam2);
1038 }
1039 }
1040