mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
refactor FLAC decoder
This commit is contained in:
parent
80cc6f07bc
commit
7925d3853c
4 changed files with 121 additions and 121 deletions
|
@ -78,7 +78,6 @@ CAEStreamingDecoder::~CAEStreamingDecoder()
|
||||||
delete reinterpret_cast<CAEDataStreamNew*>(pStream);
|
delete reinterpret_cast<CAEDataStreamNew*>(pStream);
|
||||||
else
|
else
|
||||||
delete reinterpret_cast<CAEDataStreamOld*>(pStream);
|
delete reinterpret_cast<CAEDataStreamOld*>(pStream);
|
||||||
pStream = nullptr;
|
|
||||||
|
|
||||||
if ( --nMallocRefCount == 0 )
|
if ( --nMallocRefCount == 0 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,91 +1,95 @@
|
||||||
#include "StdAfxSA.h"
|
#include "StdAfxSA.h"
|
||||||
#include "FLACDecoderSA.h"
|
#include "FLACDecoderSA.h"
|
||||||
|
#include <algorithm>
|
||||||
extern void* pMalloc;
|
#include <iterator>
|
||||||
extern unsigned int nBlockSize;
|
|
||||||
extern unsigned int nLastMallocSize;
|
|
||||||
|
|
||||||
static unsigned int nSamplesLeftToProcess = 0;
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
UNREFERENCED_PARAMETER(decoder);
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
|
|
||||||
ReadFile(pClientData->GetStream()->GetFile(), buffer, *bytes, reinterpret_cast<LPDWORD>(bytes), nullptr); //*bytes = pClientData->GetStream()->FillBuffer(buffer, *bytes);
|
DWORD size = *bytes;
|
||||||
//*bytes = pClientData->GetStream()->FillBuffer(buffer, *bytes);
|
BOOL result = ReadFile(pClientData->GetStream()->GetFile(), buffer, size, &size, nullptr);
|
||||||
//bEOFFlag = GetLastError() == ERROR_HANDLE_EOF;
|
*bytes = size;
|
||||||
|
|
||||||
auto result = *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
if ( result == FALSE )
|
||||||
|
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
|
||||||
|
|
||||||
return result;
|
if ( size == 0 )
|
||||||
|
{
|
||||||
|
pClientData->m_eof = true;
|
||||||
|
return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||||
|
}
|
||||||
|
pClientData->m_eof = false;
|
||||||
|
return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC__StreamDecoderWriteStatus CAEFLACDecoder::write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
|
FLAC__StreamDecoderWriteStatus CAEFLACDecoder::write_cb(const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame, const FLAC__int32 *const buffer[], void *client_data)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
|
size_t processedChannels;
|
||||||
|
|
||||||
// Obtain current sample
|
// Obtain current sample
|
||||||
pClientData->nCurrentSample = frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ?
|
pClientData->m_currentSample = frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER ? frame->header.number.sample_number : frame->header.number.frame_number;
|
||||||
frame->header.number.sample_number :
|
processedChannels = std::min<size_t>(2, frame->header.channels);
|
||||||
frame->header.number.frame_number * frame->header.blocksize;
|
pClientData->m_curBlockSize = frame->header.blocksize;
|
||||||
|
pClientData->m_bufferCursor = 0;
|
||||||
|
|
||||||
// Mono/stereo?
|
if ( pClientData->m_curBlockSize > pClientData->m_maxBlockSize )
|
||||||
unsigned int nNumChannelsToAlloc = pClientData->pStreamInfo->data.stream_info.channels > 1 ? 2 : 1;
|
|
||||||
|
|
||||||
if ( frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc > nLastMallocSize )
|
|
||||||
{
|
{
|
||||||
// Realloc needed
|
delete pClientData->m_buffer;
|
||||||
if ( pMalloc )
|
pClientData->m_buffer = new FLAC__int32[pClientData->m_curBlockSize * processedChannels];
|
||||||
operator delete(pMalloc);
|
pClientData->m_maxBlockSize = pClientData->m_curBlockSize;
|
||||||
|
}
|
||||||
nLastMallocSize = frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc;
|
|
||||||
pMalloc = operator new(nLastMallocSize); // TODO: More channels?
|
std::copy_n( buffer[0], pClientData->m_curBlockSize, stdext::checked_array_iterator<FLAC__int32*>(pClientData->m_buffer, pClientData->m_curBlockSize) );
|
||||||
|
if ( processedChannels > 1 )
|
||||||
|
{
|
||||||
|
std::copy_n( buffer[1], pClientData->m_curBlockSize, stdext::checked_array_iterator<FLAC__int32*>(pClientData->m_buffer+pClientData->m_curBlockSize, pClientData->m_curBlockSize) );
|
||||||
}
|
}
|
||||||
nBlockSize = frame->header.blocksize;
|
|
||||||
|
|
||||||
memcpy(pMalloc, buffer[0], nBlockSize * sizeof(FLAC__int32));
|
|
||||||
if ( nNumChannelsToAlloc > 1 )
|
|
||||||
memcpy(static_cast<FLAC__int32*>(pMalloc)+nBlockSize, buffer[1], nBlockSize * sizeof(FLAC__int32));
|
|
||||||
|
|
||||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAEFLACDecoder::meta_cb(const FLAC__StreamDecoder* decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
void CAEFLACDecoder::meta_cb(const FLAC__StreamDecoder* decoder, const FLAC__StreamMetadata *metadata, void *client_data)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
if ( metadata->type == FLAC__METADATA_TYPE_STREAMINFO )
|
if ( metadata->type == FLAC__METADATA_TYPE_STREAMINFO )
|
||||||
{
|
{
|
||||||
// Cache the header
|
// Cache the header
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
pClientData->pStreamInfo = FLAC__metadata_object_clone(metadata);
|
pClientData->m_streamMeta = FLAC__metadata_object_clone(metadata);
|
||||||
|
assert( pClientData->m_streamMeta != nullptr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC__StreamDecoderSeekStatus CAEFLACDecoder::seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
|
FLAC__StreamDecoderSeekStatus CAEFLACDecoder::seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
li.QuadPart = absolute_byte_offset;
|
li.QuadPart = absolute_byte_offset;
|
||||||
|
|
||||||
li.LowPart = SetFilePointer(pClientData->GetStream()->GetFile(), li.LowPart, &li.HighPart, FILE_BEGIN);
|
return SetFilePointerEx(pClientData->GetStream()->GetFile(), li, nullptr, FILE_BEGIN) != 0 ? FLAC__STREAM_DECODER_SEEK_STATUS_OK : FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
|
||||||
|
|
||||||
return li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ? FLAC__STREAM_DECODER_SEEK_STATUS_ERROR : FLAC__STREAM_DECODER_SEEK_STATUS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC__StreamDecoderTellStatus CAEFLACDecoder::tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
|
FLAC__StreamDecoderTellStatus CAEFLACDecoder::tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
li.QuadPart = 0;
|
li.QuadPart = 0;
|
||||||
|
|
||||||
li.LowPart = SetFilePointer(pClientData->GetStream()->GetFile(), 0, &li.HighPart, FILE_CURRENT);
|
BOOL result = SetFilePointerEx(pClientData->GetStream()->GetFile(), li, &li, FILE_CURRENT);
|
||||||
*absolute_byte_offset = li.QuadPart;
|
*absolute_byte_offset = li.QuadPart;
|
||||||
|
|
||||||
return li.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR ? FLAC__STREAM_DECODER_TELL_STATUS_ERROR : FLAC__STREAM_DECODER_TELL_STATUS_OK;
|
return result != 0 ? FLAC__STREAM_DECODER_TELL_STATUS_OK : FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
FLAC__StreamDecoderLengthStatus CAEFLACDecoder::length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
|
FLAC__StreamDecoderLengthStatus CAEFLACDecoder::length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data)
|
||||||
{
|
{
|
||||||
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
LARGE_INTEGER li;
|
LARGE_INTEGER li;
|
||||||
|
|
||||||
|
@ -97,10 +101,9 @@ FLAC__StreamDecoderLengthStatus CAEFLACDecoder::length_cb(const FLAC__StreamDeco
|
||||||
|
|
||||||
FLAC__bool CAEFLACDecoder::eof_cb(const FLAC__StreamDecoder* decoder, void* client_data)
|
FLAC__bool CAEFLACDecoder::eof_cb(const FLAC__StreamDecoder* decoder, void* client_data)
|
||||||
{
|
{
|
||||||
// Not implemented
|
|
||||||
UNREFERENCED_PARAMETER(decoder);
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
UNREFERENCED_PARAMETER(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
return false;
|
return pClientData->m_eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAEFLACDecoder::error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDecoderErrorStatus status, void* client_data)
|
void CAEFLACDecoder::error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDecoderErrorStatus status, void* client_data)
|
||||||
|
@ -114,133 +117,126 @@ void CAEFLACDecoder::error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDe
|
||||||
|
|
||||||
bool CAEFLACDecoder::Initialise()
|
bool CAEFLACDecoder::Initialise()
|
||||||
{
|
{
|
||||||
pFLACDecoder = FLAC__stream_decoder_new();
|
m_FLACdecoder = FLAC__stream_decoder_new();
|
||||||
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 )
|
assert( m_FLACdecoder != nullptr );
|
||||||
{
|
if ( m_FLACdecoder == nullptr )
|
||||||
FLAC__stream_decoder_process_until_end_of_metadata(pFLACDecoder);
|
return false;
|
||||||
|
|
||||||
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);
|
if ( FLAC__stream_decoder_init_stream(m_FLACdecoder, read_cb, seek_cb, tell_cb, length_cb, eof_cb, write_cb, meta_cb, error_cb, this) != FLAC__STREAM_DECODER_INIT_STATUS_OK )
|
||||||
}
|
return false;
|
||||||
return false;
|
|
||||||
|
if ( FLAC__stream_decoder_process_until_end_of_metadata(m_FLACdecoder) == false )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if ( m_streamMeta == nullptr )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
m_eof = false;
|
||||||
|
return m_streamMeta->data.stream_info.sample_rate <= 48000 && (m_streamMeta->data.stream_info.bits_per_sample == 8 || m_streamMeta->data.stream_info.bits_per_sample == 16 || m_streamMeta->data.stream_info.bits_per_sample == 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t CAEFLACDecoder::FillBuffer(void* pBuf, uint32_t nLen)
|
uint32_t CAEFLACDecoder::FillBuffer(void* pBuf, uint32_t nLen)
|
||||||
{
|
{
|
||||||
unsigned int nBytesDecoded = 0;
|
uint32_t samplesToDecode = nLen / (2 * sizeof(int16_t));
|
||||||
FLAC__int16* pBuffer = static_cast<FLAC__int16*>(pBuf);
|
uint32_t bytesDecoded = 0;
|
||||||
|
int16_t* outputBuffer = static_cast<int16_t*>(pBuf);
|
||||||
|
FLAC__int32* inputBuffer[] = { m_buffer+m_bufferCursor, m_buffer+m_bufferCursor+m_curBlockSize };
|
||||||
|
|
||||||
const unsigned int nSampleRate = pStreamInfo->data.stream_info.bits_per_sample;
|
const uint32_t sampleWidth = m_streamMeta->data.stream_info.bits_per_sample;
|
||||||
const bool bStereo = pStreamInfo->data.stream_info.channels > 1;
|
const bool stereo = m_streamMeta->data.stream_info.channels > 1;
|
||||||
|
|
||||||
while ( nBytesDecoded < nLen )
|
while ( bytesDecoded < nLen )
|
||||||
{
|
{
|
||||||
unsigned int nToWrite;
|
if ( m_bufferCursor >= m_curBlockSize )
|
||||||
// No samples left from a previous fetch?
|
|
||||||
if ( !nSamplesLeftToProcess )
|
|
||||||
{
|
{
|
||||||
FLAC__stream_decoder_process_single(pFLACDecoder);
|
// New FLAC frame needed
|
||||||
|
if ( FLAC__stream_decoder_get_state(m_FLACdecoder) == FLAC__STREAM_DECODER_END_OF_STREAM )
|
||||||
|
break;
|
||||||
|
|
||||||
if ( (nLen - nBytesDecoded) / 4 >= nBlockSize )
|
FLAC__stream_decoder_process_single(m_FLACdecoder);
|
||||||
nToWrite = nBlockSize;
|
inputBuffer[0] = m_buffer;
|
||||||
else
|
inputBuffer[1] = m_buffer+m_curBlockSize;
|
||||||
nToWrite = (nLen - nBytesDecoded) / 4;
|
|
||||||
|
|
||||||
nSamplesLeftToProcess = nBlockSize;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
nToWrite = nSamplesLeftToProcess;
|
|
||||||
|
|
||||||
FLAC__int32* pCurrentPtr[2] = { static_cast<FLAC__int32*>(pMalloc), static_cast<FLAC__int32*>(pMalloc)+nBlockSize };
|
size_t samplesThisIteration = std::min( m_curBlockSize-m_bufferCursor, samplesToDecode );
|
||||||
const unsigned int ExtraIndex = nBlockSize - nSamplesLeftToProcess;
|
if ( sampleWidth == 8 )
|
||||||
|
|
||||||
// Write channels
|
|
||||||
if ( nSampleRate == 8 )
|
|
||||||
{
|
{
|
||||||
// 8-bit
|
if ( stereo )
|
||||||
if ( bStereo )
|
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
for ( size_t i = 0; i < samplesThisIteration; ++i )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pCurrentPtr[0][ExtraIndex+i] << 8;
|
outputBuffer[0] = int16_t(*inputBuffer[0]++ << 8);
|
||||||
pBuffer[1] = pCurrentPtr[1][ExtraIndex+i] << 8;
|
outputBuffer[1] = int16_t(*inputBuffer[1]++ << 8);
|
||||||
|
outputBuffer += 2;
|
||||||
pBuffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
for ( size_t i = 0; i < samplesThisIteration; ++i )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pBuffer[1] = pCurrentPtr[0][ExtraIndex+i] << 8;
|
outputBuffer[0] = outputBuffer[1] = int16_t(*inputBuffer[0]++ << 8);
|
||||||
|
outputBuffer += 2;
|
||||||
pBuffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( nSampleRate == 24 )
|
else if ( sampleWidth == 24 )
|
||||||
{
|
{
|
||||||
// 24-bit
|
// 24-bit
|
||||||
if ( bStereo )
|
if ( stereo )
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
for ( size_t i = 0; i < samplesThisIteration; ++i )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pCurrentPtr[0][ExtraIndex+i] >> 8;
|
outputBuffer[0] = int16_t(*inputBuffer[0]++ >> 8);
|
||||||
pBuffer[1] = pCurrentPtr[1][ExtraIndex+i] >> 8;
|
outputBuffer[1] = int16_t(*inputBuffer[1]++ >> 8);
|
||||||
|
outputBuffer += 2;
|
||||||
pBuffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
for ( size_t i = 0; i < samplesThisIteration; ++i )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pBuffer[1] = pCurrentPtr[0][ExtraIndex+i] >> 8;
|
outputBuffer[0] = outputBuffer[1] = int16_t(*inputBuffer[0]++ >> 8);
|
||||||
|
outputBuffer += 2;
|
||||||
pBuffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 16-bit
|
if ( stereo )
|
||||||
if ( bStereo )
|
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
for ( size_t i = 0; i < samplesThisIteration; ++i )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pCurrentPtr[0][ExtraIndex+i];
|
outputBuffer[0] = int16_t(*inputBuffer[0]++);
|
||||||
pBuffer[1] = pCurrentPtr[1][ExtraIndex+i];
|
outputBuffer[1] = int16_t(*inputBuffer[1]++);
|
||||||
|
outputBuffer += 2;
|
||||||
pBuffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
for ( size_t i = 0; i < samplesThisIteration; ++i )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pBuffer[1] = pCurrentPtr[0][ExtraIndex+i];
|
outputBuffer[0] = outputBuffer[1] = int16_t(*inputBuffer[0]++);
|
||||||
|
outputBuffer += 2;
|
||||||
pBuffer += 2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nBytesDecoded += nToWrite*4;
|
m_bufferCursor += samplesThisIteration;
|
||||||
|
samplesToDecode -= samplesThisIteration;
|
||||||
if ( FLAC__stream_decoder_get_state(pFLACDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM )
|
bytesDecoded += samplesThisIteration * 2 * sizeof(int16_t);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return nBytesDecoded;
|
return bytesDecoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAEFLACDecoder::~CAEFLACDecoder()
|
CAEFLACDecoder::~CAEFLACDecoder()
|
||||||
{
|
{
|
||||||
nSamplesLeftToProcess = 0;
|
if ( m_FLACdecoder != nullptr )
|
||||||
if ( pFLACDecoder )
|
|
||||||
{
|
{
|
||||||
FLAC__stream_decoder_finish(pFLACDecoder);
|
FLAC__stream_decoder_finish(m_FLACdecoder);
|
||||||
FLAC__stream_decoder_delete(pFLACDecoder);
|
FLAC__stream_decoder_delete(m_FLACdecoder);
|
||||||
|
|
||||||
FLAC__metadata_object_delete(pStreamInfo);
|
if ( m_streamMeta != nullptr )
|
||||||
pFLACDecoder = nullptr;
|
FLAC__metadata_object_delete(m_streamMeta);
|
||||||
}
|
}
|
||||||
|
delete m_buffer;
|
||||||
}
|
}
|
|
@ -5,9 +5,13 @@
|
||||||
class CAEFLACDecoder : public CAEStreamingDecoder
|
class CAEFLACDecoder : public CAEStreamingDecoder
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
FLAC__StreamDecoder* pFLACDecoder;
|
FLAC__StreamDecoder* m_FLACdecoder;
|
||||||
FLAC__StreamMetadata* pStreamInfo;
|
FLAC__StreamMetadata* m_streamMeta;
|
||||||
unsigned int nCurrentSample;
|
FLAC__uint64 m_currentSample;
|
||||||
|
FLAC__int32* m_buffer;
|
||||||
|
size_t m_curBlockSize, m_maxBlockSize;
|
||||||
|
size_t m_bufferCursor;
|
||||||
|
bool m_eof;
|
||||||
|
|
||||||
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);
|
||||||
|
@ -21,20 +25,21 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAEFLACDecoder(CAEDataStream* stream)
|
CAEFLACDecoder(CAEDataStream* stream)
|
||||||
: CAEStreamingDecoder(stream), pFLACDecoder(nullptr)
|
: CAEStreamingDecoder(stream), m_FLACdecoder(nullptr), m_streamMeta(nullptr)
|
||||||
|
, m_buffer(nullptr), m_curBlockSize(0), m_maxBlockSize(0), m_bufferCursor(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~CAEFLACDecoder();
|
virtual ~CAEFLACDecoder();
|
||||||
virtual bool Initialise() override;
|
virtual bool Initialise() override;
|
||||||
virtual uint32_t FillBuffer(void* pBuf, uint32_t nLen) override;
|
virtual uint32_t FillBuffer(void* pBuf, uint32_t nLen) override;
|
||||||
virtual uint32_t GetStreamLengthMs() override
|
virtual uint32_t GetStreamLengthMs() override
|
||||||
{ return pStreamInfo->data.stream_info.total_samples * 1000 / pStreamInfo->data.stream_info.sample_rate; }
|
{ return uint32_t((m_streamMeta->data.stream_info.total_samples * 1000) / m_streamMeta->data.stream_info.sample_rate); }
|
||||||
virtual uint32_t GetStreamPlayTimeMs() override
|
virtual uint32_t GetStreamPlayTimeMs() override
|
||||||
{ return nCurrentSample * 1000 / pStreamInfo->data.stream_info.sample_rate; }
|
{ return uint32_t((m_currentSample * 1000) / m_streamMeta->data.stream_info.sample_rate); }
|
||||||
virtual void SetCursor(uint32_t nTime) override
|
virtual void SetCursor(uint32_t nTime) override
|
||||||
{ FLAC__stream_decoder_seek_absolute(pFLACDecoder, nTime * pStreamInfo->data.stream_info.sample_rate / 1000); }
|
{ FLAC__stream_decoder_seek_absolute(m_FLACdecoder, (uint64_t(nTime) * m_streamMeta->data.stream_info.sample_rate) / 1000); }
|
||||||
virtual uint32_t GetSampleRate() override
|
virtual uint32_t GetSampleRate() override
|
||||||
{ return pStreamInfo->data.stream_info.sample_rate; }
|
{ return m_streamMeta->data.stream_info.sample_rate; }
|
||||||
virtual uint32_t GetStreamID() override
|
virtual uint32_t GetStreamID() override
|
||||||
{ return GetStream()->GetID(); }
|
{ return GetStream()->GetID(); }
|
||||||
};
|
};
|
|
@ -86,7 +86,7 @@ copy /y "$(TargetPath)" "D:\gry\GTA San Andreas clean\scripts\newsteam_r2_lowvio
|
||||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<PreprocessorDefinitions>_GTA_SA;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_GTA_SA;NDEBUG;_SECURE_SCL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<AdditionalIncludeDirectories>D:\RWSDK\Graphics\rwsdk\include\d3d9;..\SilentPatch;$(DXSDK_DIR)\include</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>D:\RWSDK\Graphics\rwsdk\include\d3d9;..\SilentPatch;$(DXSDK_DIR)\include</AdditionalIncludeDirectories>
|
||||||
|
|
Loading…
Reference in a new issue