CLI reference

Every flag, its default, and whether it moves a number.

crête needs no flags to measure correctly — the defaults are the validated path, and the figures on this site are all produced without one. The flags exist for the cases where the default is not what you want: a different mix on the disc, a different area of the SACD, or a deliberate A/B against a value someone recorded under an older algorithm. This page is the complete surface of crete 0.23.0, grouped by what each flag actually changes.

18
flags in total
0
needed for a correct run
5
axes recorded in every JSON row
3
marked A/B-only in the help text

01 — What a flag can do

Three kinds of flag, and only one of them is dangerous

Conflating these is how an unreproducible measurement gets recorded. A flag that changes the presentation is free. A flag that changes which stream is decoded produces a perfectly valid number about a different piece of audio. A flag that changes the algorithm produces a different number about the same audio — and that one has to travel with the number, or the number is worthless.

crête’s answer is that the third kind is written into every JSON result it emits. The table below carries the same distinction in its last column.

moves numbers Changes the reported figures. Recorded in JSON.
selects input Changes which audio is measured, not how.
no effect on values Presentation, destination or speed only.

02 — Measurement axes

The only five flags that change a DR figure on a PCM source. All five are written into every JSON result, because a measurement you cannot attribute to an algorithm is not a measurement. Four of them exist for A/B comparison and should not produce a number you then publish.

FlagValuesDefaultWhat it does
--dr-blocksreference | legacy | foobarreferenceWhich 3 s blocks are ranked. reference is the PMF reference implementation — the trailing partial block is kept and normalised by its own length, and there is no gate. legacy is what crête shipped up to 0.13.1: trailing block discarded, blocks gated at joint_rms > 1e-3. It biases DR low. foobar, added in 0.20.0, is the reference rules on a grid whose first full block starts 244 ms in, as measured on foobar2000 DR Meter 1.0.8; experimental, until a full weekly decides it. A/B only. moves numbers
--dr-meanquadratic | arithmeticquadraticHow the loudest 20 % of blocks are averaged. quadratic averages power — the PMF procedure, and what MAAT and foobar2000 both do. arithmetic averages amplitude, which is what crête shipped up to 0.12.1; it biases DR high. Applies to every format, not just DSD. A/B only. moves numbers
--dr-lfeexclude | includeexcludeWhether the LFE is scored. Affects TT DR only — the DR mean, the joint sample and true peaks behind it, the block gate and worst_channel. Integrated loudness, Max M/S, LRA and Min PSR never move, because BS.1770-4 weights the LFE at zero. A no-op on mono and stereo, so no stereo measurement can change. include matches foobar2000’s DR Meter. moves numbers
--dr-shortexclude | includeexcludeTracks under 10 s. exclude gives such a track no DR — DR-- in text, null in JSON with dr_defined: false — and leaves it out of the album DR, which is MAAT DROffline’s own limit, measured at exactly 10.000 s. Every other metric on the track is still reported. include reproduces ≤ 0.19.5, where a clip could score a raw DR of −100 and drag an album from DR10 to DR4. Added in 0.20.0. A/B only. moves numbers
--channel-maskuse | ignoreuseWhether the speaker mask a file declares — dwChannelMask in an extensible WAV, RF64 or Wave64, the channel-mask tag in FLAC, FFmpeg’s native layout — decides the labels, the LFE and the loudness weights when it describes a layout the channel count does not. An Auro-3D 8.0 file is otherwise read as 7.1, with a surround taken for an LFE and left out. A mask that agrees with the count, and every mono and stereo file, takes the old path unchanged. ignore reproduces ≤ 0.20.0. Added in 0.21.0. A/B only. moves numbers

The LFE rule, with both sides measured

crête’s DR for a 5.1 or 7.1 file is the mean of the scored channels — everything but the LFE. A .1 track is a band-limited effects channel whose crest factor is nearly flat and whose level is mix-dependent, so averaging it in measures the mixer’s bass management rather than the music. TT DR defines nothing past stereo, so this is a chosen rule, and crête says which rule produced which number rather than presenting one as the multichannel DR. foobar2000 chooses the other way; the flag exists so the two can be compared directly.

DSOTM 5.1 96 kHz — the same file, both scoring rules
SettingDR rawScoredLowest
--dr-lfe exclude default11.97725Ls
--dr-lfe include foobar200011.86066LFE

03 — DSD decode

DSD has no PCM samples to measure, so a decimation chain has to be chosen before there is anything to meter — and the choice moves the number. The defaults are the parity-guaranteed path; the others are offered for analysis. None of them touch a PCM format.

FlagValuesDefaultWhat it does
--dsd-modedirect | multistagemultistagemultistage is the measurement-grade chain, brickwalled at Nyquist, valid for DSD64 through DSD512 at every output rate. direct is a single wide FIR with a gentle ~30 kHz corner and is DSD64 → 44 100 only, a libdsddpcm restriction rather than a crête one. moves numbers
--dsd-out-rate44100 | 88200 | 176400 | 3528004410044 100 is the rate every DSD parity claim on this site is made at. Above 48 kHz the decimation cascade alone keeps the modulator’s shaped ultrasonic noise, which inflates RMS, peak and DR — a property of the format, not a defect in the decode. Since 0.22.0 --dsd-bandwidth removes most of it at 176 400 and 352 800 by default, but a 50 kHz band still holds content the 44.1 kHz decode does not, so the higher rates are for analysis, not for parity. moves numbers
--dsd-bandwidthdefault | full | HzdefaultThe band limit on the decoded PCM. default appends a linear-phase low-pass with a 50 kHz corner — the Scarlet Book Annex D.1 measurement band, flat to the corner, at least 153 dB down from 1.4 times it, unity DC. full turns it off and reproduces ≤ 0.21.0; a number is a corner in Hz, at least 20 000. It acts only where the corner sits below the output Nyquist: with the default that is 176 400 and 352 800, while 44 100 already brickwalls and 88 200 is bit-identical to 0.21.0. JSON records dsd_bandwidth and whether it ran, dsd_bandwidth_applied. Added in 0.22.0. moves numbers
--dsd-filterdefault | firls | kaiserdefaultThe ranked final stage. Honoured only at --dsd-out-rate 44100, and silently ignored otherwise, since no other rate reaches that stage. default is equiripple at 383 taps; firls is a least-squares cross-check at 767; kaiser is the 4 095-tap maximum decode. moves numbers

The support matrix, the tap counts and the reasoning behind each chain are on the Formats page. crete --version prints the resolved chain, decimation, tap count and group delay for DSD64 through DSD512 at whatever settings you pass it, which is the fastest way to see what a combination actually does before committing a run to it.

04 — Choosing what gets measured

Neither of these changes how crête measures. Both change which audio arrives at the meter — and on a disc source that difference is far larger than any algorithmic axis above, because the alternatives are different mixes rather than different renderings of one mix.

FlagValuesDefaultWhat it does
--sacd-areaauto | stereo | multichannelautoWhich area of an SACD .iso to read. auto prefers the 2-channel area deliberately: it is the layer crête’s DR references are built on, the layer comparable with every other release of an album, and usually the uncompressed one. A bad value fails on the main thread before any decoding starts. selects input
--streamNFFmpeg’s own pickThe audio stream to decode in a multi-stream container, indexed as ffprobe -show_streams prints it. With no --stream, FFmpeg ranks by bitrate and channel count — a reasonable default, but not the container’s default flag and not stable across remuxes of the same content. Whenever a file holds more than one audio stream crête says which one it measured, and records stream_index and audio_stream_count in JSON. On a DVD the index is taken over the whole title set, since it is not stable from one .vob fragment to the next; the compact FFmpeg also lists one phantom stream per .vob, which automatic selection passes over because it ranks by bitrate and the phantom has none. selects input

A music Blu-ray commonly ships the same album several times over

One DSOTM remux carries six audio streams — LPCM 5.1 96 kHz, DTS-HD MA 5.1, TrueHD 7.1 Atmos, an AC-3 core, and stereo LPCM and DTS-HD MA. These are different mixes with different DR, not different encodings of one mix, so crête refuses to pick one silently:

Warning: album.mkv has 6 audio streams; measured stream 2 (PCM_S24LE, 6 ch, 96000 Hz). Use --stream N to choose.

FFmpeg’s unaided pick is not stable across remuxes of the same content: on the file above it selects the 13.8 Mbps LPCM track, while on a 60-second copy of the same six streams it selects the TrueHD one. Single-stream files are unaffected — no warning, and no extra JSON keys.

05 — Output

Presentation and destination. Nothing here can change a figure — the same analysis is formatted five ways.

FlagValuesDefaultWhat it does
-f, --formatstd | foobar | ext | detail | jsonstdmaat is accepted as a synonym for ext. json needs a build that has it — make cli-json or make cli-json-ffmpeg — and a zero-dependency binary refuses the flag with that hint rather than falling back to text. no effect on values
-o, --outputfilestdoutRedirects stdout only. Progress, per-file decode errors and the multi-stream warning are written to stderr and still reach the terminal, which is what makes -o safe to point at a JSON file. no effect on values
-q, --quiet—progress shownSuppresses the progress line. Errors and warnings are not suppressed — a quiet run still tells you what it could not read. no effect on values

06 — Run control

Wall-clock time and information. Verified never to change a number.

FlagValuesDefaultWhat it does
-j, --jobsNfitted to memory and coresPins the worker count. Results are order-preserving and bit-identical to a sequential run, so -j buys time and nothing else; -j 1 forces strictly sequential. An explicit N is obeyed exactly — crête warns if it does not expect N to fit in memory and proceeds, because silently overriding the flag would make a run unreproducible. Workers are per unit of work, and the pool is the lower of N and the number of units — see below. no effect on values
--memory-limitSIZE | N%detectedThe memory crête may plan for when it sizes the worker pool — a size such as 8G or 512M, or a share of this machine’s RAM such as 40%. The detected default is the host’s free memory, honouring a container / cgroup limit where one is in force rather than the physical machine underneath. Added in 0.19.0; affects scheduling only, and the JSON tracks array is byte-identical across limits. no effect on values
-v, --version——Prints the build’s tiers, the DSD engine and licence, the five DR axes as resolved, the full decimation chain — taps and group delay — for DSD64 through 512 at the current settings, and since 0.19.0 a Host: line with the CPUs and memory the machine reported. A version string alone would not say which algorithm produced a number. no effect on values
-h, --help——The flag list, plus the native formats, the SACD rule and the cue rule as that binary implements them. no effect on values

What -j parallelises, and what it cannot

A worker takes one unit of work, and a unit is a plain file, a cue album, or an SACD area — not a track. So a folder of twelve FLACs uses twelve workers’ worth of parallelism, while a cue-sliced monolith or a disc image is a single unit and runs on one thread however high -j goes. The pool is capped at the number of units present, so asking for more never costs anything.

Why the default is not one per core

crête loads a file before decoding it, and each in-flight file holds its full decoded float64 buffer. A monolithic 60-minute DSD64 album is about 2.6 GB at the default output rate and eight times that at 352.8 kHz. Up to 0.18.1 the default was one worker per core, so a 16 GB box measuring DSD512 asked for 22 GB and was killed by the OS — with empty stderr, which reads as a crash. Since 0.19.0 the default pool is fitted to free memory as well as cores, estimated per item from its header, and says so when memory decides:

Note: using 3 of 12 cores -- each worker needs about 3.7 GB
and 12 GB is available. Override with --jobs or --memory-limit.

It is a memory control, not a correctness one: the JSON tracks array is byte-identical across --jobs and --memory-limit settings, and -j is verified bit-identical to a sequential run on FLAC, DSD and cue albums. The Linux and Windows detection paths have not yet been run.

07 — Output formats

Five renderings of one analysis

Chosen with -f. The analysis is identical in all five — these differ in what they print, not in what they measured.

-f std Standard
The default. Compatible with the dr.loudness-war.info submission format: DR, peak, RMS and filename per track, then the file count and the official album DR.
-f foobar foobar2000 style
The DR Meter layout, with duration and a per-album technical info block.
-f ext Extended
MAAT DROffline MkII–style pipe-delimited table, 26 columns: per-channel sample and true peaks, RMS, max momentary and short-term LUFS, LUFSi, DR (PMF), DR LEFT, DR RIGHT, PLR, LRA, Min PSR and more. This is the parity-testing format.
-f detail Detail
Per-track, per-channel vertical table — the readable one for a single-track investigation. Each joint value carries its governing-standard tag, (ITU) / (EBU) / (AES) / (PMF), with a legend in the footer; per-channel momentary and short-term columns are marked informative (non-ITU) variants.
-f json JSON
Every metric for every track, the full channel_metrics array, the standards map, the always-present warnings array, and the axes the result was produced under. Needs a cli-json build. This is what the pytest harness reads — it never scrapes text.

08 — Reproducibility

A JSON row is readable without knowing how it was produced

Every axis that can move a figure is written into the result alongside the figure. This is the whole reason the flags are safe to have: an A/B run cannot be mistaken later for a default one, because the record says which it was.

Which releases moved a number →
KeyPresentWhat it pins
dr_blocksevery resultThe 3 s block set.
dr_rms_meanevery resultThe top-20 % averaging mode.
dr_lfe · scored_channelsevery resultThe LFE scoring rule, and how many channels it left scored.
dr_short · dr_definedevery result · every trackThe short-track rule, and whether this track has a DR under it.
channel_mask_mode · channel_maskevery result · masked layoutsWhether a declared speaker mask was honoured, and the mask itself wherever it, not the channel count, described the layout.
standardstop levelWhich specification governs each reported field.
warningsevery resultFailed decodes, CRC mismatches, truncation and the multi-stream choice. Always present, so an empty array is the positive statement that nothing was wrong.
dsd_mode · dsd_filter · dsd_out_rate · dsd_bandwidth · dsd_bandwidth_appliedDSD sourcesThe full decode configuration, and whether the band limit actually ran at that output rate. An unlabelled DSD result is not interpretable.
stream_index · audio_stream_countmulti-stream containersWhich of the mixes on the disc these numbers describe.

09 — Exit status

A meter that measured nothing has not succeeded

Three codes, and the new one is the one worth wiring into a script. Since 0.17.0 0 means every input decoded cleanly rather than “something came back”, so a run that silently averaged a damaged track into an album value can no longer exit the same way a clean one does.

exit 0 Every input decoded cleanly.
Not “something was measured”. Since 0.17.0 a clean exit is a statement about the whole run, which is what makes it worth testing — a partial success no longer hides inside it.
exit 1 Nothing could be analysed, or a flag was rejected.
A meter that measured nothing has not succeeded — and with -f json it emits no JSON at all, so a caller trusting the exit code would parse an empty string. That is exactly how a stale FFmpeg build with no TrueHD or DTS decoder surfaced in CI: as a JSONDecodeError instead of crête’s own error line.
exit 2 Completed, but some input failed to decode or was damaged.
The run produced numbers and they are unreliable — including any album value computed from them, because a damaged track is averaged into it. Added in 0.17.0, alongside the warnings array: crête still measures a damaged file, because it is a meter and not a repair tool, but it will not let the result pass for a clean one. num_tracks counts what was measured, so a file that failed to decode contributes a warning and no track. Since 0.18.0 a DVD-Audio title set whose audio format changes partway through exits 2 as well: crête measures the first group and says so rather than metering through the change. Since 0.19.1 so does a cue track whose range is empty: it is dropped with a named warning, because an album missing a track is not a complete measurement.

10 — Recipes

The invocations worth knowing

A normal run

# defaults: reference, quadratic, LFE excluded
crete /path/to/album/

# per-channel, with the standard tags
crete -f detail track.flac

# CI shape: results to the file, errors to stderr
crete -q -f json -o album.json /path/to/album/

# on a shared machine: plan for a share of it
crete --memory-limit 40% /path/to/album/

Disc sources

# SACD: auto prefers the 2-channel area
crete album.iso

# the 5.1 area, DST or not
crete --sacd-area multichannel album.iso

# pin the mix; ffprobe indices
crete-ffmpeg --stream 2 album.mkv

DSD

# multistage → 44.1 kHz, the parity path
crete /path/to/dsd/

# analysis rate; workers fitted to memory
crete --dsd-out-rate 352800 /path/to/dsd/

# taps and group delay for every chain
crete --version

Comparing against another meter

# match foobar2000’s multichannel rule
crete --dr-lfe include /path/to/5.1/

# reproduce a pre-0.14.0 recorded value
crete --dr-blocks legacy /path/to/album/

# reproduce a pre-0.20.0 album with short clips
crete --dr-short include /path/to/album/

# reproduce a pre-0.21.0 masked layout
crete --channel-mask ignore /path/to/auro/

# reproduce a pre-0.22.0 high-rate DSD value
crete --dsd-out-rate 352800 --dsd-bandwidth full /path/to/dsd/

# reproduce a pre-0.12.1 recorded value
crete --dr-mean arithmetic /path/to/album/

The default is the point

No flag on this page is needed to measure an album correctly.

The defaults are the reference block set, quadratic averaging, the LFE excluded, the multistage DSD chain at 44.1 kHz and the 2-channel SACD area — every one of them the path the weekly parity run gates. The rest of this page is for deliberately leaving it.

What the defaults are gated against →
crête 0.23.0 Flags, defaults and accepted spellings taken from the argument parser in the Crete repository, not from documentation. Run crete --help on your own build for that binary's tiers. codeberg.org/abksh/Crete