mirror of
https://github.com/CookiePLMonster/SilentPatch.git
synced 2024-12-29 15:23:02 +05:00
Fixes for FLAC support
This commit is contained in:
parent
ed410fcea2
commit
d71e048691
2 changed files with 65 additions and 35 deletions
|
@ -8,21 +8,27 @@
|
||||||
//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); }
|
||||||
|
|
||||||
|
//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)
|
||||||
{
|
{
|
||||||
|
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);
|
ReadFile(pClientData->GetStream()->GetFile(), buffer, *bytes, reinterpret_cast<LPDWORD>(bytes), nullptr); //*bytes = pClientData->GetStream()->FillBuffer(buffer, *bytes);
|
||||||
//*bytes = pClientData->GetStream()->FillBuffer(buffer, *bytes);
|
//*bytes = pClientData->GetStream()->FillBuffer(buffer, *bytes);
|
||||||
|
//bEOFFlag = GetLastError() == ERROR_HANDLE_EOF;
|
||||||
|
|
||||||
FLAC__StreamDecoderReadStatus bResult = *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
auto result = *bytes ? FLAC__STREAM_DECODER_READ_STATUS_CONTINUE : FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
|
||||||
|
|
||||||
return bResult;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FLAC__int32* pMalloc = nullptr;
|
static FLAC__int32* pMalloc = nullptr;
|
||||||
static unsigned int nBlockSize = 0;
|
static unsigned int nBlockSize = 0;
|
||||||
|
|
||||||
|
static unsigned int nSamplesLeftToProcess = 0;
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
|
||||||
|
@ -32,16 +38,22 @@ FLAC__StreamDecoderWriteStatus CAEFLACDecoder::write_cb(const FLAC__StreamDecode
|
||||||
frame->header.number.sample_number :
|
frame->header.number.sample_number :
|
||||||
frame->header.number.frame_number * frame->header.blocksize;
|
frame->header.number.frame_number * frame->header.blocksize;
|
||||||
|
|
||||||
if ( frame->header.blocksize > nBlockSize )
|
// Mono/stereo?
|
||||||
|
unsigned int nNumChannelsToAlloc = pClientData->pStreamInfo->data.stream_info.channels > 1 ? 2 : 1;
|
||||||
|
static unsigned int nLastMallocSize = 0;
|
||||||
|
|
||||||
|
if ( frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc > nLastMallocSize )
|
||||||
{
|
{
|
||||||
// Realloc needed
|
// Realloc needed
|
||||||
operator delete(pMalloc);
|
operator delete(pMalloc);
|
||||||
|
|
||||||
pMalloc = static_cast<FLAC__int32*>(operator new(frame->header.blocksize * sizeof(FLAC__int32) * 2)); // TODO: More channels?
|
nLastMallocSize = frame->header.blocksize * sizeof(FLAC__int32) * nNumChannelsToAlloc;
|
||||||
|
pMalloc = static_cast<FLAC__int32*>(operator new(nLastMallocSize)); // TODO: More channels?
|
||||||
}
|
}
|
||||||
nBlockSize = frame->header.blocksize;
|
nBlockSize = frame->header.blocksize;
|
||||||
|
|
||||||
memcpy(pMalloc, buffer[0], nBlockSize * sizeof(FLAC__int32));
|
memcpy(pMalloc, buffer[0], nBlockSize * sizeof(FLAC__int32));
|
||||||
|
if ( nNumChannelsToAlloc > 1 )
|
||||||
memcpy(pMalloc+nBlockSize, buffer[1], nBlockSize * sizeof(FLAC__int32));
|
memcpy(pMalloc+nBlockSize, buffer[1], nBlockSize * sizeof(FLAC__int32));
|
||||||
|
|
||||||
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
|
||||||
|
@ -91,10 +103,11 @@ FLAC__StreamDecoderLengthStatus CAEFLACDecoder::length_cb(const FLAC__StreamDeco
|
||||||
return bResult ? FLAC__STREAM_DECODER_LENGTH_STATUS_OK: FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
|
return bResult ? FLAC__STREAM_DECODER_LENGTH_STATUS_OK: FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
||||||
// TODO: DO
|
UNREFERENCED_PARAMETER(decoder);
|
||||||
|
UNREFERENCED_PARAMETER(client_data);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,38 +130,64 @@ bool CAEFLACDecoder::Initialise()
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
unsigned int CAEFLACDecoder::FillBuffer(void* pBuf, unsigned long nLen)
|
unsigned int CAEFLACDecoder::FillBuffer(void* pBuf, unsigned long nLen)
|
||||||
{
|
{
|
||||||
signed int nSigLen = nLen / 4;
|
//unsigned int nSigLen = nLen / 4;
|
||||||
unsigned int nBytesDecoded = 0;
|
unsigned int nBytesDecoded = 0;
|
||||||
FLAC__int16* pBuffer = static_cast<FLAC__int16*>(pBuf);
|
FLAC__int16* pBuffer = static_cast<FLAC__int16*>(pBuf);
|
||||||
|
|
||||||
while ( nSigLen > 0 )
|
while ( nBytesDecoded < nLen )
|
||||||
|
{
|
||||||
|
static FLAC__int32* pCurrentPtr[2];
|
||||||
|
|
||||||
|
unsigned int nToWrite;
|
||||||
|
// No samples left from a previous fetch?
|
||||||
|
if ( !nSamplesLeftToProcess )
|
||||||
{
|
{
|
||||||
FLAC__stream_decoder_process_single(pFLACDecoder);
|
FLAC__stream_decoder_process_single(pFLACDecoder);
|
||||||
|
|
||||||
FLAC__int32* pCurrentPtr[2];
|
|
||||||
|
|
||||||
pCurrentPtr[0] = pMalloc;
|
pCurrentPtr[0] = pMalloc;
|
||||||
pCurrentPtr[1] = pMalloc+nBlockSize;
|
pCurrentPtr[1] = pMalloc+nBlockSize;
|
||||||
|
|
||||||
|
if ( (nLen - nBytesDecoded) / 4 >= nBlockSize )
|
||||||
|
nToWrite = nBlockSize;
|
||||||
|
else
|
||||||
|
nToWrite = (nLen - nBytesDecoded) / 4;
|
||||||
|
|
||||||
|
nSamplesLeftToProcess = nBlockSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nToWrite = nSamplesLeftToProcess;
|
||||||
|
|
||||||
// Write channels
|
// Write channels
|
||||||
unsigned int nToWrite = min(nLen / 4, nBlockSize);
|
// = min((nLen - nBytesDecoded) / 4, nBlockSize);
|
||||||
for ( unsigned int i = 0; i < nToWrite; i++ )
|
|
||||||
|
for ( unsigned int i = 0; i < nToWrite; i++, nSamplesLeftToProcess-- )
|
||||||
{
|
{
|
||||||
pBuffer[0] = pCurrentPtr[0][i];
|
pBuffer[0] = pCurrentPtr[0][i];
|
||||||
pBuffer[1] = pCurrentPtr[1][i];
|
pBuffer[1] = pCurrentPtr[pStreamInfo->data.stream_info.channels > 1][i];
|
||||||
|
|
||||||
pBuffer += 2;
|
pBuffer += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
nSigLen -= nToWrite;
|
//nSigLen -= nToWrite;
|
||||||
nBytesDecoded += nToWrite*4;
|
nBytesDecoded += nToWrite*4;
|
||||||
|
|
||||||
if ( FLAC__stream_decoder_get_state(pFLACDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM )
|
if ( FLAC__stream_decoder_get_state(pFLACDecoder) == FLAC__STREAM_DECODER_END_OF_STREAM )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return nSigLen > 0 ? nLen - nBytesDecoded : nLen;
|
return nBytesDecoded;//nSigLen > 0 ? nLen - nBytesDecoded : nLen;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAEFLACDecoder::~CAEFLACDecoder()
|
||||||
|
{
|
||||||
|
nSamplesLeftToProcess = 0;
|
||||||
|
if ( pFLACDecoder )
|
||||||
|
{
|
||||||
|
FLAC__stream_decoder_finish(pFLACDecoder);
|
||||||
|
FLAC__stream_decoder_delete(pFLACDecoder);
|
||||||
|
|
||||||
|
FLAC__metadata_object_delete(pStreamInfo);
|
||||||
|
pFLACDecoder = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -144,18 +144,7 @@ public:
|
||||||
: CAEStreamingDecoder(stream), pFLACDecoder(nullptr)
|
: CAEStreamingDecoder(stream), pFLACDecoder(nullptr)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual ~CAEFLACDecoder()
|
virtual ~CAEFLACDecoder();
|
||||||
{
|
|
||||||
if ( pFLACDecoder )
|
|
||||||
{
|
|
||||||
FLAC__stream_decoder_finish(pFLACDecoder);
|
|
||||||
FLAC__stream_decoder_delete(pFLACDecoder);
|
|
||||||
|
|
||||||
FLAC__metadata_object_delete(pStreamInfo);
|
|
||||||
pFLACDecoder = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
virtual bool Initialise() override;
|
virtual bool Initialise() override;
|
||||||
|
|
||||||
|
@ -163,12 +152,14 @@ public:
|
||||||
|
|
||||||
virtual unsigned int GetStreamLengthMs() override
|
virtual unsigned int GetStreamLengthMs() override
|
||||||
{
|
{
|
||||||
return pStreamInfo->data.stream_info.total_samples * 1000 / pStreamInfo->data.stream_info.sample_rate;
|
unsigned int nTime = pStreamInfo->data.stream_info.total_samples * 1000 / pStreamInfo->data.stream_info.sample_rate;
|
||||||
|
return nTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual unsigned int GetStreamPlayTimeMs() override
|
virtual unsigned int GetStreamPlayTimeMs() override
|
||||||
{
|
{
|
||||||
return nCurrentSample * 1000 / pStreamInfo->data.stream_info.sample_rate;
|
unsigned int nTime = nCurrentSample * 1000 / pStreamInfo->data.stream_info.sample_rate;
|
||||||
|
return nTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void SetCursor(unsigned int nTime) override
|
virtual void SetCursor(unsigned int nTime) override
|
||||||
|
|
Loading…
Reference in a new issue