From b7f7f89dce96c53f143ef044a34a50541912133d Mon Sep 17 00:00:00 2001 From: Silent Date: Wed, 11 Jun 2014 02:58:25 +0200 Subject: [PATCH] Improved memory management Support for 8-bit and 24-bit FLACs --- SilentPatch/AudioHardware.cpp | 63 +++++++++++++++++++++++++++-------- SilentPatch/AudioHardware.h | 6 +++- SilentPatch/dllmain.cpp | 12 +++---- 3 files changed, 60 insertions(+), 21 deletions(-) diff --git a/SilentPatch/AudioHardware.cpp b/SilentPatch/AudioHardware.cpp index b29c99e..c16cd6a 100644 --- a/SilentPatch/AudioHardware.cpp +++ b/SilentPatch/AudioHardware.cpp @@ -8,6 +8,8 @@ //WRAPPER unsigned int CAEDataStream::FillBuffer(void* pBuf, unsigned long nLen) { EAXJMP(0x4DC1C0); } WRAPPER bool CAEDataStream::Initialise() { EAXJMP(0x4DC2B0); } +unsigned int CAEFLACDecoder::nRefCount = 0; + //static bool bEOFFlag = false; FLAC__StreamDecoderReadStatus CAEFLACDecoder::read_cb(const FLAC__StreamDecoder* decoder, FLAC__byte buffer[], size_t* bytes, void* client_data) @@ -39,13 +41,14 @@ FLAC__StreamDecoderWriteStatus CAEFLACDecoder::write_cb(const FLAC__StreamDecode frame->header.number.frame_number * frame->header.blocksize; // Mono/stereo? - unsigned int nNumChannelsToAlloc = pClientData->pStreamInfo->data.stream_info.channels > 1 ? 2 : 1; - static unsigned int nLastMallocSize = 0; + unsigned int nNumChannelsToAlloc = pClientData->pStreamInfo->data.stream_info.channels > 1 ? 2 : 1; + static unsigned int nLastMallocSize; - if ( frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc > nLastMallocSize ) + if ( !pMalloc || frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc > nLastMallocSize ) { // Realloc needed - operator delete(pMalloc); + if ( pMalloc ) + operator delete(pMalloc); nLastMallocSize = frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc; pMalloc = static_cast(operator new(nLastMallocSize)); // TODO: More channels? @@ -123,11 +126,13 @@ void CAEFLACDecoder::error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDe bool CAEFLACDecoder::Initialise() { pFLACDecoder = FLAC__stream_decoder_new(); - auto result = FLAC__stream_decoder_init_stream(pFLACDecoder, read_cb, seek_cb, tell_cb, length_cb, eof_cb, write_cb, meta_cb, error_cb, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK; - - FLAC__stream_decoder_process_until_end_of_metadata(pFLACDecoder); + if ( FLAC__stream_decoder_init_stream(pFLACDecoder, read_cb, seek_cb, tell_cb, length_cb, eof_cb, write_cb, meta_cb, error_cb, this) == FLAC__STREAM_DECODER_INIT_STATUS_OK ) + { + FLAC__stream_decoder_process_until_end_of_metadata(pFLACDecoder); - return result; + return pStreamInfo->data.stream_info.sample_rate <= 48000 && (pStreamInfo->data.stream_info.bits_per_sample == 8 || pStreamInfo->data.stream_info.bits_per_sample == 16 || pStreamInfo->data.stream_info.bits_per_sample == 24); + } + return false; } unsigned int CAEFLACDecoder::FillBuffer(void* pBuf, unsigned long nLen) @@ -160,14 +165,38 @@ unsigned int CAEFLACDecoder::FillBuffer(void* pBuf, unsigned long nLen) nToWrite = nSamplesLeftToProcess; // Write channels - // = min((nLen - nBytesDecoded) / 4, nBlockSize); - - for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- ) + if ( pStreamInfo->data.stream_info.bits_per_sample == 8 ) { - pBuffer[0] = pCurrentPtr[0][i]; - pBuffer[1] = pCurrentPtr[pStreamInfo->data.stream_info.channels > 1][i]; + // 8-bit + for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- ) + { + pBuffer[0] = pCurrentPtr[0][i] << 8; + pBuffer[1] = pCurrentPtr[pStreamInfo->data.stream_info.channels > 1][i] << 8; - pBuffer += 2; + pBuffer += 2; + } + } + else if ( pStreamInfo->data.stream_info.bits_per_sample == 24 ) + { + // 24-bit + for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- ) + { + pBuffer[0] = pCurrentPtr[0][i] >> 8; + pBuffer[1] = pCurrentPtr[pStreamInfo->data.stream_info.channels > 1][i] >> 8; + + pBuffer += 2; + } + } + else + { + // 16-bit + for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- ) + { + pBuffer[0] = pCurrentPtr[0][i]; + pBuffer[1] = pCurrentPtr[pStreamInfo->data.stream_info.channels > 1][i]; + + pBuffer += 2; + } } //nSigLen -= nToWrite; @@ -190,4 +219,10 @@ CAEFLACDecoder::~CAEFLACDecoder() FLAC__metadata_object_delete(pStreamInfo); pFLACDecoder = nullptr; } + + if ( --nRefCount == 0 ) + { + operator delete(pMalloc); + pMalloc = nullptr; + } } \ No newline at end of file diff --git a/SilentPatch/AudioHardware.h b/SilentPatch/AudioHardware.h index a58f8b8..1f0c158 100644 --- a/SilentPatch/AudioHardware.h +++ b/SilentPatch/AudioHardware.h @@ -129,6 +129,8 @@ private: FLAC__StreamMetadata* pStreamInfo; unsigned int nCurrentSample; + static unsigned int nRefCount; + private: static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder* decoder, FLAC__byte buffer[], size_t* bytes, void* client_data); static FLAC__StreamDecoderWriteStatus write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data); @@ -142,7 +144,9 @@ private: public: CAEFLACDecoder(CAEDataStream* stream) : CAEStreamingDecoder(stream), pFLACDecoder(nullptr) - {} + { + ++nRefCount; + } virtual ~CAEFLACDecoder(); diff --git a/SilentPatch/dllmain.cpp b/SilentPatch/dllmain.cpp index 891e7c0..b0df266 100644 --- a/SilentPatch/dllmain.cpp +++ b/SilentPatch/dllmain.cpp @@ -1812,13 +1812,13 @@ LoadFLAC_Success: jnz LoadFLAC_Return_NoDelete LoadFLAC_Return: - push esi - //mov ecx, esi - call StreamDtor - //call CAEDataStream::~CAEDataStream //push esi - //call free // TODO: operator delete - //add esp, 4 + mov ecx, esi + //call StreamDtor + call CAEDataStream::~CAEDataStream + push esi + call GTAdelete + add esp, 4 LoadFLAC_Return_NoDelete: mov eax, [esp+20h+4]