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