Untitled

mail@pastecode.io avatar
unknown
diff
3 years ago
22 kB
6
Indexable
Never
diff --git a/l3codeca.acm/Makefile.in b/l3codeca.acm/Makefile.in
index 4f946ed654..451794b262 100644
--- a/l3codeca.acm/Makefile.in
+++ b/l3codeca.acm/Makefile.in
@@ -1,7 +1,6 @@
 MODULE    = l3codeca.acm
-IMPORTS   = winmm user32
-EXTRAINCL = $(MPG123_CFLAGS)
-EXTRALIBS = $(MPG123_LIBS) $(COREAUDIO_LIBS)
+IMPORTS   = $(MPG123_PE_LIBS) winmm user32 kernelbase
+EXTRAINCL = $(MPG123_PE_CFLAGS)
 
 C_SRCS = \
 	mpegl3.c
diff --git a/l3codeca.acm/mpegl3.c b/l3codeca.acm/mpegl3.c
index 2e929371ae..336e706bb8 100644
--- a/l3codeca.acm/mpegl3.c
+++ b/l3codeca.acm/mpegl3.c
@@ -3,8 +3,6 @@
  *
  * Copyright (C) 2002 Eric Pouech
  * Copyright (C) 2009 CodeWeavers, Aric Stewart
- * Copyright (C) 2010 Kristofer Henriksson
- *
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -21,24 +19,10 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  */
 
-#include "config.h"
-#include "wine/port.h"
-
 #include <assert.h>
 #include <stdarg.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
-#endif
+#include <mpg123.h>
 
 #include "windef.h"
 #include "winbase.h"
@@ -123,15 +107,6 @@ static	DWORD	MPEG3_GetFormatIndex(LPWAVEFORMATEX wfx)
     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
  */
@@ -151,11 +126,9 @@ static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
 }
 
 
-static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
-                      const unsigned char* src, LPDWORD nsrc,
-                      unsigned char* dst, LPDWORD ndst)
+static void mp3_horse(mpg123_handle *handle, const unsigned char *src,
+        DWORD *nsrc, unsigned char *dst, DWORD *ndst)
 {
-    AcmMpeg3Data*       amd = (AcmMpeg3Data*)adsi->dwDriver;
     int                 ret;
     size_t              size;
     DWORD               dpos = 0;
@@ -163,7 +136,7 @@ static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
 
     if (*nsrc > 0)
     {
-        ret = mpg123_feed(amd->mh, src, *nsrc);
+        ret = mpg123_feed(handle, src, *nsrc);
         if (ret != MPG123_OK)
         {
             ERR("Error feeding data\n");
@@ -174,7 +147,7 @@ static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
 
     do {
         size = 0;
-        ret = mpg123_read(amd->mh, dst + dpos, *ndst - dpos, &size);
+        ret = mpg123_read(handle, dst + dpos, *ndst - dpos, &size);
         if (ret == MPG123_ERR)
         {
             FIXME("Error occurred during decoding!\n");
@@ -186,7 +159,7 @@ static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
         {
             long rate;
             int channels, enc;
-            mpg123_getformat(amd->mh, &rate, &channels, &enc);
+            mpg123_getformat(handle, &rate, &channels, &enc);
             TRACE("New format: %li Hz, %i channels, encoding value %i\n", rate, channels, enc);
         }
         dpos += size;
@@ -195,483 +168,69 @@ static void mp3_horse(PACMDRVSTREAMINSTANCE adsi,
     *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)
+static LRESULT MPEG3_StreamOpen(ACMDRVSTREAMINSTANCE *instance)
 {
-    LRESULT error = MMSYSERR_NOTSUPPORTED;
-    AcmMpeg3Data*	aad;
+    mpg123_handle *handle;
     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->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
-             adsi->pwfxDst->wFormatTag == WAVE_FORMAT_PCM)
-    {
-        if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
-        {
-            MPEGLAYER3WAVEFORMAT *formatmp3 = (MPEGLAYER3WAVEFORMAT *)adsi->pwfxSrc;
-
-            if (adsi->pwfxSrc->cbSize < MPEGLAYER3_WFX_EXTRA_BYTES ||
-                formatmp3->wID != MPEGLAYER3_ID_MPEG)
-            {
-                error = ACMERR_NOTPOSSIBLE;
-                goto theEnd;
-            }
-        }
-
-	/* 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);
-
-#if MPG123_API_VERSION >= 31 /* needed for MPG123_IGNORE_FRAMEINFO enum value */
-        /* mpg123 may find a XING header in the mp3 and use that information
-         * to ask for seeks in order to read specific frames in the file.
-         * We cannot allow that since the caller application is feeding us.
-         * This fixes problems for mp3 files encoded with LAME (bug 42361)
-         */
-        mpg123_param(aad->mh, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0);
-#endif
-    }
-    else if (adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_PCM &&
-             (adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3 ||
-              adsi->pwfxDst->wFormatTag == WAVE_FORMAT_MPEG))
-    {
-        WARN("Encoding to MPEG is not supported\n");
-        goto theEnd;
-    }
-    else goto theEnd;
-    MPEG3_Reset(adsi, aad);
-
-    return MMSYSERR_NOERROR;
-
- theEnd:
-    HeapFree(GetProcessHeap(), 0, aad);
-    adsi->dwDriver = 0L;
-    return error;
-}
-
-/***********************************************************************
- *           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_AUDIOTOOLBOX_AUDIOCONVERTER_H)
-
-static const unsigned short Mp3BitRates[2][16] =
-{
-    {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
-    {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
-};
-
-static const unsigned short Mp3SampleRates[2][4] =
-{
-    {44100, 48000, 32000, 0},
-    {22050, 24000, 16000, 0}
-};
-
-typedef struct tagAcmMpeg3Data
-{
-    LRESULT (*convert)(PACMDRVSTREAMINSTANCE adsi, unsigned char*,
-                       LPDWORD, unsigned char*, LPDWORD);
-    AudioConverterRef acr;
-    AudioStreamBasicDescription in,out;
-
-    AudioBufferList outBuffer;
-    AudioBuffer inBuffer;
-
-    SInt32 tagBytesLeft;
-
-    UInt32 NumberPackets;
-    AudioStreamPacketDescription *PacketDescriptions;
-} AcmMpeg3Data;
-
-/***********************************************************************
- *           MPEG3_drvOpen
- */
-static LRESULT MPEG3_drvOpen(LPCSTR str)
-{
-    return 1;
-}
-
-/***********************************************************************
- *           MPEG3_drvClose
- */
-static LRESULT MPEG3_drvClose(DWORD_PTR dwDevID)
-{
-    return 1;
-}
-
-/*
- When it asks for data, give it all we have. If we have no data, we assume
- we will in the future, so give it no packets and return an error, which
- signals that we will have more later.
- */
-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] = amd->inBuffer;
-        amd->inBuffer.mDataByteSize = 0;
-        if (outDataPacketDescription)
-            *outDataPacketDescription = amd->PacketDescriptions;
-        return noErr;
-    }
-    else
-    {
-        *ioNumberDataPackets = 0;
-        return -74;
-    }
-}
-
-/*
- Get the length of the current frame. We need to be at the start of a
- frame now. The buffer must have at least the four bytes for the header.
- */
-static SInt32 Mp3GetPacketLength(const unsigned char* src)
-{
-    unsigned char mpegv;
-    unsigned short brate, srate;
-    unsigned int size;
-
-    /*
-     Check that our position looks like an MP3 header and see which type
-     of MP3 file we have.
-     */
-    if (src[0] == 0xff && src[1] >> 1 == 0x7d) mpegv = 0; /* MPEG-1 File */
-    else if (src[0] == 0xff && src[1] >> 1 == 0x79) mpegv = 1; /* MPEG-2 File */
-    else return -1;
-
-    /* Fill in bit rate and sample rate. */
-    brate = Mp3BitRates[mpegv][(src[2] & 0xf0) >> 4];
-    srate = Mp3SampleRates[mpegv][(src[2] & 0xc) >> 2];
+    assert(!(instance->fdwOpen & ACM_STREAMOPENF_ASYNC));
 
-    /* Certain values for bit rate and sample rate are invalid. */
-    if (brate == 0 || srate == 0) return -1;
-
-    /* Compute frame size, round down */
-    size = 72 * (2 - mpegv) * brate * 1000 / srate;
-
-    /* If there is padding, add one byte */
-    if (src[2] & 0x2) return size + 1;
-    else return size;
-}
-
-/*
- Apple's AudioFileStream does weird things so we deal with parsing the
- file ourselves. It was also designed for a different use case, so this
- is not unexpected. We expect to have MP3 data as input (i.e. we can only
- deal with MPEG-1 or MPEG-2 Layer III), which simplifies parsing a bit. We
- understand the ID3v2 header and skip over it. Whenever we have data we
- want to skip at the beginning of the input, we do this by setting *ndst=0
- and *nsrc to the length of the unwanted data and return no error.
- */
-static LRESULT mp3_leopard_horse(PACMDRVSTREAMINSTANCE adsi,
-                                 unsigned char* src, LPDWORD nsrc,
-                                 unsigned char* dst, LPDWORD ndst)
-{
-    OSStatus err;
-    UInt32 size, aspdi, synci, syncSkip;
-    short framelen[4];
-    const unsigned char* psrc;
-    AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
-
-    TRACE("ndst %u %p  <-  %u %p\n", *ndst, dst, *nsrc, src);
+    if (MPEG3_GetFormatIndex(instance->pwfxSrc) == 0xFFFFFFFF
+            || MPEG3_GetFormatIndex(instance->pwfxDst) == 0xFFFFFFFF)
+        return ACMERR_NOTPOSSIBLE;
 
-    TRACE("First 16 bytes to input: %s\n", wine_dbgstr_an((const char *)src, 16));
+    if (instance->pwfxDst->wFormatTag != WAVE_FORMAT_PCM)
+        return MMSYSERR_NOTSUPPORTED;
 
-    /* Parse ID3 tag */
-    if (!memcmp(src, "ID3", 3) && amd->tagBytesLeft == -1)
-    {
-        amd->tagBytesLeft = (src[6] << 21) + (src[7] << 14) + (src[8] << 7) + src[9];
-        if (src[5] & 0x10) amd->tagBytesLeft += 20; /* There is a footer */
-        else amd->tagBytesLeft += 10;
-    }
+    if (instance->pwfxSrc->wFormatTag != WAVE_FORMAT_MPEGLAYER3
+            && instance->pwfxSrc->wFormatTag != WAVE_FORMAT_MPEG)
+        return MMSYSERR_NOTSUPPORTED;
 
-    /* Consume the tag */
-    if (amd->tagBytesLeft >= (SInt32)*nsrc)
+    if (instance->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEGLAYER3)
     {
-        *ndst = 0;
-        amd->tagBytesLeft -= *nsrc;
+        MPEGLAYER3WAVEFORMAT *mp3_format = (MPEGLAYER3WAVEFORMAT *)instance->pwfxSrc;
 
-        TRACE("All %d bytes of source data is ID3 tag\n", *nsrc);
-        return MMSYSERR_NOERROR;
-    }
-    else if (amd->tagBytesLeft > 0)
-    {
-        src += amd->tagBytesLeft;
-        *nsrc -= amd->tagBytesLeft;
-        TRACE("Skipping %ld for ID3 tag\n", amd->tagBytesLeft);
+        if (instance->pwfxSrc->cbSize < MPEGLAYER3_WFX_EXTRA_BYTES
+                || mp3_format->wID != MPEGLAYER3_ID_MPEG)
+            return ACMERR_NOTPOSSIBLE;
     }
 
-    /*
-     Sync to initial MP3 frame. The largest possible MP3 frame is 1440.
-     Thus, in the first 1440 bytes we must find the beginning of 3 valid
-     frames in a row unless we reach the end of the file first.
-     */
-    syncSkip = 0;
-    for (psrc = src; psrc <= src + *nsrc - 4 && psrc < src + 1440; psrc++)
-    {
-        framelen[0] = 0;
-        for (synci = 1;
-             synci < 4 && psrc + framelen[synci-1] < src + *nsrc - 4;
-             synci++)
-        {
-            framelen[synci] = Mp3GetPacketLength(psrc + framelen[synci-1]);
-            if (framelen[synci] == -1)
-            {
-                synci = 0;
-                break;
-            }
-            framelen[synci] += framelen[synci-1];
-        }
-        if (synci > 0) /* We synced successfully */
-        {
-            if (psrc - src > 0)
-            {
-                syncSkip = psrc - src;
-                src += syncSkip;
-                *nsrc -= syncSkip;
-                TRACE("Skipping %ld for frame sync\n", syncSkip);
-            }
-            break;
-        }
-    }
+    if (instance->pwfxSrc->nSamplesPerSec != instance->pwfxDst->nSamplesPerSec
+            || instance->pwfxSrc->nChannels != instance->pwfxDst->nChannels
+            || instance->pwfxDst->wBitsPerSample != 16)
+        return MMSYSERR_NOTSUPPORTED;
 
-    if (Mp3GetPacketLength(src) == -1)
-    {
-        *ndst = *nsrc = 0;
-        ERR("Frame sync failed. Cannot play file.\n");
-        return MMSYSERR_ERROR;
-    }
+    handle = mpg123_new(NULL, &err);
+    instance->dwDriver = (DWORD_PTR)handle;
+    mpg123_open_feed(handle);
 
-    /*
-     Fill in frame descriptions for all frames. We use an extra pointer
-     to keep track of our position in the input.
+    /* mpg123 may find a XING header in the mp3 and use that information
+     * to ask for seeks in order to read specific frames in the file.
+     * We cannot allow that since the caller application is feeding us.
+     * This fixes problems for mp3 files encoded with LAME (bug 42361)
      */
-
-    amd->NumberPackets = 25; /* This is the initial array capacity */
-    amd->PacketDescriptions = HeapAlloc(GetProcessHeap(), 0, amd->NumberPackets * sizeof(AudioStreamPacketDescription));
-    if (amd->PacketDescriptions == 0) return MMSYSERR_NOMEM;
-
-    for (aspdi = 0, psrc = src;
-         psrc <= src + *nsrc - 4;
-         psrc += amd->PacketDescriptions[aspdi].mDataByteSize, aspdi++)
-    {
-        /* Return an error if we can't read the frame header */
-        if (Mp3GetPacketLength(psrc) == -1)
-        {
-            *ndst = *nsrc = 0;
-            ERR("Invalid header at %p.\n", psrc);
-            HeapFree(GetProcessHeap(), 0, amd->PacketDescriptions);
-            return MMSYSERR_ERROR;
-        }
-
-        /* If we run out of space, double size and reallocate */
-        if (aspdi >= amd->NumberPackets)
-        {
-            amd->NumberPackets *= 2;
-            amd->PacketDescriptions = HeapReAlloc(GetProcessHeap(), 0, amd->PacketDescriptions, amd->NumberPackets * sizeof(AudioStreamPacketDescription));
-            if (amd->PacketDescriptions == 0) return MMSYSERR_NOMEM;
-        }
-
-        /* Fill in packet data */
-        amd->PacketDescriptions[aspdi].mStartOffset = psrc - src;
-        amd->PacketDescriptions[aspdi].mVariableFramesInPacket = 0;
-        amd->PacketDescriptions[aspdi].mDataByteSize = Mp3GetPacketLength(psrc);
-
-        /* If this brings us past the end, the last one doesn't count */
-        if (psrc + amd->PacketDescriptions[aspdi].mDataByteSize > src + *nsrc) break;
-    }
-
-    /* Fill in correct number of frames */
-    amd->NumberPackets = aspdi;
-
-    /* Adjust nsrc to only include full frames */
-    *nsrc = psrc - src;
-
-    amd->inBuffer.mDataByteSize = *nsrc;
-    amd->inBuffer.mData = src;
-    amd->inBuffer.mNumberChannels = amd->in.mChannelsPerFrame;
-
-    amd->outBuffer.mNumberBuffers = 1;
-    amd->outBuffer.mBuffers[0].mDataByteSize = *ndst;
-    amd->outBuffer.mBuffers[0].mData = dst;
-    amd->outBuffer.mBuffers[0].mNumberChannels = amd->out.mChannelsPerFrame;
-
-    /* Convert the data */
-    size = amd->outBuffer.mBuffers[0].mDataByteSize / amd->out.mBytesPerPacket;
-    err = AudioConverterFillComplexBuffer(amd->acr, Mp3AudioConverterComplexInputDataProc, amd, &size, &amd->outBuffer, 0);
-
-    HeapFree(GetProcessHeap(), 0, amd->PacketDescriptions);
-
-    /* Add skipped bytes back into *nsrc */
-    if (amd->tagBytesLeft > 0)
-    {
-        *nsrc += amd->tagBytesLeft;
-        amd->tagBytesLeft = 0;
-    }
-    *nsrc += syncSkip;
-
-    if (err != noErr && err != -74)
-    {
-        *ndst = *nsrc = 0;
-        ERR("Feed Error: %ld\n", err);
-        return MMSYSERR_ERROR;
-    }
-
-    *ndst = amd->outBuffer.mBuffers[0].mDataByteSize;
-
-    TRACE("convert %d -> %d\n", *nsrc, *ndst);
+    mpg123_param(handle, MPG123_ADD_FLAGS, MPG123_IGNORE_INFOFRAME, 0);
 
     return MMSYSERR_NOERROR;
 }
 
-/***********************************************************************
- *           MPEG3_Reset
- *
- */
-static void MPEG3_Reset(PACMDRVSTREAMINSTANCE adsi, AcmMpeg3Data* aad)
-{
-    AudioConverterReset(aad->acr);
-}
-
-/***********************************************************************
- *           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_MPEGLAYER3 ||
-         adsi->pwfxSrc->wFormatTag == WAVE_FORMAT_MPEG) &&
-        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->tagBytesLeft = -1;
-
-        aad->convert = mp3_leopard_horse;
-
-        err = AudioConverterNew(&aad->in, &aad->out, &aad->acr);
-        if (err != noErr)
-        {
-            ERR("Create failed: %ld\n", err);
-        }
-        else
-        {
-            MPEG3_Reset(adsi, aad);
-
-            return MMSYSERR_NOERROR;
-        }
-    }
-
-    HeapFree(GetProcessHeap(), 0, aad);
-    adsi->dwDriver = 0;
-
-    return MMSYSERR_NOTSUPPORTED;
-}
-
 /***********************************************************************
  *           MPEG3_StreamClose
  *
  */
-static LRESULT MPEG3_StreamClose(PACMDRVSTREAMINSTANCE adsi)
+static LRESULT MPEG3_StreamClose(ACMDRVSTREAMINSTANCE *instance)
 {
-    AcmMpeg3Data* amd = (AcmMpeg3Data*)adsi->dwDriver;
-
-    AudioConverterDispose(amd->acr);
-
-    HeapFree(GetProcessHeap(), 0, amd);
-    adsi->dwDriver = 0;
+    mpg123_handle *handle = (mpg123_handle *)instance->dwDriver;
 
+    mpg123_close(handle);
+    mpg123_delete(handle);
     return MMSYSERR_NOERROR;
 }
 
-#endif
-
 /***********************************************************************
  *           MPEG3_DriverDetails
  *
@@ -939,9 +498,9 @@ static	LRESULT MPEG3_StreamSize(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMSIZE ad
  *           MPEG3_StreamConvert
  *
  */
-static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEADER adsh)
+static LRESULT MPEG3_StreamConvert(ACMDRVSTREAMINSTANCE *instance, ACMDRVSTREAMHEADER *adsh)
 {
-    AcmMpeg3Data*	aad = (AcmMpeg3Data*)adsi->dwDriver;
+    mpg123_handle *handle = (mpg123_handle *)instance->dwDriver;
     DWORD		nsrc = adsh->cbSrcLength;
     DWORD		ndst = adsh->cbDstLength;
 
@@ -959,10 +518,12 @@ static LRESULT MPEG3_StreamConvert(PACMDRVSTREAMINSTANCE adsi, PACMDRVSTREAMHEAD
      */
     if ((adsh->fdwConvert & ACM_STREAMCONVERTF_START))
     {
-        MPEG3_Reset(adsi, aad);
+        mpg123_feedseek(handle, 0, SEEK_SET, NULL);
+        mpg123_close(handle);
+        mpg123_open_feed(handle);
     }
 
-    aad->convert(adsi, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
+    mp3_horse(handle, adsh->pbSrc, &nsrc, adsh->pbDst, &ndst);
     adsh->cbSrcLengthUsed = nsrc;
     adsh->cbDstLengthUsed = ndst;