winemp3.acm: Support mp3 decoding on Mac OS/X Leopard systems.
This commit is contained in:
parent
c177e938ae
commit
4430ab435d
|
@ -5687,6 +5687,9 @@ done
|
||||||
|
|
||||||
for ac_header in \
|
for ac_header in \
|
||||||
AL/al.h \
|
AL/al.h \
|
||||||
|
AudioToolbox/AudioConverter.h \
|
||||||
|
AudioToolbox/AudioFile.h \
|
||||||
|
AudioToolbox/AudioFileStream.h \
|
||||||
AudioUnit/AudioUnit.h \
|
AudioUnit/AudioUnit.h \
|
||||||
Carbon/Carbon.h \
|
Carbon/Carbon.h \
|
||||||
CoreAudio/CoreAudio.h \
|
CoreAudio/CoreAudio.h \
|
||||||
|
@ -6448,6 +6451,24 @@ fi
|
||||||
then
|
then
|
||||||
COREAUDIO="-framework CoreAudio -framework AudioUnit -framework CoreServices -framework AudioToolbox -framework CoreMIDI"
|
COREAUDIO="-framework CoreAudio -framework AudioUnit -framework CoreServices -framework AudioToolbox -framework CoreMIDI"
|
||||||
|
|
||||||
|
ac_save_LIBS="$LIBS"
|
||||||
|
if test "$ac_cv_header_AudioToolbox_AudioFile_h" = "yes"
|
||||||
|
then
|
||||||
|
LIBS="$LIBS $COREAUDIO"
|
||||||
|
for ac_func in AudioFileStreamOpen
|
||||||
|
do :
|
||||||
|
ac_fn_c_check_func "$LINENO" "AudioFileStreamOpen" "ac_cv_func_AudioFileStreamOpen"
|
||||||
|
if test "x$ac_cv_func_AudioFileStreamOpen" = x""yes; then :
|
||||||
|
cat >>confdefs.h <<_ACEOF
|
||||||
|
#define HAVE_AUDIOFILESTREAMOPEN 1
|
||||||
|
_ACEOF
|
||||||
|
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
LIBS="$ac_save_LIBS"
|
||||||
|
fi
|
||||||
|
test "x$ac_cv_func_AudioFileStreamOpen" = xyes || as_fn_append wine_notices "|AudioToolbox version too old, mp3 codec won't be supported."
|
||||||
fi
|
fi
|
||||||
if test "$ac_cv_header_OpenAL_al_h" = "yes"
|
if test "$ac_cv_header_OpenAL_al_h" = "yes"
|
||||||
then
|
then
|
||||||
|
@ -11287,7 +11308,7 @@ if test "x$ac_cv_lib_mpg123_mpg123_feed" = x""yes; then :
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi
|
fi
|
||||||
if test "x$ac_cv_lib_mpg123_mpg123_feed" != xyes; then :
|
if test "x$ac_cv_lib_mpg123_mpg123_feed" != xyes -a x"$ac_cv_header_CoreAudio_CoreAudio_h" != xyes; then :
|
||||||
case "x$with_mpg123" in
|
case "x$with_mpg123" in
|
||||||
x) as_fn_append wine_notices "|libmpg123 ${notice_platform}development files not found (or too old), mp3 codec won't be supported." ;;
|
x) as_fn_append wine_notices "|libmpg123 ${notice_platform}development files not found (or too old), mp3 codec won't be supported." ;;
|
||||||
xno) ;;
|
xno) ;;
|
||||||
|
@ -11295,7 +11316,7 @@ if test "x$ac_cv_lib_mpg123_mpg123_feed" != xyes; then :
|
||||||
This is an error since --with-mpg123 was requested." "$LINENO" 5 ;;
|
This is an error since --with-mpg123 was requested." "$LINENO" 5 ;;
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
test "x$ac_cv_lib_mpg123_mpg123_feed" = xyes || enable_winemp3_acm=${enable_winemp3_acm:-no}
|
test "x$ac_cv_lib_mpg123_mpg123_feed" = xyes -o "x$ac_cv_func_AudioFileStreamOpen" = xyes || enable_winemp3_acm=${enable_winemp3_acm:-no}
|
||||||
|
|
||||||
if test "$ac_cv_header_AL_al_h" = "yes"
|
if test "$ac_cv_header_AL_al_h" = "yes"
|
||||||
then
|
then
|
||||||
|
|
15
configure.ac
15
configure.ac
|
@ -308,6 +308,9 @@ AC_SYS_LARGEFILE()
|
||||||
|
|
||||||
AC_CHECK_HEADERS(\
|
AC_CHECK_HEADERS(\
|
||||||
AL/al.h \
|
AL/al.h \
|
||||||
|
AudioToolbox/AudioConverter.h \
|
||||||
|
AudioToolbox/AudioFile.h \
|
||||||
|
AudioToolbox/AudioFileStream.h \
|
||||||
AudioUnit/AudioUnit.h \
|
AudioUnit/AudioUnit.h \
|
||||||
Carbon/Carbon.h \
|
Carbon/Carbon.h \
|
||||||
CoreAudio/CoreAudio.h \
|
CoreAudio/CoreAudio.h \
|
||||||
|
@ -643,6 +646,14 @@ case $host_os in
|
||||||
then
|
then
|
||||||
dnl CoreServices needed by AudioUnit
|
dnl CoreServices needed by AudioUnit
|
||||||
AC_SUBST(COREAUDIO,"-framework CoreAudio -framework AudioUnit -framework CoreServices -framework AudioToolbox -framework CoreMIDI")
|
AC_SUBST(COREAUDIO,"-framework CoreAudio -framework AudioUnit -framework CoreServices -framework AudioToolbox -framework CoreMIDI")
|
||||||
|
ac_save_LIBS="$LIBS"
|
||||||
|
if test "$ac_cv_header_AudioToolbox_AudioFile_h" = "yes"
|
||||||
|
then
|
||||||
|
LIBS="$LIBS $COREAUDIO"
|
||||||
|
AC_CHECK_FUNCS(AudioFileStreamOpen)
|
||||||
|
LIBS="$ac_save_LIBS"
|
||||||
|
fi
|
||||||
|
test "x$ac_cv_func_AudioFileStreamOpen" = xyes || WINE_NOTICE([AudioToolbox version too old, mp3 codec won't be supported.])
|
||||||
fi
|
fi
|
||||||
if test "$ac_cv_header_OpenAL_al_h" = "yes"
|
if test "$ac_cv_header_OpenAL_al_h" = "yes"
|
||||||
then
|
then
|
||||||
|
@ -1452,9 +1463,9 @@ if test "$ac_cv_header_mpg123_h" = "yes"
|
||||||
then
|
then
|
||||||
AC_CHECK_LIB(mpg123,mpg123_feed,[AC_SUBST(LIBMPG123,"-lmpg123")])
|
AC_CHECK_LIB(mpg123,mpg123_feed,[AC_SUBST(LIBMPG123,"-lmpg123")])
|
||||||
fi
|
fi
|
||||||
WINE_NOTICE_WITH(mpg123,[test "x$ac_cv_lib_mpg123_mpg123_feed" != xyes],
|
WINE_NOTICE_WITH(mpg123,[test "x$ac_cv_lib_mpg123_mpg123_feed" != xyes -a x"$ac_cv_header_CoreAudio_CoreAudio_h" != xyes],
|
||||||
[libmpg123 ${notice_platform}development files not found (or too old), mp3 codec won't be supported.])
|
[libmpg123 ${notice_platform}development files not found (or too old), mp3 codec won't be supported.])
|
||||||
test "x$ac_cv_lib_mpg123_mpg123_feed" = xyes || enable_winemp3_acm=${enable_winemp3_acm:-no}
|
test "x$ac_cv_lib_mpg123_mpg123_feed" = xyes -o "x$ac_cv_func_AudioFileStreamOpen" = xyes || enable_winemp3_acm=${enable_winemp3_acm:-no}
|
||||||
|
|
||||||
dnl **** Check for OpenAL 1.1 ****
|
dnl **** Check for OpenAL 1.1 ****
|
||||||
if test "$ac_cv_header_AL_al_h" = "yes"
|
if test "$ac_cv_header_AL_al_h" = "yes"
|
||||||
|
|
|
@ -4,7 +4,7 @@ SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = winemp3.acm
|
MODULE = winemp3.acm
|
||||||
IMPORTS = winmm user32 kernel32
|
IMPORTS = winmm user32 kernel32
|
||||||
EXTRALIBS = @LIBMPG123@
|
EXTRALIBS = @LIBMPG123@ @COREAUDIO@
|
||||||
|
|
||||||
C_SRCS = \
|
C_SRCS = \
|
||||||
mpegl3.c
|
mpegl3.c
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/*
|
/*
|
||||||
* MPEG Layer 3 handling
|
* MPEG Layer 3 handling
|
||||||
*
|
*
|
||||||
* Copyright (C) 2002 Eric Pouech
|
* Copyright (C) 2002 Eric Pouech
|
||||||
* Copyright (C) 2009 CodeWeavers, Aric Stewart
|
* Copyright (C) 2009 CodeWeavers, Aric Stewart
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
|
@ -26,6 +26,25 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_MPG123_H
|
||||||
|
# include <mpg123.h>
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_COREAUDIO_COREAUDIO_H
|
||||||
|
# include <CoreFoundation/CoreFoundation.h>
|
||||||
|
# include <CoreAudio/CoreAudio.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H
|
||||||
|
# include <AudioToolbox/AudioConverter.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_AUDIOTOOLBOX_AUDIOFILE_H
|
||||||
|
# include <AudioToolbox/AudioFile.h>
|
||||||
|
# endif
|
||||||
|
# ifdef HAVE_AUDIOTOOLBOX_AUDIOFILESTREAM_H
|
||||||
|
# include <AudioToolbox/AudioFileStream.h>
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
|
@ -35,40 +54,10 @@
|
||||||
#include "mmreg.h"
|
#include "mmreg.h"
|
||||||
#include "msacm.h"
|
#include "msacm.h"
|
||||||
#include "msacmdrv.h"
|
#include "msacmdrv.h"
|
||||||
|
|
||||||
#ifdef HAVE_MPG123_H
|
|
||||||
#include <mpg123.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(mpeg3);
|
WINE_DEFAULT_DEBUG_CHANNEL(mpeg3);
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* MPEG3_drvOpen
|
|
||||||
*/
|
|
||||||
static LRESULT MPEG3_drvOpen(LPCSTR str)
|
|
||||||
{
|
|
||||||
mpg123_init();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* MPEG3_drvClose
|
|
||||||
*/
|
|
||||||
static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
|
|
||||||
{
|
|
||||||
mpg123_exit();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct tagAcmMpeg3Data
|
|
||||||
{
|
|
||||||
void (*convert)(PACMDRVSTREAMINSTANCE adsi,
|
|
||||||
const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
|
|
||||||
mpg123_handle *mh;
|
|
||||||
} AcmMpeg3Data;
|
|
||||||
|
|
||||||
/* table to list all supported formats... those are the basic ones. this
|
/* table to list all supported formats... those are the basic ones. this
|
||||||
* also helps given a unique index to each of the supported formats
|
* also helps given a unique index to each of the supported formats
|
||||||
*/
|
*/
|
||||||
|
@ -141,6 +130,34 @@ static DWORD MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
|
||||||
return 0xFFFFFFFF;
|
return 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_MPG123_H
|
||||||
|
|
||||||
|
typedef struct tagAcmMpeg3Data
|
||||||
|
{
|
||||||
|
void (*convert)(PACMDRVSTREAMINSTANCE adsi,
|
||||||
|
const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
|
||||||
|
mpg123_handle *mh;
|
||||||
|
} AcmMpeg3Data;
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_drvOpen
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_drvOpen(LPCSTR str)
|
||||||
|
{
|
||||||
|
mpg123_init();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_drvClose
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
|
||||||
|
{
|
||||||
|
mpg123_exit();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
|
static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
|
||||||
const unsigned char* src, LPDWORD nsrc,
|
const unsigned char* src, LPDWORD nsrc,
|
||||||
unsigned char* dst, LPDWORD ndst)
|
unsigned char* dst, LPDWORD ndst)
|
||||||
|
@ -185,6 +202,314 @@ static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
|
||||||
*ndst = dpos;
|
*ndst = dpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_Reset
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
|
||||||
|
{
|
||||||
|
mpg123_feedseek(aad->mh, 0, SEEK_SET, NULL);
|
||||||
|
mpg123_close(aad->mh);
|
||||||
|
mpg123_open_feed(aad->mh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_StreamOpen
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||||
|
{
|
||||||
|
AcmMpeg3Data* aad;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
||||||
|
|
||||||
|
if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
||||||
|
MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
|
||||||
|
aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data));
|
||||||
|
if (aad == 0) return MMSYSERR_NOMEM;
|
||||||
|
|
||||||
|
adsi->dwDriver = (DWORD_PTR)aad;
|
||||||
|
|
||||||
|
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||||
|
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||||
|
{
|
||||||
|
goto theEnd;
|
||||||
|
}
|
||||||
|
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 &&
|
||||||
|
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||||
|
{
|
||||||
|
/* resampling or mono <=> stereo not available
|
||||||
|
* MPEG3 algo only define 16 bit per sample output
|
||||||
|
*/
|
||||||
|
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
|
||||||
|
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
|
||||||
|
adsi->pwfxDst->wBitsPerSample != 16)
|
||||||
|
goto theEnd;
|
||||||
|
aad->convert = mp3_horse;
|
||||||
|
aad->mh = mpg123_new(NULL,&err);
|
||||||
|
mpg123_open_feed(aad->mh);
|
||||||
|
}
|
||||||
|
/* no encoding yet
|
||||||
|
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||||
|
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
|
||||||
|
*/
|
||||||
|
else goto theEnd;
|
||||||
|
MPEG3_Reset(adsi, aad);
|
||||||
|
|
||||||
|
return MMSYSERR_NOERROR;
|
||||||
|
|
||||||
|
theEnd:
|
||||||
|
HeapFree(GetProcessHeap(), 0, aad);
|
||||||
|
adsi->dwDriver = 0L;
|
||||||
|
return MMSYSERR_NOTSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_StreamClose
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
||||||
|
{
|
||||||
|
mpg123_close(((AcmMpeg3Data*)adsi->dwDriver)->mh);
|
||||||
|
mpg123_delete(((AcmMpeg3Data*)adsi->dwDriver)->mh);
|
||||||
|
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
||||||
|
return MMSYSERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(HAVE_AUDIOFILESTREAMOPEN)
|
||||||
|
|
||||||
|
typedef struct tagAcmMpeg3Data
|
||||||
|
{
|
||||||
|
LRESULT (*convert)(PACMDRVSTREAMINSTANCE adsi,
|
||||||
|
const unsigned char*, LPDWORD, unsigned char*, LPDWORD);
|
||||||
|
AudioConverterRef acr;
|
||||||
|
AudioStreamBasicDescription in,out;
|
||||||
|
AudioFileStreamID afs;
|
||||||
|
|
||||||
|
AudioBufferList outBuffer;
|
||||||
|
AudioBuffer inBuffer;
|
||||||
|
|
||||||
|
UInt32 NumberPackets;
|
||||||
|
AudioStreamPacketDescription *PacketDescriptions;
|
||||||
|
|
||||||
|
OSStatus lastError;
|
||||||
|
} AcmMpeg3Data;
|
||||||
|
|
||||||
|
static inline const char* wine_dbgstr_fourcc(unsigned long fourcc)
|
||||||
|
{
|
||||||
|
char buf[4] = { (char) (fourcc >> 24), (char) (fourcc >> 16),
|
||||||
|
(char) (fourcc >> 8), (char) fourcc };
|
||||||
|
return wine_dbgstr_an(buf, sizeof(buf));
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_drvOpen
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_drvOpen(LPCSTR str)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_drvClose
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static OSStatus Mp3AudioConverterComplexInputDataProc (
|
||||||
|
AudioConverterRef inAudioConverter,
|
||||||
|
UInt32 *ioNumberDataPackets,
|
||||||
|
AudioBufferList *ioData,
|
||||||
|
AudioStreamPacketDescription **outDataPacketDescription,
|
||||||
|
void *inUserData
|
||||||
|
)
|
||||||
|
{
|
||||||
|
AcmMpeg3Data *amd = (AcmMpeg3Data*)inUserData;
|
||||||
|
|
||||||
|
if (amd->inBuffer.mDataByteSize > 0)
|
||||||
|
{
|
||||||
|
*ioNumberDataPackets = amd->NumberPackets;
|
||||||
|
ioData->mNumberBuffers = 1;
|
||||||
|
ioData->mBuffers[0].mDataByteSize = amd->inBuffer.mDataByteSize;
|
||||||
|
ioData->mBuffers[0].mData = amd->inBuffer.mData;
|
||||||
|
ioData->mBuffers[0].mNumberChannels = amd->inBuffer.mNumberChannels;
|
||||||
|
amd->inBuffer.mDataByteSize = 0;
|
||||||
|
if (outDataPacketDescription)
|
||||||
|
*outDataPacketDescription = amd->PacketDescriptions;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*ioNumberDataPackets = 0;
|
||||||
|
return noErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static LRESULT mp3_leopard_horse(PACMDRVSTREAMINSTANCE adsi,
|
||||||
|
const unsigned char* src, LPDWORD nsrc,
|
||||||
|
unsigned char* dst, LPDWORD ndst)
|
||||||
|
{
|
||||||
|
AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
|
||||||
|
OSStatus ret;
|
||||||
|
|
||||||
|
TRACE("ndst %u %p <- %u %p\n",*ndst,dst,*nsrc, src);
|
||||||
|
amd->outBuffer.mNumberBuffers = 1;
|
||||||
|
amd->outBuffer.mBuffers[0].mDataByteSize = *ndst;
|
||||||
|
amd->outBuffer.mBuffers[0].mData = dst;
|
||||||
|
amd->outBuffer.mBuffers[0].mNumberChannels = amd->out.mChannelsPerFrame;
|
||||||
|
|
||||||
|
memset(dst,0xff,*ndst);
|
||||||
|
ret = AudioFileStreamParseBytes( amd->afs, *nsrc, src, 0 );
|
||||||
|
|
||||||
|
if (ret != noErr)
|
||||||
|
{
|
||||||
|
*nsrc = 0;
|
||||||
|
ERR("Feed Error %s\n", wine_dbgstr_fourcc(ret));
|
||||||
|
return MMSYSERR_ERROR;
|
||||||
|
}
|
||||||
|
else if (amd->lastError != noErr)
|
||||||
|
{
|
||||||
|
*nsrc = 0;
|
||||||
|
ERR("Error during feed %s\n", wine_dbgstr_fourcc(ret));
|
||||||
|
return MMSYSERR_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ndst = amd->outBuffer.mBuffers[0].mDataByteSize;
|
||||||
|
*nsrc = amd->inBuffer.mDataByteSize;
|
||||||
|
|
||||||
|
return MMSYSERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_Reset
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
|
||||||
|
{
|
||||||
|
SInt64 offset;
|
||||||
|
AudioConverterReset(aad->acr);
|
||||||
|
AudioFileStreamSeek(aad->afs, 0, &offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mp3PropertyListenerProc ( void *inClientData,
|
||||||
|
AudioFileStreamID inAudioFileStream, UInt32 inPropertyID, UInt32 *ioFlags)
|
||||||
|
{
|
||||||
|
/* No operation at this time */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Mp3PacketsProc ( void *inClientData, UInt32 inNumberBytes,
|
||||||
|
UInt32 inNumberPackets, const void *inInputData,
|
||||||
|
AudioStreamPacketDescription *inPacketDescriptions)
|
||||||
|
{
|
||||||
|
AcmMpeg3Data *amd = (AcmMpeg3Data*)inClientData;
|
||||||
|
UInt32 size;
|
||||||
|
|
||||||
|
amd->inBuffer.mDataByteSize = inNumberBytes;
|
||||||
|
amd->inBuffer.mData = (void*)inInputData;
|
||||||
|
amd->inBuffer.mNumberChannels = amd->in.mChannelsPerFrame;
|
||||||
|
|
||||||
|
amd->NumberPackets = inNumberPackets;
|
||||||
|
amd->PacketDescriptions = inPacketDescriptions;
|
||||||
|
|
||||||
|
size = amd->outBuffer.mBuffers[0].mDataByteSize / amd->out.mBytesPerPacket;
|
||||||
|
amd->lastError = AudioConverterFillComplexBuffer(amd->acr, Mp3AudioConverterComplexInputDataProc, inClientData, &size, &amd->outBuffer, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_StreamOpen
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
||||||
|
{
|
||||||
|
AcmMpeg3Data* aad;
|
||||||
|
|
||||||
|
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
||||||
|
|
||||||
|
if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
||||||
|
MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
|
||||||
|
return ACMERR_NOTPOSSIBLE;
|
||||||
|
|
||||||
|
aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data));
|
||||||
|
if (aad == 0) return MMSYSERR_NOMEM;
|
||||||
|
|
||||||
|
adsi->dwDriver = (DWORD_PTR)aad;
|
||||||
|
|
||||||
|
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
||||||
|
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||||
|
{
|
||||||
|
goto theEnd;
|
||||||
|
}
|
||||||
|
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 &&
|
||||||
|
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
||||||
|
{
|
||||||
|
OSStatus err;
|
||||||
|
|
||||||
|
aad->in.mSampleRate = adsi->pwfxSrc->nSamplesPerSec;
|
||||||
|
aad->out.mSampleRate = adsi->pwfxDst->nSamplesPerSec;
|
||||||
|
aad->in.mBitsPerChannel = adsi->pwfxSrc->wBitsPerSample;
|
||||||
|
aad->out.mBitsPerChannel = adsi->pwfxDst->wBitsPerSample;
|
||||||
|
aad->in.mFormatID = kAudioFormatMPEGLayer3;
|
||||||
|
aad->out.mFormatID = kAudioFormatLinearPCM;
|
||||||
|
aad->in.mChannelsPerFrame = adsi->pwfxSrc->nChannels;
|
||||||
|
aad->out.mChannelsPerFrame = adsi->pwfxDst->nChannels;
|
||||||
|
aad->in.mFormatFlags = 0;
|
||||||
|
aad->out.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger;
|
||||||
|
aad->in.mBytesPerFrame = 0;
|
||||||
|
|
||||||
|
aad->out.mBytesPerFrame = (aad->out.mBitsPerChannel * aad->out.mChannelsPerFrame) / 8;
|
||||||
|
aad->in.mBytesPerPacket = 0;
|
||||||
|
aad->out.mBytesPerPacket = aad->out.mBytesPerFrame;
|
||||||
|
aad->in.mFramesPerPacket = 0;
|
||||||
|
aad->out.mFramesPerPacket = 1;
|
||||||
|
aad->in.mReserved = aad->out.mReserved = 0;
|
||||||
|
|
||||||
|
aad->acr = NULL;
|
||||||
|
|
||||||
|
err = AudioConverterNew(&aad->in, &aad->out ,&aad->acr);
|
||||||
|
if (err != noErr)
|
||||||
|
{
|
||||||
|
ERR("Create failed: %s\n", wine_dbgstr_fourcc(err));
|
||||||
|
goto theEnd;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aad->convert = mp3_leopard_horse;
|
||||||
|
err = AudioFileStreamOpen(aad, Mp3PropertyListenerProc, Mp3PacketsProc, kAudioFormatMPEGLayer3, &aad->afs);
|
||||||
|
if (err != noErr)
|
||||||
|
{
|
||||||
|
ERR("Stream Open failed: %s\n", wine_dbgstr_fourcc(err));
|
||||||
|
goto theEnd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else goto theEnd;
|
||||||
|
MPEG3_Reset(adsi, aad);
|
||||||
|
|
||||||
|
return MMSYSERR_NOERROR;
|
||||||
|
|
||||||
|
theEnd:
|
||||||
|
HeapFree(GetProcessHeap(), 0, aad);
|
||||||
|
adsi->dwDriver = 0L;
|
||||||
|
return MMSYSERR_NOTSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* MPEG3_StreamClose
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
||||||
|
{
|
||||||
|
AudioConverterDispose(((AcmMpeg3Data*)adsi->dwDriver)->acr);
|
||||||
|
AudioFileStreamClose(((AcmMpeg3Data*)adsi->dwDriver)->afs);
|
||||||
|
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
||||||
|
return MMSYSERR_NOERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* MPEG3_DriverDetails
|
* MPEG3_DriverDetails
|
||||||
*
|
*
|
||||||
|
@ -390,83 +715,6 @@ static LRESULT MPEG3_FormatSuggest(PACMDRVFORMATSUGGEST adfs)
|
||||||
return MMSYSERR_NOERROR;
|
return MMSYSERR_NOERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* MPEG3_Reset
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
|
|
||||||
{
|
|
||||||
mpg123_feedseek(aad->mh, 0, SEEK_SET, NULL);
|
|
||||||
mpg123_close(aad->mh);
|
|
||||||
mpg123_open_feed(aad->mh);
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* MPEG3_StreamOpen
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static LRESULT MPEG3_StreamOpen(PACMDRVSTREAMINSTANCE adsi)
|
|
||||||
{
|
|
||||||
AcmMpeg3Data* aad;
|
|
||||||
int err;
|
|
||||||
|
|
||||||
assert(!(adsi->fdwOpen & ACM_STREAMOPENF_ASYNC));
|
|
||||||
|
|
||||||
if (MPEG3_GetFormatIndex(adsi->pwfxSrc) == 0xFFFFFFFF ||
|
|
||||||
MPEG3_GetFormatIndex(adsi->pwfxDst) == 0xFFFFFFFF)
|
|
||||||
return ACMERR_NOTPOSSIBLE;
|
|
||||||
|
|
||||||
aad = HeapAlloc(GetProcessHeap(), 0, sizeof(AcmMpeg3Data));
|
|
||||||
if (aad == 0) return MMSYSERR_NOMEM;
|
|
||||||
|
|
||||||
adsi->dwDriver = (DWORD_PTR)aad;
|
|
||||||
|
|
||||||
if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
|
||||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
|
||||||
{
|
|
||||||
goto theEnd;
|
|
||||||
}
|
|
||||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3 &&
|
|
||||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
|
|
||||||
{
|
|
||||||
/* resampling or mono <=> stereo not available
|
|
||||||
* MPEG3 algo only define 16 bit per sample output
|
|
||||||
*/
|
|
||||||
if (adsi->pwfxSrc->nSamplesPerSec != adsi->pwfxDst->nSamplesPerSec ||
|
|
||||||
adsi->pwfxSrc->nChannels != adsi->pwfxDst->nChannels ||
|
|
||||||
adsi->pwfxDst->wBitsPerSample != 16)
|
|
||||||
goto theEnd;
|
|
||||||
aad->convert = mp3_horse;
|
|
||||||
aad->mh = mpg123_new(NULL,&err);
|
|
||||||
mpg123_open_feed(aad->mh);
|
|
||||||
}
|
|
||||||
/* no encoding yet
|
|
||||||
else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
|
|
||||||
adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
|
|
||||||
*/
|
|
||||||
else goto theEnd;
|
|
||||||
MPEG3_Reset(adsi, aad);
|
|
||||||
|
|
||||||
return MMSYSERR_NOERROR;
|
|
||||||
|
|
||||||
theEnd:
|
|
||||||
HeapFree(GetProcessHeap(), 0, aad);
|
|
||||||
adsi->dwDriver = 0L;
|
|
||||||
return MMSYSERR_NOTSUPPORTED;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* MPEG3_StreamClose
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)
|
|
||||||
{
|
|
||||||
mpg123_close(((AcmMpeg3Data*)adsi->dwDriver)->mh);
|
|
||||||
mpg123_delete(((AcmMpeg3Data*)adsi->dwDriver)->mh);
|
|
||||||
HeapFree(GetProcessHeap(), 0, (void*)adsi->dwDriver);
|
|
||||||
return MMSYSERR_NOERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* MPEG3_StreamSize
|
* MPEG3_StreamSize
|
||||||
*
|
*
|
||||||
|
|
|
@ -32,6 +32,19 @@
|
||||||
/* Define to 1 if you have the <asm/types.h> header file. */
|
/* Define to 1 if you have the <asm/types.h> header file. */
|
||||||
#undef HAVE_ASM_TYPES_H
|
#undef HAVE_ASM_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `AudioFileStreamOpen' function. */
|
||||||
|
#undef HAVE_AUDIOFILESTREAMOPEN
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <AudioToolbox/AudioConverter.h> header file. */
|
||||||
|
#undef HAVE_AUDIOTOOLBOX_AUDIOCONVERTER_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <AudioToolbox/AudioFileStream.h> header file.
|
||||||
|
*/
|
||||||
|
#undef HAVE_AUDIOTOOLBOX_AUDIOFILESTREAM_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <AudioToolbox/AudioFile.h> header file. */
|
||||||
|
#undef HAVE_AUDIOTOOLBOX_AUDIOFILE_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <AudioUnit/AudioUnit.h> header file. */
|
/* Define to 1 if you have the <AudioUnit/AudioUnit.h> header file. */
|
||||||
#undef HAVE_AUDIOUNIT_AUDIOUNIT_H
|
#undef HAVE_AUDIOUNIT_AUDIOUNIT_H
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue