Replace the FLAC encoder library with an own implementation#194
Open
douglas-carmichael wants to merge 1 commit into
Open
Replace the FLAC encoder library with an own implementation#194douglas-carmichael wants to merge 1 commit into
douglas-carmichael wants to merge 1 commit into
Conversation
The bundled encoder crashed on samples whose length modulo 4096 is 2, 3 or 4 with a non-constant tail (e.g. 'The FLAC encoder failed for sample ...' when writing Renoise files; SFZ with the FLAC option, Bliss and Synclavier Regen failed hard since they have no WAV fallback). The new encoder in file/flac supports constant, verbatim, fixed and LPC sub-frames, Rice partitioning and stereo de-correlation and compresses on par with the old library. The library remains in use for reading FLAC files.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The bundled FLAC encoder library crashes with an
ArrayIndexOutOfBoundsException(inSubframe_Fixed.encodeSamples) on any sample whose length modulo 4096 is 2, 3 or 4 and whose trailing samples are not all identical: the fixed-predictor order selection reads 4 samples ahead without checking the length of the final short block. A real-world example is a 65538-frame drum sample (16 × 4096 + 2).Affected writers:
Solution
A new encoder
file/flac/FlacEncoderwritten from the FLAC specification (RFC 9639), in the same spirit as the existing NCW/SF2/RIFF/FastLZ implementations. It supports constant, verbatim, fixed prediction (order 0-4) and linear prediction (LPC, order up to 8) sub-frames, Rice coding with per-partition parameters and per-frame stereo de-correlation (left/side, side/right, mid/side), each chosen by the smallest encoded size. Compression is on par with the old library (within ~2% on a real drum library); losslessness is guaranteed by construction since the residuals are calculated with the exact integer arithmetic of the decoder. Short trailing blocks - the case the old library crashed on - are handled correctly for all lengths.The library remains in use for reading FLAC files. Two quirks of its jFLAC based reader are deliberately catered for so ConvertWithMoss can re-read its own output: a PADDING block always terminates the meta-data (the reader fails if STREAMINFO is the only block) and blocks shorter than 16 samples are stored verbatim (the reader mis-decodes predicted sub-frames there).
AudioFileUtils.compressToFLACnow returns the bytes directly, which also removes the temporary-file workarounds in the Renoise, Bliss and Synclavier Regen creators.Verification
flac -t(flac 1.5.0, including its MD5 check of the decoded audio), decodes byte-identical with the reference decoder and round-trips through the application's own FLAC reader.