flacoutcpp
flacoutcpp is a modern C++17 recreation of the original flacout utility. It focuses on providing extreme lossless FLAC recompression by using advanced dynamic programming techniques to find the absolute optimal block partitioning and LPC coefficients for the FLAC stream.
While the original tool was a closed-source Windows binary, this project reverse-engineered its core compression logic and ported it to a clean, multi-threaded C++ implementation that can run on any modern platform (including macOS ARM64 and Linux). It significantly outperforms the original in speed by leveraging std::thread to evaluate block configurations concurrently and includes early-exit heuristics to speed up exhaustive LPC searches without any loss in compression ratio.
By default, flacoutcpp acts as a drop-in FLAC optimizer, flawlessly cloning all original IDv3 tags, Vorbis Comments, cover arts, and other metadata into the recompressed output.
Building from source
The project uses CMake for its build system and includes libflac as a submodule. A C++17 compliant compiler is required.
To build the project:
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake --build . --config Release
Usage
Usage: flacoutcpp [options] [output.flac]
Options:
-e, --exhaustive Exact search: fully encode every block-size and
stereo-mode choice instead of estimating them,
and offer all windows (extremely slow).
Worth far more than any -E level: 0.6% (24-bit)
to 2.3% (16-bit) on real music, against ~0.2%
across the whole dial. Rarely worth it bare:
'-e -L 1' is ~5x faster for 99.5% of the gain,
and '-e -E 0' ~80x faster for ~76% of it.
-c, --candidates N Fully evaluate only the N most promising
(window, order) pairs per subframe, ranked by
Levinson-Durbin prediction error. 0 = no limit.
Default: 24 (effort level 3), or 0 when -e is
given without -c/-L/-E. Composes with -e
(e.g. -e -c 8). Larger N is slower and
compresses better.
-p, --patience N Keep scanning past -c N while candidates are
still improving; stop after N consecutive that
are not. Makes -c a floor, not a ceiling.
Default: 2x -c. 0 disables it (plain top-N cut).
-E, --effort N Effort 0-12: one dial along the measured
size/time frontier, setting -c, -L, -a and
— from level 10 — exact DP, together (they
are not independent; which mix is efficient
shifts with the budget). 0 fastest, 9 = every
candidate and every rung under estimated DP,
10-12 = exact DP at increasing depth. Level 3
is the default. Against it, on a 188-track
mix: 0 is +0.15% at 0.8x the time, 6 is
-0.03% at 1.5x, 9 is -0.05% at 5.7x, 10 is
-0.52% at 7.7x, 12 is -0.61% at 24x. Level 10
is the value corner — ten times level 9's
compression for 20% more time — because exact
pricing is worth far more than search depth.
An explicit -c/-p/-L/-a wins; the level's -a
yields to -e/-w rather than erroring.
-L, --rungs N Encode only the N most promising of the 8 LPC
coefficient precisions per candidate, chosen by
an analytic model of the quantization error
instead of by encoding all of them.
Default: 1 (effort level 3); 0 under a bare
-e, which prices the whole ladder. Against
all 8 rungs: 1 costs 0.019% for 1.31x, 2
costs 0.009% for 1.25x, 3 costs 0.005%.
-c and -L are not independent —
prefer -E, which pairs them along the measured
frontier, unless you know which pair you want.
-Q, --lattice N Refine the winning subframe's quantized LPC
coefficients by coordinate descent: try each
tap at +-1, keep what lowers the exact cost,
up to N sweeps (0 = off, the default).
Experimental. Never grows a subframe.
-b, --blocks Comma-separated block sizes the DP may choose
from (default: 1024,2048,4096,8192,16384).
Each must be a multiple of 16 in [16, 65520],
and every size must be a multiple of the
smallest, or the DP cannot reach the stream's
end. FLAC's own limits are 16 and 65535, but
65535 is odd, so no usable grid reaches it;
65520 is the largest attainable size, and
needs a smallest size that divides it (e.g.
16 or 5040, not 1024). Cost scales with
sum(sizes)/gcd(sizes): the default is 31 block
-samples of work per input sample, and
16,...,32768 is 4095 — about 130x. Best paired
with -e, which prices every choice exactly.
-n, --no-metadata Do not copy metadata from input to output
-a, --adaptive-windows Add windows chosen from each block's signal
statistics to the shortlist. On by default;
estimated-DP only, so it yields silently to
-e/-w and is an error only when named there.
-A, --no-adaptive-windows Turn that off.
-R, --no-reuse Disable input-frame reuse. By default, input
frames that beat the re-encoded ones are spliced
into the output (and the input is copied through
if the output would still be larger), so
re-encoding never grows a file. -R measures the
raw search alone — mainly for testing
-W, --warn-superior Warn on stderr when the input's own frames beat
the re-encode (i.e. frame reuse fired), naming
the input's encoder when its metadata says.
Prints even with -q; incompatible with -R
-q, --quiet Suppress all progress output
-t, --threads N Limit parallel worker threads (default: all CPUs)
-w, --windows Comma-separated list of apodization windows to use
(default: all 26 with a bare -e, else
tukey005,tukey020,
tukey050,hann,welch,rect and the partial/punchout
tukey pair at .33/.67)
An entry of the form custom: loads a window
shape from a knot file (up to 4 per run); see
bench/windows/example_taper.txt for the format
Available window names:
rect, bartlett, bartletthann, blackman, blackmanharris, connes, flattop,
gauss025, gauss0125, hamming, hann, kaiserbessel, nuttall, triangle, welch,
tukey005, tukey010, tukey020, tukey050, tukey075, tukey090,
partialtukey2, partialtukey2_033, partialtukey2_067,
punchouttukey2_033, punchouttukey2_067
Experimental windows (never in a default set; explicit -w only):
lanczos, bohman, parzen, plancktaper010, plancktaper025,
partialtukey3_{1,2,3}, punchouttukey3_{1,2,3},
partialtukey3h_{000,033,067}, punchouttukey3h_{025,050},
punchouttukey2_000,
expdecay{2,4}, expattack{2,4}, attackdecay{005,010,020},
dpss{2,3,4}