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);