FLAC library (Java)
This package contains a library for decoding and encoding FLAC files, as well as sample applications. The implementation is in pure Java and is based on my interpretation of the FLAC format specification.
The library is well-documented with many comments, and the code contains numerous assertions to catch invalid data strictly. This library is moderately sophisticated; for beginners learning about the file format, please first read the code in my simple FLAC implementation. The library is much shorter than the official Xiph.Org FLAC implementation in C.
Project source code at GitHub: https://github.com/nayuki/FLAC-library-Java
Decoder
Supported features:
- Handling all valid sample depths from 4 to 32 bits
- Handling all valid sample rates and block sizes
- Handling all valid numbers of channels (from 1 to 8)
- Handling all stereo encoding modes (mid-side, etc.)
- Handling all fixed predictors (orders 0 to 4) and all LPC orders (1 to 32)
- Handling all Rice methods, partitions, and parameters
- Reading the seek table metadata block
- Seeking in a FLAC file based on seek table points
- Seeking based on jumping, resynchronizing, and binary search
- Skipping unrecognized header metadata blocks
- Writing unsigned 8-bit and signed 16/24/32-bit PCM WAV files
- Verification of all checksums – CRC-8 (frame header), CRC-16 (full frame), MD5 hash (full decoded audio)
- Very defensive checks on all method arguments and file data
- Speed optimizations in Rice decoding
- Sample applications: DecodeFlacToWav.java, SeekableFlacPlayerGui.java, ShowFlacFileStats.java
Unsupported features:
- Faster playback skipping without full decoding
- Parsing song tags and giving them to an application
- Skipping data not recognized by the FLAC format (e.g. ID3v1 and ID3v2 tags)
- Resynchronization when corrupt or unrecognized data is encountered
Encoder
Supported features:
- Reading unsigned 8-bit and signed 16/24/32-bit PCM WAV files
- Writing the stream info header metadata block
- Optimal choice among the 4 stereo coding modes
- Optimal choice of Rice coding partitions and parameters
- Optimal block splitting within given parameters (but very time-consuming)
- Decent choice of LPC coefficients through least squares
- Writing frame size statistics to stream info header block after all frames are encoded
- Computing and writing all checksums – CRC-8, CRC-16, MD5 hash
- Sample application: EncodeWavToFlac.java
Unsupported features:
- Writing padding blocks
- Writing seek tables
- Writing song metadata tags
- Fast heuristics for variable block sizing
- Fast heuristics for choosing LPC filter order
- Higher quality selection of LPC coefficients
- Higher quality selection of LPC coefficient precision
- Speed optimization of bit output stream
Notes
This FLAC decoder and encoder library can handle up to 32-bit sample depth for completeness, since it is specified by the FLAC format. Xiph.Org’s FLAC encoder and decoder are currently limited to handling a maximum sample depth of 24 bits. In reality there is no audible benefit beyond 20-bit audio, so anything above 24 bits is certainly overkill.
My FLAC encoder can produce streams with variable block sizes, which decreases the output file size. Experiments were conducted and published on my FLAC benchmarks page. Xiph.Org’s FLAC encoder currently doesn’t generate variable-block streams (except the final block can be shorter than the preceding blocks). Xiph.Org’s FLAC decoder does support variable block sizes, so such streams are definitely usable in practice.