Improved memory management

Support for 8-bit and 24-bit FLACs
This commit is contained in:
Silent 2014-06-11 02:58:25 +02:00
parent d71e048691
commit b7f7f89dce
3 changed files with 60 additions and 21 deletions

View file

@ -8,6 +8,8 @@
//WRAPPER unsigned int CAEDataStream::FillBuffer(void* pBuf, unsigned long nLen) { EAXJMP(0x4DC1C0); } //WRAPPER unsigned int CAEDataStream::FillBuffer(void* pBuf, unsigned long nLen) { EAXJMP(0x4DC1C0); }
WRAPPER bool CAEDataStream::Initialise() { EAXJMP(0x4DC2B0); } WRAPPER bool CAEDataStream::Initialise() { EAXJMP(0x4DC2B0); }
unsigned int CAEFLACDecoder::nRefCount = 0;
//static bool bEOFFlag = false; //static bool bEOFFlag = false;
FLAC__StreamDecoderReadStatus CAEFLACDecoder::read_cb(const FLAC__StreamDecoder* decoder, FLAC__byte buffer[], size_t* bytes, void* client_data) 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; frame->header.number.frame_number * frame->header.blocksize;
// Mono/stereo? // Mono/stereo?
unsigned int nNumChannelsToAlloc = pClientData->pStreamInfo->data.stream_info.channels > 1 ? 2 : 1; unsigned int nNumChannelsToAlloc = pClientData->pStreamInfo->data.stream_info.channels > 1 ? 2 : 1;
static unsigned int nLastMallocSize = 0; 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 // Realloc needed
operator delete(pMalloc); if ( pMalloc )
operator delete(pMalloc);
nLastMallocSize = frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc; nLastMallocSize = frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc;
pMalloc = static_cast<FLAC__int32*>(operator new(nLastMallocSize)); // TODO: More channels? pMalloc = static_cast<FLAC__int32*>(operator new(nLastMallocSize)); // TODO: More channels?
@ -123,11 +126,13 @@ void CAEFLACDecoder::error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDe
bool CAEFLACDecoder::Initialise() bool CAEFLACDecoder::Initialise()
{ {
pFLACDecoder = FLAC__stream_decoder_new(); 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; 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); 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) unsigned int CAEFLACDecoder::FillBuffer(void* pBuf, unsigned long nLen)
@ -160,14 +165,38 @@ unsigned int CAEFLACDecoder::FillBuffer(void* pBuf, unsigned long nLen)
nToWrite = nSamplesLeftToProcess; nToWrite = nSamplesLeftToProcess;
// Write channels // Write channels
// = min((nLen - nBytesDecoded) / 4, nBlockSize); if ( pStreamInfo->data.stream_info.bits_per_sample == 8 )
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
{ {
pBuffer[0] = pCurrentPtr[0][i]; // 8-bit
pBuffer[1] = pCurrentPtr[pStreamInfo->data.stream_info.channels > 1][i]; 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; //nSigLen -= nToWrite;
@ -190,4 +219,10 @@ CAEFLACDecoder::~CAEFLACDecoder()
FLAC__metadata_object_delete(pStreamInfo); FLAC__metadata_object_delete(pStreamInfo);
pFLACDecoder = nullptr; pFLACDecoder = nullptr;
} }
if ( --nRefCount == 0 )
{
operator delete(pMalloc);
pMalloc = nullptr;
}
} }

View file

@ -129,6 +129,8 @@ private:
FLAC__StreamMetadata* pStreamInfo; FLAC__StreamMetadata* pStreamInfo;
unsigned int nCurrentSample; unsigned int nCurrentSample;
static unsigned int nRefCount;
private: private:
static FLAC__StreamDecoderReadStatus read_cb(const FLAC__StreamDecoder* decoder, FLAC__byte buffer[], size_t* bytes, void* client_data); 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); 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: public:
CAEFLACDecoder(CAEDataStream* stream) CAEFLACDecoder(CAEDataStream* stream)
: CAEStreamingDecoder(stream), pFLACDecoder(nullptr) : CAEStreamingDecoder(stream), pFLACDecoder(nullptr)
{} {
++nRefCount;
}
virtual ~CAEFLACDecoder(); virtual ~CAEFLACDecoder();

View file

@ -1812,13 +1812,13 @@ LoadFLAC_Success:
jnz LoadFLAC_Return_NoDelete jnz LoadFLAC_Return_NoDelete
LoadFLAC_Return: LoadFLAC_Return:
push esi
//mov ecx, esi
call StreamDtor
//call CAEDataStream::~CAEDataStream
//push esi //push esi
//call free // TODO: operator delete mov ecx, esi
//add esp, 4 //call StreamDtor
call CAEDataStream::~CAEDataStream
push esi
call GTAdelete
add esp, 4
LoadFLAC_Return_NoDelete: LoadFLAC_Return_NoDelete:
mov eax, [esp+20h+4] mov eax, [esp+20h+4]