2 * MPEG Layer 3 handling
4 * Copyright (C) 2002 Eric Pouech
5 * Copyright (C) 2009 CodeWeavers, Aric Stewart
6 * Copyright (C) 2010 Kristofer Henriksson
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.
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.
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
25 #include "wine/port.h"
34 # ifdef HAVE_COREAUDIO_COREAUDIO_H
35 # include <CoreFoundation/CoreFoundation.h>
36 # include <CoreAudio/CoreAudio.h>
38 # ifdef HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H
39 # include <AudioToolbox/AudioConverter.h>
52 #include "wine/debug.h"
54 WINE_DEFAULT_DEBUG_CHANNEL(mpeg3
);
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
66 static const Format PCM_Formats
[] =
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}
79 static const Format MPEG3_Formats
[] =
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}
92 #define NUM_PCM_FORMATS (sizeof(PCM_Formats) / sizeof(PCM_Formats[0]))
93 #define NUM_MPEG3_FORMATS (sizeof(MPEG3_Formats) / sizeof(MPEG3_Formats[0]))
95 /***********************************************************************
96 * MPEG3_GetFormatIndex
98 static DWORD
MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx
)
103 switch (wfx
->wFormatTag
)
105 case WAVE_FORMAT_PCM
:
106 hi
= NUM_PCM_FORMATS
;
109 case WAVE_FORMAT_MPEG
:
110 case WAVE_FORMAT_MPEGLAYER3
:
111 hi
= NUM_MPEG3_FORMATS
;
112 fmts
= MPEG3_Formats
;
118 for (i
= 0; i
< hi
; i
++)
120 if (wfx
->nChannels
== fmts
[i
].nChannels
&&
121 wfx
->nSamplesPerSec
== fmts
[i
].rate
&&
122 (wfx
->wBitsPerSample
== fmts
[i
].nBits
|| !fmts
[i
].nBits
))
131 typedef struct tagAcmMpeg3Data
133 void (*convert
)(PACMDRVSTREAMINSTANCE adsi
,
134 const unsigned char*, LPDWORD
, unsigned char*, LPDWORD
);
138 /***********************************************************************
141 static LRESULT
MPEG3_drvOpen(LPCSTR str
)
147 /***********************************************************************
150 static LRESULT
MPEG3_drvClose(DWORD_PTR dwDevID
)
157 static void mp3_horse(PACMDRVSTREAMINSTANCE adsi
,
158 const unsigned char* src
, LPDWORD nsrc
,
159 unsigned char* dst
, LPDWORD ndst
)
161 AcmMpeg3Data
* amd
= (AcmMpeg3Data
*)adsi
->dwDriver
;
169 ret
= mpg123_feed(amd
->mh
, src
, *nsrc
);
170 if (ret
!= MPG123_OK
)
172 ERR("Error feeding data\n");
180 ret
= mpg123_read(amd
->mh
, dst
+ dpos
, *ndst
- dpos
, &size
);
181 if (ret
== MPG123_ERR
)
183 FIXME("Error occurred during decoding!\n");
188 if (ret
== MPG123_NEW_FORMAT
)
192 mpg123_getformat(amd
->mh
, &rate
, &channels
, &enc
);
193 TRACE("New format: %li Hz, %i channels, encoding value %i\n", rate
, channels
, enc
);
196 if (dpos
>= *ndst
) break;
197 } while (ret
!= MPG123_ERR
&& ret
!= MPG123_NEED_MORE
);
201 /***********************************************************************
205 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi
, AcmMpeg3Data
* aad
)
207 mpg123_feedseek(aad
->mh
, 0, SEEK_SET
, NULL
);
208 mpg123_close(aad
->mh
);
209 mpg123_open_feed(aad
->mh
);
212 /***********************************************************************
216 static LRESULT
MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi
)
218 LRESULT error
= MMSYSERR_NOTSUPPORTED
;
222 assert(!(adsi
->fdwOpen
& ACM_STREAMOPENF_ASYNC
));
224 if (MPEG3_GetFormatIndex(adsi
->pwfxSrc
) == 0xFFFFFFFF ||
225 MPEG3_GetFormatIndex(adsi
->pwfxDst
) == 0xFFFFFFFF)
226 return ACMERR_NOTPOSSIBLE
;
228 aad
= HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data
));
229 if (aad
== 0) return MMSYSERR_NOMEM
;
231 adsi
->dwDriver
= (DWORD_PTR
)aad
;
233 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
234 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
238 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
239 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEG
) &&
240 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
242 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
)
244 MPEGLAYER3WAVEFORMAT
*formatmp3
= (MPEGLAYER3WAVEFORMAT
*)adsi
->pwfxSrc
;
246 if (adsi
->pwfxSrc
->cbSize
< MPEGLAYER3_WFX_EXTRA_BYTES
||
247 formatmp3
->wID
!= MPEGLAYER3_ID_MPEG
)
249 error
= ACMERR_NOTPOSSIBLE
;
254 /* resampling or mono <=> stereo not available
255 * MPEG3 algo only define 16 bit per sample output
257 if (adsi
->pwfxSrc
->nSamplesPerSec
!= adsi
->pwfxDst
->nSamplesPerSec
||
258 adsi
->pwfxSrc
->nChannels
!= adsi
->pwfxDst
->nChannels
||
259 adsi
->pwfxDst
->wBitsPerSample
!= 16)
261 aad
->convert
= mp3_horse
;
262 aad
->mh
= mpg123_new(NULL
,&err
);
263 mpg123_open_feed(aad
->mh
);
265 #if MPG123_API_VERSION >= 31 /* needed for MPG123_IGNORE_FRAMEINFO enum value */
266 /* mpg123 may find a XING header in the mp3 and use that information
267 * to ask for seeks in order to read specific frames in the file.
268 * We cannot allow that since the caller application is feeding us.
269 * This fixes problems for mp3 files encoded with LAME (bug 42361)
271 mpg123_param(aad
->mh
, MPG123_ADD_FLAGS
, MPG123_IGNORE_INFOFRAME
, 0);
274 else if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
275 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
276 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MPEG
))
278 WARN("Encoding to MPEG is not supported\n");
282 MPEG3_Reset(adsi
, aad
);
284 return MMSYSERR_NOERROR
;
287 HeapFree(GetProcessHeap(), 0, aad
);
292 /***********************************************************************
296 static LRESULT
MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi
)
298 mpg123_close(((AcmMpeg3Data
*)adsi
->dwDriver
)->mh
);
299 mpg123_delete(((AcmMpeg3Data
*)adsi
->dwDriver
)->mh
);
300 HeapFree(GetProcessHeap(), 0, (void*)adsi
->dwDriver
);
301 return MMSYSERR_NOERROR
;
304 #elif defined(HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H)
306 static const unsigned short Mp3BitRates
[2][16] =
308 {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
309 {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
312 static const unsigned short Mp3SampleRates
[2][4] =
314 {44100, 48000, 32000, 0},
315 {22050, 24000, 16000, 0}
318 typedef struct tagAcmMpeg3Data
320 LRESULT (*convert
)(PACMDRVSTREAMINSTANCE adsi
, unsigned char*,
321 LPDWORD
, unsigned char*, LPDWORD
);
322 AudioConverterRef acr
;
323 AudioStreamBasicDescription in
,out
;
325 AudioBufferList outBuffer
;
326 AudioBuffer inBuffer
;
330 UInt32 NumberPackets
;
331 AudioStreamPacketDescription
*PacketDescriptions
;
334 /***********************************************************************
337 static LRESULT
MPEG3_drvOpen(LPCSTR str
)
342 /***********************************************************************
345 static LRESULT
MPEG3_drvClose(DWORD_PTR dwDevID
)
351 When it asks for data, give it all we have. If we have no data, we assume
352 we will in the future, so give it no packets and return an error, which
353 signals that we will have more later.
355 static OSStatus
Mp3AudioConverterComplexInputDataProc(
356 AudioConverterRef inAudioConverter
,
357 UInt32
*ioNumberDataPackets
,
358 AudioBufferList
*ioData
,
359 AudioStreamPacketDescription
**outDataPacketDescription
,
363 AcmMpeg3Data
*amd
= (AcmMpeg3Data
*)inUserData
;
365 if (amd
->inBuffer
.mDataByteSize
> 0)
367 *ioNumberDataPackets
= amd
->NumberPackets
;
368 ioData
->mNumberBuffers
= 1;
369 ioData
->mBuffers
[0] = amd
->inBuffer
;
370 amd
->inBuffer
.mDataByteSize
= 0;
371 if (outDataPacketDescription
)
372 *outDataPacketDescription
= amd
->PacketDescriptions
;
377 *ioNumberDataPackets
= 0;
383 Get the length of the current frame. We need to be at the start of a
384 frame now. The buffer must have at least the four bytes for the header.
386 static SInt32
Mp3GetPacketLength(const unsigned char* src
)
389 unsigned short brate
, srate
;
393 Check that our position looks like an MP3 header and see which type
396 if (src
[0] == 0xff && src
[1] >> 1 == 0x7d) mpegv
= 0; /* MPEG-1 File */
397 else if (src
[0] == 0xff && src
[1] >> 1 == 0x79) mpegv
= 1; /* MPEG-2 File */
400 /* Fill in bit rate and sample rate. */
401 brate
= Mp3BitRates
[mpegv
][(src
[2] & 0xf0) >> 4];
402 srate
= Mp3SampleRates
[mpegv
][(src
[2] & 0xc) >> 2];
404 /* Certain values for bit rate and sample rate are invalid. */
405 if (brate
== 0 || srate
== 0) return -1;
407 /* Compute frame size, round down */
408 size
= 72 * (2 - mpegv
) * brate
* 1000 / srate
;
410 /* If there is padding, add one byte */
411 if (src
[2] & 0x2) return size
+ 1;
416 Apple's AudioFileStream does weird things so we deal with parsing the
417 file ourselves. It was also designed for a different use case, so this
418 is not unexpected. We expect to have MP3 data as input (i.e. we can only
419 deal with MPEG-1 or MPEG-2 Layer III), which simplifies parsing a bit. We
420 understand the ID3v2 header and skip over it. Whenever we have data we
421 want to skip at the beginning of the input, we do this by setting *ndst=0
422 and *nsrc to the length of the unwanted data and return no error.
424 static LRESULT
mp3_leopard_horse(PACMDRVSTREAMINSTANCE adsi
,
425 unsigned char* src
, LPDWORD nsrc
,
426 unsigned char* dst
, LPDWORD ndst
)
429 UInt32 size
, aspdi
, synci
, syncSkip
;
431 const unsigned char* psrc
;
432 AcmMpeg3Data
* amd
= (AcmMpeg3Data
*)adsi
->dwDriver
;
434 TRACE("ndst %u %p <- %u %p\n", *ndst
, dst
, *nsrc
, src
);
436 TRACE("First 16 bytes to input: %s\n", wine_dbgstr_an((const char *)src
, 16));
439 if (!memcmp(src
, "ID3", 3) && amd
->tagBytesLeft
== -1)
441 amd
->tagBytesLeft
= (src
[6] << 21) + (src
[7] << 14) + (src
[8] << 7) + src
[9];
442 if (src
[5] & 0x10) amd
->tagBytesLeft
+= 20; /* There is a footer */
443 else amd
->tagBytesLeft
+= 10;
446 /* Consume the tag */
447 if (amd
->tagBytesLeft
>= (SInt32
)*nsrc
)
450 amd
->tagBytesLeft
-= *nsrc
;
452 TRACE("All %d bytes of source data is ID3 tag\n", *nsrc
);
453 return MMSYSERR_NOERROR
;
455 else if (amd
->tagBytesLeft
> 0)
457 src
+= amd
->tagBytesLeft
;
458 *nsrc
-= amd
->tagBytesLeft
;
459 TRACE("Skipping %ld for ID3 tag\n", amd
->tagBytesLeft
);
463 Sync to initial MP3 frame. The largest possible MP3 frame is 1440.
464 Thus, in the first 1440 bytes we must find the beginning of 3 valid
465 frames in a row unless we reach the end of the file first.
468 for (psrc
= src
; psrc
<= src
+ *nsrc
- 4 && psrc
< src
+ 1440; psrc
++)
472 synci
< 4 && psrc
+ framelen
[synci
-1] < src
+ *nsrc
- 4;
475 framelen
[synci
] = Mp3GetPacketLength(psrc
+ framelen
[synci
-1]);
476 if (framelen
[synci
] == -1)
481 framelen
[synci
] += framelen
[synci
-1];
483 if (synci
> 0) /* We synced successfully */
487 syncSkip
= psrc
- src
;
490 TRACE("Skipping %ld for frame sync\n", syncSkip
);
496 if (Mp3GetPacketLength(src
) == -1)
499 ERR("Frame sync failed. Cannot play file.\n");
500 return MMSYSERR_ERROR
;
504 Fill in frame descriptions for all frames. We use an extra pointer
505 to keep track of our position in the input.
508 amd
->NumberPackets
= 25; /* This is the initial array capacity */
509 amd
->PacketDescriptions
= HeapAlloc(GetProcessHeap(), 0, amd
->NumberPackets
* sizeof(AudioStreamPacketDescription
));
510 if (amd
->PacketDescriptions
== 0) return MMSYSERR_NOMEM
;
512 for (aspdi
= 0, psrc
= src
;
513 psrc
<= src
+ *nsrc
- 4;
514 psrc
+= amd
->PacketDescriptions
[aspdi
].mDataByteSize
, aspdi
++)
516 /* Return an error if we can't read the frame header */
517 if (Mp3GetPacketLength(psrc
) == -1)
520 ERR("Invalid header at %p.\n", psrc
);
521 HeapFree(GetProcessHeap(), 0, amd
->PacketDescriptions
);
522 return MMSYSERR_ERROR
;
525 /* If we run out of space, double size and reallocate */
526 if (aspdi
>= amd
->NumberPackets
)
528 amd
->NumberPackets
*= 2;
529 amd
->PacketDescriptions
= HeapReAlloc(GetProcessHeap(), 0, amd
->PacketDescriptions
, amd
->NumberPackets
* sizeof(AudioStreamPacketDescription
));
530 if (amd
->PacketDescriptions
== 0) return MMSYSERR_NOMEM
;
533 /* Fill in packet data */
534 amd
->PacketDescriptions
[aspdi
].mStartOffset
= psrc
- src
;
535 amd
->PacketDescriptions
[aspdi
].mVariableFramesInPacket
= 0;
536 amd
->PacketDescriptions
[aspdi
].mDataByteSize
= Mp3GetPacketLength(psrc
);
538 /* If this brings us past the end, the last one doesn't count */
539 if (psrc
+ amd
->PacketDescriptions
[aspdi
].mDataByteSize
> src
+ *nsrc
) break;
542 /* Fill in correct number of frames */
543 amd
->NumberPackets
= aspdi
;
545 /* Adjust nsrc to only include full frames */
548 amd
->inBuffer
.mDataByteSize
= *nsrc
;
549 amd
->inBuffer
.mData
= src
;
550 amd
->inBuffer
.mNumberChannels
= amd
->in
.mChannelsPerFrame
;
552 amd
->outBuffer
.mNumberBuffers
= 1;
553 amd
->outBuffer
.mBuffers
[0].mDataByteSize
= *ndst
;
554 amd
->outBuffer
.mBuffers
[0].mData
= dst
;
555 amd
->outBuffer
.mBuffers
[0].mNumberChannels
= amd
->out
.mChannelsPerFrame
;
557 /* Convert the data */
558 size
= amd
->outBuffer
.mBuffers
[0].mDataByteSize
/ amd
->out
.mBytesPerPacket
;
559 err
= AudioConverterFillComplexBuffer(amd
->acr
, Mp3AudioConverterComplexInputDataProc
, amd
, &size
, &amd
->outBuffer
, 0);
561 HeapFree(GetProcessHeap(), 0, amd
->PacketDescriptions
);
563 /* Add skipped bytes back into *nsrc */
564 if (amd
->tagBytesLeft
> 0)
566 *nsrc
+= amd
->tagBytesLeft
;
567 amd
->tagBytesLeft
= 0;
571 if (err
!= noErr
&& err
!= -74)
574 ERR("Feed Error: %ld\n", err
);
575 return MMSYSERR_ERROR
;
578 *ndst
= amd
->outBuffer
.mBuffers
[0].mDataByteSize
;
580 TRACE("convert %d -> %d\n", *nsrc
, *ndst
);
582 return MMSYSERR_NOERROR
;
585 /***********************************************************************
589 static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi
, AcmMpeg3Data
* aad
)
591 AudioConverterReset(aad
->acr
);
594 /***********************************************************************
598 static LRESULT
MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi
)
602 assert(!(adsi
->fdwOpen
& ACM_STREAMOPENF_ASYNC
));
604 if (MPEG3_GetFormatIndex(adsi
->pwfxSrc
) == 0xFFFFFFFF ||
605 MPEG3_GetFormatIndex(adsi
->pwfxDst
) == 0xFFFFFFFF)
606 return ACMERR_NOTPOSSIBLE
;
608 aad
= HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data
));
609 if (aad
== 0) return MMSYSERR_NOMEM
;
611 adsi
->dwDriver
= (DWORD_PTR
)aad
;
613 if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
614 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEG
) &&
615 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
619 aad
->in
.mSampleRate
= adsi
->pwfxSrc
->nSamplesPerSec
;
620 aad
->out
.mSampleRate
= adsi
->pwfxDst
->nSamplesPerSec
;
621 aad
->in
.mBitsPerChannel
= adsi
->pwfxSrc
->wBitsPerSample
;
622 aad
->out
.mBitsPerChannel
= adsi
->pwfxDst
->wBitsPerSample
;
623 aad
->in
.mFormatID
= kAudioFormatMPEGLayer3
;
624 aad
->out
.mFormatID
= kAudioFormatLinearPCM
;
625 aad
->in
.mChannelsPerFrame
= adsi
->pwfxSrc
->nChannels
;
626 aad
->out
.mChannelsPerFrame
= adsi
->pwfxDst
->nChannels
;
627 aad
->in
.mFormatFlags
= 0;
628 aad
->out
.mFormatFlags
= kLinearPCMFormatFlagIsSignedInteger
;
629 aad
->in
.mBytesPerFrame
= 0;
630 aad
->out
.mBytesPerFrame
= (aad
->out
.mBitsPerChannel
* aad
->out
.mChannelsPerFrame
) / 8;
631 aad
->in
.mBytesPerPacket
= 0;
632 aad
->out
.mBytesPerPacket
= aad
->out
.mBytesPerFrame
;
633 aad
->in
.mFramesPerPacket
= 0;
634 aad
->out
.mFramesPerPacket
= 1;
635 aad
->in
.mReserved
= aad
->out
.mReserved
= 0;
637 aad
->tagBytesLeft
= -1;
639 aad
->convert
= mp3_leopard_horse
;
641 err
= AudioConverterNew(&aad
->in
, &aad
->out
, &aad
->acr
);
644 ERR("Create failed: %ld\n", err
);
648 MPEG3_Reset(adsi
, aad
);
650 return MMSYSERR_NOERROR
;
654 HeapFree(GetProcessHeap(), 0, aad
);
657 return MMSYSERR_NOTSUPPORTED
;
660 /***********************************************************************
664 static LRESULT
MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi
)
666 AcmMpeg3Data
* amd
= (AcmMpeg3Data
*)adsi
->dwDriver
;
668 AudioConverterDispose(amd
->acr
);
670 HeapFree(GetProcessHeap(), 0, amd
);
673 return MMSYSERR_NOERROR
;
678 /***********************************************************************
679 * MPEG3_DriverDetails
682 static LRESULT
MPEG3_DriverDetails(PACMDRIVERDETAILSW add
)
684 add
->fccType
= ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC
;
685 add
->fccComp
= ACMDRIVERDETAILS_FCCCOMP_UNDEFINED
;
686 add
->wMid
= MM_FRAUNHOFER_IIS
;
687 add
->wPid
= MM_FHGIIS_MPEGLAYER3_DECODE
;
688 add
->vdwACM
= 0x01000000;
689 add
->vdwDriver
= 0x01000000;
690 add
->fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
691 add
->cFormatTags
= 3; /* PCM, MPEG3 */
692 add
->cFilterTags
= 0;
694 MultiByteToWideChar( CP_ACP
, 0, "MPEG Layer-3 Codec", -1,
695 add
->szShortName
, sizeof(add
->szShortName
)/sizeof(WCHAR
) );
696 MultiByteToWideChar( CP_ACP
, 0, "Wine MPEG3 decoder", -1,
697 add
->szLongName
, sizeof(add
->szLongName
)/sizeof(WCHAR
) );
698 MultiByteToWideChar( CP_ACP
, 0, "Brought to you by the Wine team...", -1,
699 add
->szCopyright
, sizeof(add
->szCopyright
)/sizeof(WCHAR
) );
700 MultiByteToWideChar( CP_ACP
, 0, "Refer to LICENSE file", -1,
701 add
->szLicensing
, sizeof(add
->szLicensing
)/sizeof(WCHAR
) );
702 add
->szFeatures
[0] = 0;
704 return MMSYSERR_NOERROR
;
707 /***********************************************************************
708 * MPEG3_FormatTagDetails
711 static LRESULT
MPEG3_FormatTagDetails(PACMFORMATTAGDETAILSW aftd
, DWORD dwQuery
)
713 static const WCHAR szPcm
[]={'P','C','M',0};
714 static const WCHAR szMpeg3
[]={'M','P','e','g','3',0};
715 static const WCHAR szMpeg
[]={'M','P','e','g',0};
719 case ACM_FORMATTAGDETAILSF_INDEX
:
720 if (aftd
->dwFormatTagIndex
> 2) return ACMERR_NOTPOSSIBLE
;
722 case ACM_FORMATTAGDETAILSF_LARGESTSIZE
:
723 if (aftd
->dwFormatTag
== WAVE_FORMAT_UNKNOWN
)
725 aftd
->dwFormatTagIndex
= 2; /* WAVE_FORMAT_MPEG is biggest */
729 case ACM_FORMATTAGDETAILSF_FORMATTAG
:
730 switch (aftd
->dwFormatTag
)
732 case WAVE_FORMAT_PCM
: aftd
->dwFormatTagIndex
= 0; break;
733 case WAVE_FORMAT_MPEGLAYER3
: aftd
->dwFormatTagIndex
= 1; break;
734 case WAVE_FORMAT_MPEG
: aftd
->dwFormatTagIndex
= 2; break;
735 default: return ACMERR_NOTPOSSIBLE
;
739 WARN("Unsupported query %08x\n", dwQuery
);
740 return MMSYSERR_NOTSUPPORTED
;
743 aftd
->fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
744 switch (aftd
->dwFormatTagIndex
)
747 aftd
->dwFormatTag
= WAVE_FORMAT_PCM
;
748 aftd
->cbFormatSize
= sizeof(PCMWAVEFORMAT
);
749 aftd
->cStandardFormats
= NUM_PCM_FORMATS
;
750 lstrcpyW(aftd
->szFormatTag
, szPcm
);
753 aftd
->dwFormatTag
= WAVE_FORMAT_MPEGLAYER3
;
754 aftd
->cbFormatSize
= sizeof(MPEGLAYER3WAVEFORMAT
);
755 aftd
->cStandardFormats
= 0;
756 lstrcpyW(aftd
->szFormatTag
, szMpeg3
);
759 aftd
->dwFormatTag
= WAVE_FORMAT_MPEG
;
760 aftd
->cbFormatSize
= sizeof(MPEG1WAVEFORMAT
);
761 aftd
->cStandardFormats
= 0;
762 lstrcpyW(aftd
->szFormatTag
, szMpeg
);
765 return MMSYSERR_NOERROR
;
768 /***********************************************************************
769 * MPEG3_FormatDetails
772 static LRESULT
MPEG3_FormatDetails(PACMFORMATDETAILSW afd
, DWORD dwQuery
)
776 case ACM_FORMATDETAILSF_FORMAT
:
777 if (MPEG3_GetFormatIndex(afd
->pwfx
) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE
;
779 case ACM_FORMATDETAILSF_INDEX
:
780 afd
->pwfx
->wFormatTag
= afd
->dwFormatTag
;
781 switch (afd
->dwFormatTag
)
783 case WAVE_FORMAT_PCM
:
784 if (afd
->dwFormatIndex
>= NUM_PCM_FORMATS
) return ACMERR_NOTPOSSIBLE
;
785 afd
->pwfx
->nChannels
= PCM_Formats
[afd
->dwFormatIndex
].nChannels
;
786 afd
->pwfx
->nSamplesPerSec
= PCM_Formats
[afd
->dwFormatIndex
].rate
;
787 afd
->pwfx
->wBitsPerSample
= PCM_Formats
[afd
->dwFormatIndex
].nBits
;
788 /* native MSACM uses a PCMWAVEFORMAT structure, so cbSize is not accessible
789 * afd->pwfx->cbSize = 0;
791 afd
->pwfx
->nBlockAlign
=
792 (afd
->pwfx
->nChannels
* afd
->pwfx
->wBitsPerSample
) / 8;
793 afd
->pwfx
->nAvgBytesPerSec
=
794 afd
->pwfx
->nSamplesPerSec
* afd
->pwfx
->nBlockAlign
;
796 case WAVE_FORMAT_MPEGLAYER3
:
797 case WAVE_FORMAT_MPEG
:
798 WARN("Encoding to MPEG is not supported\n");
799 return ACMERR_NOTPOSSIBLE
;
801 WARN("Unsupported tag %08x\n", afd
->dwFormatTag
);
802 return MMSYSERR_INVALPARAM
;
806 WARN("Unsupported query %08x\n", dwQuery
);
807 return MMSYSERR_NOTSUPPORTED
;
809 afd
->fdwSupport
= ACMDRIVERDETAILS_SUPPORTF_CODEC
;
810 afd
->szFormat
[0] = 0; /* let MSACM format this for us... */
812 return MMSYSERR_NOERROR
;
815 /***********************************************************************
816 * MPEG3_FormatSuggest
819 static LRESULT
MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs
)
822 if (adfs
->cbwfxSrc
< sizeof(PCMWAVEFORMAT
) ||
823 adfs
->cbwfxDst
< sizeof(PCMWAVEFORMAT
) ||
824 MPEG3_GetFormatIndex(adfs
->pwfxSrc
) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE
;
825 /* FIXME: should do those tests against the real size (according to format tag */
827 /* If no suggestion for destination, then copy source value */
828 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_NCHANNELS
))
829 adfs
->pwfxDst
->nChannels
= adfs
->pwfxSrc
->nChannels
;
830 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_NSAMPLESPERSEC
))
831 adfs
->pwfxDst
->nSamplesPerSec
= adfs
->pwfxSrc
->nSamplesPerSec
;
832 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_WBITSPERSAMPLE
))
833 adfs
->pwfxDst
->wBitsPerSample
= 16;
834 if (!(adfs
->fdwSuggest
& ACM_FORMATSUGGESTF_WFORMATTAG
))
836 if (adfs
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
)
838 WARN("Encoding to MPEG is not supported\n");
839 return ACMERR_NOTPOSSIBLE
;
842 adfs
->pwfxDst
->wFormatTag
= WAVE_FORMAT_PCM
;
845 /* check if result is ok */
846 if (MPEG3_GetFormatIndex(adfs
->pwfxDst
) == 0xFFFFFFFF) return ACMERR_NOTPOSSIBLE
;
848 /* recompute other values */
849 switch (adfs
->pwfxDst
->wFormatTag
)
851 case WAVE_FORMAT_PCM
:
852 adfs
->pwfxDst
->nBlockAlign
= (adfs
->pwfxDst
->nChannels
* adfs
->pwfxDst
->wBitsPerSample
) / 8;
853 adfs
->pwfxDst
->nAvgBytesPerSec
= adfs
->pwfxDst
->nSamplesPerSec
* adfs
->pwfxDst
->nBlockAlign
;
855 case WAVE_FORMAT_MPEG
:
856 case WAVE_FORMAT_MPEGLAYER3
:
857 WARN("Encoding to MPEG is not supported\n");
858 return ACMERR_NOTPOSSIBLE
;
865 return MMSYSERR_NOERROR
;
868 /***********************************************************************
872 static LRESULT
MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi
, PACMDRVSTREAMSIZE adss
)
876 switch (adss
->fdwSize
)
878 case ACM_STREAMSIZEF_DESTINATION
:
879 /* cbDstLength => cbSrcLength */
880 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
881 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
882 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MPEG
))
884 nblocks
= (adss
->cbDstLength
- 3000) / (DWORD
)(adsi
->pwfxDst
->nAvgBytesPerSec
* 1152 / adsi
->pwfxDst
->nSamplesPerSec
+ 0.5);
886 return ACMERR_NOTPOSSIBLE
;
887 adss
->cbSrcLength
= nblocks
* 1152 * adsi
->pwfxSrc
->nBlockAlign
;
889 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
890 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEG
) &&
891 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
893 nblocks
= adss
->cbDstLength
/ (adsi
->pwfxDst
->nBlockAlign
* 1152);
895 return ACMERR_NOTPOSSIBLE
;
896 adss
->cbSrcLength
= nblocks
* (DWORD
)(adsi
->pwfxSrc
->nAvgBytesPerSec
* 1152 / adsi
->pwfxSrc
->nSamplesPerSec
);
900 return MMSYSERR_NOTSUPPORTED
;
903 case ACM_STREAMSIZEF_SOURCE
:
904 /* cbSrcLength => cbDstLength */
905 if (adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_PCM
&&
906 (adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
907 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_MPEG
))
909 nblocks
= adss
->cbSrcLength
/ (adsi
->pwfxSrc
->nBlockAlign
* 1152);
910 if (adss
->cbSrcLength
% (DWORD
)(adsi
->pwfxSrc
->nBlockAlign
* 1152))
911 /* Round block count up. */
914 return ACMERR_NOTPOSSIBLE
;
915 adss
->cbDstLength
= 3000 + nblocks
* (DWORD
)(adsi
->pwfxDst
->nAvgBytesPerSec
* 1152 / adsi
->pwfxDst
->nSamplesPerSec
+ 0.5);
917 else if ((adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEGLAYER3
||
918 adsi
->pwfxSrc
->wFormatTag
== WAVE_FORMAT_MPEG
) &&
919 adsi
->pwfxDst
->wFormatTag
== WAVE_FORMAT_PCM
)
921 nblocks
= adss
->cbSrcLength
/ (DWORD
)(adsi
->pwfxSrc
->nAvgBytesPerSec
* 1152 / adsi
->pwfxSrc
->nSamplesPerSec
);
922 if (adss
->cbSrcLength
% (DWORD
)(adsi
->pwfxSrc
->nAvgBytesPerSec
* 1152 / adsi
->pwfxSrc
->nSamplesPerSec
))
923 /* Round block count up. */
926 return ACMERR_NOTPOSSIBLE
;
927 adss
->cbDstLength
= nblocks
* 1152 * adsi
->pwfxDst
->nBlockAlign
;
931 return MMSYSERR_NOTSUPPORTED
;
935 WARN("Unsupported query %08x\n", adss
->fdwSize
);
936 return MMSYSERR_NOTSUPPORTED
;
938 return MMSYSERR_NOERROR
;
941 /***********************************************************************
942 * MPEG3_StreamConvert
945 static LRESULT
MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi
, PACMDRVSTREAMHEADER adsh
)
947 AcmMpeg3Data
* aad
= (AcmMpeg3Data
*)adsi
->dwDriver
;
948 DWORD nsrc
= adsh
->cbSrcLength
;
949 DWORD ndst
= adsh
->cbDstLength
;
951 if (adsh
->fdwConvert
&
952 ~(ACM_STREAMCONVERTF_BLOCKALIGN
|
953 ACM_STREAMCONVERTF_END
|
954 ACM_STREAMCONVERTF_START
))
956 FIXME("Unsupported fdwConvert (%08x), ignoring it\n", adsh
->fdwConvert
);
958 /* ACM_STREAMCONVERTF_BLOCKALIGN
959 * currently all conversions are block aligned, so do nothing for this flag
960 * ACM_STREAMCONVERTF_END
961 * no pending data, so do nothing for this flag
963 if ((adsh
->fdwConvert
& ACM_STREAMCONVERTF_START
))
965 MPEG3_Reset(adsi
, aad
);
968 aad
->convert(adsi
, adsh
->pbSrc
, &nsrc
, adsh
->pbDst
, &ndst
);
969 adsh
->cbSrcLengthUsed
= nsrc
;
970 adsh
->cbDstLengthUsed
= ndst
;
972 return MMSYSERR_NOERROR
;
975 /**************************************************************************
976 * MPEG3_DriverProc [exported]
978 LRESULT CALLBACK
MPEG3_DriverProc(DWORD_PTR dwDevID
, HDRVR hDriv
, UINT wMsg
,
979 LPARAM dwParam1
, LPARAM dwParam2
)
981 TRACE("(%08lx %p %04x %08lx %08lx);\n",
982 dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);
986 case DRV_LOAD
: return 1;
987 case DRV_FREE
: return 1;
988 case DRV_OPEN
: return MPEG3_drvOpen((LPSTR
)dwParam1
);
989 case DRV_CLOSE
: return MPEG3_drvClose(dwDevID
);
990 case DRV_ENABLE
: return 1;
991 case DRV_DISABLE
: return 1;
992 case DRV_QUERYCONFIGURE
: return 1;
993 case DRV_CONFIGURE
: MessageBoxA(0, "MPEG3 filter !", "Wine Driver", MB_OK
); return 1;
994 case DRV_INSTALL
: return DRVCNF_RESTART
;
995 case DRV_REMOVE
: return DRVCNF_RESTART
;
997 case ACMDM_DRIVER_NOTIFY
:
998 /* no caching from other ACM drivers is done so far */
999 return MMSYSERR_NOERROR
;
1001 case ACMDM_DRIVER_DETAILS
:
1002 return MPEG3_DriverDetails((PACMDRIVERDETAILSW
)dwParam1
);
1004 case ACMDM_FORMATTAG_DETAILS
:
1005 return MPEG3_FormatTagDetails((PACMFORMATTAGDETAILSW
)dwParam1
, dwParam2
);
1007 case ACMDM_FORMAT_DETAILS
:
1008 return MPEG3_FormatDetails((PACMFORMATDETAILSW
)dwParam1
, dwParam2
);
1010 case ACMDM_FORMAT_SUGGEST
:
1011 return MPEG3_FormatSuggest((PACMDRVFORMATSUGGEST
)dwParam1
);
1013 case ACMDM_STREAM_OPEN
:
1014 return MPEG3_StreamOpen((PACMDRVSTREAMINSTANCE
)dwParam1
);
1016 case ACMDM_STREAM_CLOSE
:
1017 return MPEG3_StreamClose((PACMDRVSTREAMINSTANCE
)dwParam1
);
1019 case ACMDM_STREAM_SIZE
:
1020 return MPEG3_StreamSize((PACMDRVSTREAMINSTANCE
)dwParam1
, (PACMDRVSTREAMSIZE
)dwParam2
);
1022 case ACMDM_STREAM_CONVERT
:
1023 return MPEG3_StreamConvert((PACMDRVSTREAMINSTANCE
)dwParam1
, (PACMDRVSTREAMHEADER
)dwParam2
);
1025 case ACMDM_HARDWARE_WAVE_CAPS_INPUT
:
1026 case ACMDM_HARDWARE_WAVE_CAPS_OUTPUT
:
1027 /* this converter is not a hardware driver */
1028 case ACMDM_FILTERTAG_DETAILS
:
1029 case ACMDM_FILTER_DETAILS
:
1030 /* this converter is not a filter */
1031 case ACMDM_STREAM_RESET
:
1032 /* only needed for asynchronous driver... we aren't, so just say it */
1033 return MMSYSERR_NOTSUPPORTED
;
1034 case ACMDM_STREAM_PREPARE
:
1035 case ACMDM_STREAM_UNPREPARE
:
1036 /* nothing special to do here... so don't do anything */
1037 return MMSYSERR_NOERROR
;
1040 return DefDriverProc(dwDevID
, hDriv
, wMsg
, dwParam1
, dwParam2
);