Repository navigation
0.7.0 (2026-10-15)
Features
- analysis: measure and cache each track's loudness (392d7dc)
- analysis: measure each file's loudness and cache it (8dbcaf8)
- analysis: run loudness-only jobs below every analysis (7a03837)
- app: measure the loudness of tracks analysed before (f65dbf6)
- backends: report the frames a stream holds before the device plays them (b459bc8)
- control: ignore a MIDI fader bound to a locked player (a50a00b)
- decode: refuse encoded bitstreams stored as PCM (a6903be)
- dsp: add fp-dsp with a gated integrated loudness meter (05bb677)
- dsp: measure the gated integrated loudness of a programme (12e100a)
- engine: follow the rate under a hard start on a bit-perfect bus (1563566)
- engine: give each mixer slot a fixed gain (4dafd85)
- engine: play each source at its loudness normalization gain (551464d)
- engine: play each source at its normalization gain (3671658)
- engine: prepare the next track at the rate of a planned cut (7ce125a)
- engine: reopen a bit-perfect device between two tracks (366b377)
- engine: reopen bit-perfect devices at each track's rate (9417adb)
- engine: report each bus's stream rate and refused rates (9ba5121)
- model: add limits.max_log_file_mb and limits.max_log_files (1c9a379)
- model: add the loudness normalization settings (3561e7b)
- model: decide each source's loudness normalization gain (c802f39)
- model: decide the normalization gain of a track (272edd4)
- model: exclude a track from normalization or trim it (104c532)
- model: hold a bit-perfect player's fader at 100 % (90e133a)
- model: keep each device's stream rate (1dce66c)
- model: keep each source's gain while it sounds (3101716)
- model: keep each track's loudness measurement (e0ced2e)
- model: list the faders Apply now would reset (67e404e)
- model: plan bit-perfect players hard and lock their fader (6913310)
- model: plan every transition of a bit-perfect player hard (f543338)
- model: send each source's normalization with its request (b9feced)
- model: start Next and Previous hard on a bit-perfect player (c2c9eb9)
- model: tell bit-perfect players and the rate a cut reopens at (65fa2b2)
- new app icon (9adcae0)
- new app icon (d030af5)
- remote: read the loudness and set a track's loudness edit (daa2574)
- remote: respect the locked fader of bit-perfect players on MIDI and remote control (2fa2500)
- remote: show and enforce the locked fader of bit-perfect players (8b27053)
- store: read the log limits before logging starts (ebc626a)
- ui: add a one-line hint to every analysis setting (8b7c1a6)
- ui: add the Loudness tab to Settings (7191ab6)
- ui: create a playlist from the player's tab strip (8b1802f)
- ui: describe the normalization of a player and a track (918a308)
- ui: drain a bar on Fade stop while a fade runs (b802ed8)
- ui: draw a bit-perfect player's fader locked at 100 % (de6f194)
- ui: exclude a track from normalization or trim it (c4f07c3)
- ui: fader level, analysis hints, new playlist button and fade progress (82bd95e)
- ui: name the faders Apply now resets to 100 % (83aa4fa)
- ui: say in Settings what bit-perfect output costs (4d684db)
- ui: show and control loudness normalization (555b563)
- ui: show that a bit-perfect player does not mix (4842921)
- ui: show the author, the licence and a disclaimer in About (58ccb43)
- ui: show the locked fader and what bit-perfect output costs (7876b14)
- ui: show the normalization gain and a track's loudness (47fb32b)
- ui: show the volume level under the player's fader (ab51890)
Bug Fixes
- analysis: cache only real loudness answers and re-measure old entries (e0ad8f4)
- analysis: drop a loudness measurement that is not finite (8c85bc7)
- analysis: never analyse a promoted track twice, and make the analysis tests timing-free (c11edf3)
- analysis: never start a track again that ends while it is promoted (a62e7c8)
- app: bound the log: quiet pulseaudio, collapse repeats, cap file size (fc7f6e0)
- app: keep the log bounded and quiet repeated lines (1ead88f)
- app: never apply a stale loudness-only answer over an analysis (5a0aab0)
- app: report long repeat runs periodically and tighten the log limits (03d981a)
- backends: guard the pacer's inputs and describe catch-up as it runs (89f513c)
- backends: make up time the null output loses to a late wake-up (b6b54e3)
- backends: make up time the null output loses to a late wake-up (c44630e)
- clear the deferred bit-perfect and loudness review minors (a5ea074)
- decode: end the stream on a seek past the end of a piped Matroska file (59f192c)
- decode: land Matroska seeks on the target block (384b07a)
- decode: land Matroska seeks on the target frame (8f1813b)
- decode: log no track element value for an unknown Matroska codec (9e58bbf)
- decode: open a file again only for a seek that really goes backwards (1940677)
- decode: refuse encoded bitstreams stored as PCM (6aa8f27)
- decode: restart from the start of the stream sample-identical to the first play (901d74b)
- decode: restart Opus in Matroska sample-identically and seek cue-less Matroska backwards (a4f8f1b)
- decode: resume a Matroska reader from the end of the block read last (273b780)
- decode: round the end of a block without duration up to the next tick (7c48dcf)
- decode: seek a Matroska file without cues backwards (cf9a79c)
- decode: seek Matroska audio next to video from the right cluster (40ec206)
- decode: step back through clusters until a cue reaches the audio block (e996363)
- decode: tighten the encoded-bitstream sniff (5ad90e1)
- docs: fail the screenshot run when the players' tracks cannot be read (b2e22fe)
- docs: wait for the saved loudness before restarting the screenshot app (2cc2e59)
- docs: wait for the saved loudness before restarting the screenshot app (16c79cb)
- dsp: carry a split frame and measure every file of 400 ms or more (232f134)
- dsp: give no loudness for a corrupt file's absurd true peak (2657858)
- engine: bound the play-out before a rate cut (d54f7e7)
- engine: end a paused source at its pause ramp and quiet a paused held end once cut (29e1bf1)
- engine: forget the sound end on a reopen and quiet a zero play-out bound (29bf355)
- engine: hold the next track while paused during a held end (efa13a9)
- engine: keep the bit-perfect reopen when the operator seeks in the gap (b2c5762)
- engine: keep the bit-perfect reopen when the operator seeks in the gap (e02f85c)
- engine: keep the last sound end on its bus (967f35e)
- engine: let carts and resumes wait for the play-out too (f29ba42)
- engine: let the device play out before a rate cut closes it (6d8ab07)
- engine: let the device play out before a rate cut closes it (721a574)
- engine: open a source sought in the gap at the rate the cut waits for (8eb9ac8)
- engine: play a DSD track that keeps a normalization gain converted (e2dd63d)
- engine: report a bus's rate again when a holder is placed on it (604a566)
- engine: report the gain a scheduled transition started with (ed25a46)
- engine: report the latest normalization status of a kept preload (acaeaa0)
- loudness normalization follow-ups (DSD gain, engine-reported gain, trim in use) (5e53db0)
- model: allow no boost from a maximum that is not a number (ffce157)
- model: answer no SetVolume for an unknown player at any value (b806949)
- model: count a paused player as sounding before a rate cut (fb7a6c9)
- model: drop a stream rate reported for a device no holder uses (12bf652)
- model: keep every boost within the true-peak ceiling and share the maximum trim (26f2031)
- model: never round a ceiling-limited boost above the true-peak ceiling (5e3475d)
- model: record the length and identity of the running fade (46de686)
- site: check each start's own log line and bound the app's shutdown (5d87bee)
- site: shoot the scene with loudness normalization on (fb28d29)
- ui: align the column reorder arrows in Settings (b46b6ef)
- ui: change the number of players only when the slider is released (c5a6fcd)
- ui: colour the status-bar MIX legend like the marker and test the polish (9e7b9b1)
- ui: draw the active mix marker violet, apart from the orange outro (3589cfe)
- ui: give every Settings button the same padding and height (b8525a8)
- ui: green BP badge, padded settings buttons, aligned column arrows, violet mix marker (5b103ef)
- ui: keep the audio system list inside a narrow Settings window (f355e45)
- ui: keep the audio system list inside a narrow Settings window (6b260f1)
- ui: keep the settings lists inside a narrow window (8ab256d)
- ui: keep the settings lists inside a narrow window (2bda50e)
- ui: name a trim limited only when the limit shows (483dfeb)
- ui: name the application, not a player, in the Spanish cover message (fed9fae)
- ui: one tooltip on the language list, and on disabled lists too (81d8512)
- ui: resize a cart page only once a typed size is complete (c393157)
- ui: resize a cart page only once a typed size is complete (f1a90d2)
- ui: say player and bit-perfect throughout the Spanish interface (9cda738)
- ui: shorten the About window's AI translation notice (8f599e0)
- ui: shorten the About window's AI translation notice (99aed0b)
- ui: show a shortened output choice whole on hover (8c11cba)
- ui: show the attribution untranslated and scroll the whole About window (50a2446)
- ui: show the BP badge green when on and drop the stacked About tooltip (88ca63d)
- ui: show the trim in use, not the saved one, in loudness tooltips (f7b91b2)
- ui: stop quoting current loudness settings beside an earlier gain (31cc51d)
- ui: time the Fade stop bar by the running fade and polish the new-playlist popup (2cf291d)
- ui: word the refused-trim message for values that are not numbers (7ce1ffa)
Code Refactoring
- dsp: move the K-weighting and the true peak to a new fp-dsp crate (753f5b3)
- engine: drop the lint allows of the rate-cut example (022e5d5)
- ui: take the Trim slider's range from the shared maximum trim (bd197a6)
Documentation
- add the disclaimer and a new README header, and say the texts are AI-produced (8c9b574)
- align the attribution term, packages and specs with the new About (a38b7b1)
- decode: note how the vendored Matroska reader's patch can be dropped (c107473)
- describe loudness normalization in the guide and the API (85a3b9a)
- describe the fp-dsp crate (cbe8ba8)
- describe the locked fader on MIDI and remote control (2d12c94)
- describe the log filter, repeat collapsing and the size cap (194e5c4)
- describe the loudness measurement and its pass (0153f87)
- describe the normalization settings and per-track edit (21a665a)
- describe the per-source normalization gain (f045071)
- describe the rate cuts of bit-perfect buses (4d6e981)
- describe the repeat summary interval and the log limits (7c1c016)
- describe the violet MIX marker, the green BP badge and the tile tooltip rule (ea31f40)
- design and plan bit-perfect rate cuts and the locked fader (46029a3)
- design and plan loudness normalization (5f2b728)
- explain what bit-perfect output costs (59926d8)
- match the loudness spec and analysis docs to the implementation (3e95727)
- number the play-out rule BR17 (24623d8)
- plan: plan loudness normalization (140bceb)
- plan: plan the bit-perfect hard transitions and locked fader (d35df40)
- regenerate the screenshots with loudness normalization on (ea10d16)
- regenerate the screenshots with loudness normalization on (bfbdcab)
- say when a lowered maximum trim is saved into a track's edit (50d9fc5)
- say when the bit-perfect rate cannot follow and what Cue keeps (55e5451)
- spec: describe the loudness tooltip line in its own terms (f30f192)
- spec: design loudness normalization (b9c9f7e)
- spec: follow the track's rate and lock the fader on bit-perfect devices (c3392eb)
- spec: match the bit-perfect spec to the code it cites (f4c276b)
- spec: never crossfade on bit-perfect devices (83e8ff4)
- spec: point the amended rules to the bit-perfect rate and fader spec (f87d42f)
- spec: record that every bit-perfect device cuts on a rate change (89ac743)
- spec: record the maintainer's answers on loudness normalization (aa57bd6)
Build System
- add Dependabot updates for Cargo and GitHub Actions (24e61bc)
- generate the icons from the SVG source (662ca98)
- group Dependabot updates by compatibility (418fc33)
Unsigned installers
- the Windows installer (SmartScreen warns about an unknown publisher)
- the macOS app (not signed or notarised: macOS asks before its first start)
How to open them: Getting started.