From 97f61bb40c33640ab2de045ae540d641cd228620 Mon Sep 17 00:00:00 2001 From: "m.podoprelov" Date: Mon, 13 Nov 2023 20:01:38 +0300 Subject: [PATCH] Add check and normalization for more than 16 bits per sample FLAC-files --- src/flactomp3.cpp | 22 +++++++++++++++++----- src/flactomp3.h | 3 ++- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/flactomp3.cpp b/src/flactomp3.cpp index 2f7d67c..bb9b27b 100644 --- a/src/flactomp3.cpp +++ b/src/flactomp3.cpp @@ -294,16 +294,28 @@ bool FLACtoMP3::scaleJPEG(const FLAC__StreamMetadata_Picture& picture) { return true; } -bool FLACtoMP3::decodeFrame(const int32_t * const buffer[], uint32_t size) { +bool FLACtoMP3::decodeFrame(const int32_t * const buffer[], uint32_t size, const uint32_t bitsPerSample) { if (!outputInitilized) { bool success = initializeOutput(); if (!success) return false; } + if (bitsPerSample >= 16) + return decodeFrameImpl(buffer, size, 1 << (bitsPerSample - 16)); + + return false; +} + +bool FLACtoMP3::decodeFrameImpl(const int32_t * const buffer[], uint32_t size, const uint32_t divisor) +{ for (size_t i = 0; i < size; ++i) { - pcm[pcmCounter++] = (int16_t)buffer[0][i]; - pcm[pcmCounter++] = (int16_t)buffer[1][i]; + int32_t left = buffer[0][i]; + int32_t right = buffer[1][i]; + left /= divisor; + right /= divisor; + pcm[pcmCounter++] = (int16_t)left; + pcm[pcmCounter++] = (int16_t)right; if (pcmCounter == pcmSize) return flush(); @@ -394,8 +406,8 @@ FLAC__StreamDecoderWriteStatus FLACtoMP3::write( self->logger.fatal("ERROR: buffer [1] is NULL"); return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; } - - bool result = self->decodeFrame(buffer, frame->header.blocksize); + + bool result = self->decodeFrame(buffer, frame->header.blocksize, frame->header.bits_per_sample); if (result) return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; diff --git a/src/flactomp3.h b/src/flactomp3.h index 0bf1a8a..d246b5a 100644 --- a/src/flactomp3.h +++ b/src/flactomp3.h @@ -29,7 +29,8 @@ private: void processTags(const FLAC__StreamMetadata_VorbisComment& tags); void processInfo(const FLAC__StreamMetadata_StreamInfo& info); void processPicture(const FLAC__StreamMetadata_Picture& picture); - bool decodeFrame(const int32_t * const buffer[], uint32_t size); + bool decodeFrame(const int32_t * const buffer[], uint32_t size, const uint32_t bitsPerSample); + bool decodeFrameImpl(const int32_t * const buffer[], uint32_t size, const uint32_t divisor); bool flush(); bool initializeOutput(); bool scaleJPEG(const FLAC__StreamMetadata_Picture& picture);