Replace libflac with dr_flac

This commit is contained in:
VintNarni 2025-01-12 16:41:33 +01:00
parent 2a597da1bc
commit e77bb48757
5 changed files with 12587 additions and 179 deletions

12558
SilentPatch/dr_flac.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,138 +1,22 @@
#include "StdAfxSA.h"
#define DR_FLAC_IMPLEMENTATION
#include "FLACDecoderSA.h"
#include <algorithm>
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);
DWORD size = *bytes;
BOOL result = ReadFile(pClientData->GetStream()->GetFile(), buffer, size, &size, nullptr);
*bytes = size;
if ( result == FALSE )
return FLAC__STREAM_DECODER_READ_STATUS_ABORT;
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)
{
UNREFERENCED_PARAMETER(decoder);
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
size_t processedChannels;
// Obtain current sample
assert( frame->header.number_type == FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER );
pClientData->m_currentSample = frame->header.number.sample_number;
processedChannels = std::min<size_t>(2, frame->header.channels);
pClientData->m_curBlockSize = frame->header.blocksize;
pClientData->m_bufferCursor = 0;
if ( pClientData->m_curBlockSize > pClientData->m_maxBlockSize )
{
delete[] pClientData->m_buffer;
pClientData->m_buffer = new FLAC__int32[pClientData->m_curBlockSize * processedChannels];
pClientData->m_maxBlockSize = pClientData->m_curBlockSize;
}
auto it = std::copy_n( buffer[0], pClientData->m_curBlockSize, pClientData->m_buffer );
if ( processedChannels > 1 )
{
std::copy_n( buffer[1], pClientData->m_curBlockSize, it );
}
return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
}
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 )
{
// Cache the header
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
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)
{
UNREFERENCED_PARAMETER(decoder);
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
LARGE_INTEGER li;
li.QuadPart = absolute_byte_offset;
return SetFilePointerEx(pClientData->GetStream()->GetFile(), li, nullptr, FILE_BEGIN) != 0 ? FLAC__STREAM_DECODER_SEEK_STATUS_OK : FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
}
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);
LARGE_INTEGER li;
li.QuadPart = 0;
BOOL result = SetFilePointerEx(pClientData->GetStream()->GetFile(), li, &li, FILE_CURRENT);
*absolute_byte_offset = li.QuadPart;
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)
{
UNREFERENCED_PARAMETER(decoder);
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
LARGE_INTEGER li;
BOOL bResult = GetFileSizeEx(pClientData->GetStream()->GetFile(), &li);
*stream_length = li.QuadPart;
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)
{
UNREFERENCED_PARAMETER(decoder);
CAEFLACDecoder* pClientData = static_cast<CAEFLACDecoder*>(client_data);
return pClientData->m_eof;
}
void CAEFLACDecoder::error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDecoderErrorStatus status, void* client_data)
{
// Not implemented
UNREFERENCED_PARAMETER(decoder);
UNREFERENCED_PARAMETER(status);
UNREFERENCED_PARAMETER(client_data);
}
bool CAEFLACDecoder::Initialise()
{
m_FLACdecoder = FLAC__stream_decoder_new();
assert( m_FLACdecoder != nullptr );
DWORD size;
BOOL result = ReadFile(GetStream()->GetFile(), m_buffer, sizeof(m_buffer), &size, nullptr);
if ( result == FALSE || size == 0 )
return false;
m_FLACdecoder = drflac_open_memory(m_buffer, size, nullptr);
assert(m_FLACdecoder != nullptr);
if ( m_FLACdecoder == nullptr )
return false;
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;
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);
return m_FLACdecoder->sampleRate <= 48000 && (m_FLACdecoder->bitsPerSample == 8 || m_FLACdecoder->bitsPerSample == 16 || m_FLACdecoder->bitsPerSample == 24);
}
uint32_t CAEFLACDecoder::FillBuffer(void* pBuf, uint32_t nLen)
@ -140,20 +24,20 @@ uint32_t CAEFLACDecoder::FillBuffer(void* pBuf, uint32_t nLen)
uint32_t samplesToDecode = nLen / (2 * sizeof(int16_t));
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 };
drflac_int32* inputBuffer[] = { m_buffer+m_bufferCursor, m_buffer+m_bufferCursor+m_curBlockSize };
const uint32_t sampleWidth = m_streamMeta->data.stream_info.bits_per_sample;
const bool stereo = m_streamMeta->data.stream_info.channels > 1;
const uint32_t sampleWidth = m_FLACdecoder->bitsPerSample;
const bool stereo = m_FLACdecoder->channels > 1;
while ( bytesDecoded < nLen )
{
if ( m_bufferCursor >= m_curBlockSize )
{
// New FLAC frame needed
if ( FLAC__stream_decoder_get_state(m_FLACdecoder) == FLAC__STREAM_DECODER_END_OF_STREAM )
if ( m_FLACdecoder->memoryStream.currentReadPos == m_FLACdecoder->memoryStream.dataSize )
break;
FLAC__stream_decoder_process_single(m_FLACdecoder);
drflac_seek_to_pcm_frame(m_FLACdecoder, (drflac_int64)inputBuffer);
inputBuffer[0] = m_buffer;
inputBuffer[1] = m_buffer+m_curBlockSize;
}
@ -231,13 +115,6 @@ uint32_t CAEFLACDecoder::FillBuffer(void* pBuf, uint32_t nLen)
CAEFLACDecoder::~CAEFLACDecoder()
{
if ( m_FLACdecoder != nullptr )
{
FLAC__stream_decoder_finish(m_FLACdecoder);
FLAC__stream_decoder_delete(m_FLACdecoder);
if ( m_streamMeta != nullptr )
FLAC__metadata_object_delete(m_streamMeta);
}
if ( m_FLACdecoder != nullptr ) drflac_close(m_FLACdecoder);
delete[] m_buffer;
}

View file

@ -2,30 +2,19 @@
#include "AudioHardwareSA.h"
// libflac
#include "FLAC\stream_decoder.h"
#include "FLAC\metadata.h"
#define DR_FLAC_NO_STDIO
#define DR_FLAC_NO_OGG
#include "dr_flac.h"
class CAEFLACDecoder final : public CAEStreamingDecoder
{
private:
FLAC__StreamDecoder* m_FLACdecoder = nullptr;
FLAC__StreamMetadata* m_streamMeta = nullptr;
FLAC__uint64 m_currentSample;
FLAC__int32* m_buffer = nullptr;
size_t m_curBlockSize, m_maxBlockSize = 0;
size_t m_bufferCursor;
bool m_eof;
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);
static void meta_cb(const FLAC__StreamDecoder* decoder, const FLAC__StreamMetadata *metadata, void *client_data);
static void error_cb(const FLAC__StreamDecoder* decoder, FLAC__StreamDecoderErrorStatus status, void* client_data);
static FLAC__StreamDecoderSeekStatus seek_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data);
static FLAC__StreamDecoderTellStatus tell_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
static FLAC__StreamDecoderLengthStatus length_cb(const FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data);
static FLAC__bool eof_cb(const FLAC__StreamDecoder *decoder, void *client_data);
drflac* m_FLACdecoder = nullptr;
drflac_uint64 m_currentSample;
drflac_int32* m_buffer = nullptr;
size_t m_curBlockSize, m_maxBlockSize = 0;
size_t m_bufferCursor;
bool m_eof;
public:
CAEFLACDecoder(CAEDataStream* stream)
@ -36,13 +25,13 @@ public:
virtual bool Initialise() override;
virtual uint32_t FillBuffer(void* pBuf, uint32_t nLen) override;
virtual uint32_t GetStreamLengthMs() const override
{ return uint32_t((m_streamMeta->data.stream_info.total_samples * 1000) / m_streamMeta->data.stream_info.sample_rate); }
{ return uint32_t((m_FLACdecoder->totalPCMFrameCount * 1000) / m_FLACdecoder->sampleRate); }
virtual uint32_t GetStreamPlayTimeMs() const override
{ return uint32_t((m_currentSample * 1000) / m_streamMeta->data.stream_info.sample_rate); }
{ return uint32_t((m_currentSample * 1000) / m_FLACdecoder->sampleRate); }
virtual void SetCursor(uint32_t nTime) override
{ FLAC__stream_decoder_seek_absolute(m_FLACdecoder, (uint64_t(nTime) * m_streamMeta->data.stream_info.sample_rate) / 1000); }
{ drflac_seek_to_pcm_frame(m_FLACdecoder, (uint64_t(nTime) * m_FLACdecoder->sampleRate) / 1000); }
virtual uint32_t GetSampleRate() const override
{ return m_streamMeta->data.stream_info.sample_rate; }
{ return m_FLACdecoder->sampleRate; }
virtual uint32_t GetStreamID() const override
{ return GetStream()->GetID(); }
};

View file

@ -70,18 +70,6 @@
<TargetExt>.asi</TargetExt>
<TargetName>SilentPatchSA</TargetName>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>true</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Shipping|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgUseStatic>true</VcpkgUseStatic>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>

View file

@ -1,4 +0,0 @@
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"dependencies": ["libflac"]
}