Add optional FLAC compression by braheezy · Pull Request #76 · mewkiz/flac
Hi! I added the ability for the encoder to optionally choose a prediction method for better compression. I'm not sure the API is great but it seems to work and allows this library to produce files smaller than their input, see the Results at the end.
Bonus: The change in frame.go may be inappropriate for this PR but it fixes an out-of-index error I was getting in wav2flac on all files.
How
Added an opt-in prediction analysis pass.
Encodernow has a boolean fieldAnalysisEnabled(helperEnablePredictionAnalysis(true)).- When the flag is off (default) the encoder behaves as before: it writes Constant / Verbatim frames exactly as provided by the caller. This guarantees the round-trip tests that decode an existing FLAC and immediately re-encode it still pass.
- When the flag is on the encoder examines any sub-frame that is still marked
PredVerbatimand chooses the smallest of:- Constant predictor (all samples equal)
- Verbatim (no prediction)
- Fixed prediction. The new
analyseFixed()picks the best order and Rice-k.
libFLAC exposes a range of parameters to tune the encoding process. This PR introduces one knob to try to pick the best prediction method.
Results
Here's what I got when enabling prediction analysis on various audio files:
| File | Original Size | w/out analysis | w/ analysis | Reduction |
|---|---|---|---|---|
| forest_of_illusion.wav | 6.7 MB | 7.9 MB | 4.1 MB | 48% |
| yoshis_island.wav | 4.8 MB | 5.3 MB | 2.6 MB | 51% |
| vanilla_dome.wav | 8.5 MB | 9.8 MB | 5.9 MB | 40% |
There's an expected increase in encoding resources:
| Metric | Before | After | Change |
|---|---|---|---|
| Time | 1547070 ns/op | 6727643 ns/op | 4.35x slower |
| Memory | 1101783 B/op | 3449681 B/op | 3.13x more |
| Allocations | 244 allocs/op | 704 allocs/op | 2.89x more |
The new enc_benchmark_test.go created these results.
Review
I'm open to feedback or questions, or if more tests are needed. I have no personal need for this, just thought it would be fun to try to enhance things a bit.