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