Skip to content

Catch the effects up with the audioif floor at cebb7ca - #67

Merged
bdbarnett merged 5 commits into
mainfrom
fix/audioif-pin-cebb7ca
Sep 17, 2026
Merged

bdbarnett merged 5 commits into
mainfrom
fix/audioif-pin-cebb7ca

Conversation

@bdbarnett

Copy link
Copy Markdown
Contributor

Fixes #66. Tests has been red on main since the audioif floor moved to cebb7ca for acoustickit. That move brought five deliberate audioif changes, and 27 tests went red.

Four of the fixes change what you'd hear:

  • AutoPan's Centre was mirrored. CircuitPython 10.3.0 reversed synthio's panning sign, so setting Centre to the left put the sound on the right. No existing test could see it, because every sweep test is symmetric. The notes are paired the other way now, and a new test holds Centre to its side, with the old pairing planted to prove it can go red.
  • The first block after construction was silent, then clicked in. On AutoPan, DeEsser and MultibandCompressor. A fresh mixer voice or synthio note now starts at level 0 and waits for a zero crossing. _component.open_level_gates opens each gate on one block of silence before the voices take their sources. With the helper switched off, the original failures come back.
  • Saturation's tape character had lost its head bump. synthio.Biquad is CircuitPython's Q15 arithmetic again (audioif#77), so the 80 Hz shelf that should add +1.5 dB was reading −7.65 dB. The shelves are on audiobiquad now, falling back to synthio only where it's missing. Forcing the fallback turns the five tests red again.
  • BandPass T1 mostly came right (audioif#64). The low-corner probe now puts 55 of 56 cells inside the bar, both knob stops included. The one remaining miss is −0.091 dB at 31.5 Hz with Q 32, and it's pinned by its own test.

The rest are tests catching up with audioif's intended behaviour. A released node raises ValueError, Splitter releases, Dynamics.reset() clears the key filters, and there are 55 instruments. GraphicEQ's two plants were re-pointed so they can still fail.

Verified in a clean venv with audioif installed from the pin, as CI does:

  • 957 tests OK (2 skipped), validate_api (55 + 45), effects smoke 0 failures over 203 patches, and flake8 clean.
  • CPython and desktop MicroPython (today's build-standard, which carries this audioif) render the same FNV digest on nine renders across all six touched classes.
  • The evidence-pack addenda are in the workspace repo.

Not done: no board cost runs, and nothing was run on the CircuitPython oracle build.

The pin move to audioif cebb7ca brought four behaviour changes these tests
were written against, and each test was right to go red:

- a released node raises ValueError on every target, as CircuitPython
  does (audioif e1f3704), not RuntimeError;
- audioroute.Splitter has a deinit() (audioif#58), so the walk releases it:
  the NoiseGate walk checks it by its flag, since it is not a sample, and
  the kit's no-deinit gap is held to its behaviour with a planted node;
- Dynamics.reset() clears the key filters (audioif 1f33077): the test that
  recorded the 33 LSB miss was written to go red on exactly this, and now
  asserts exact zero from -6 dBFS and from full scale;
- acoustickit is the 55th instrument.

Part of #66.
…thio

The floor move to audioif cebb7ca brought 10.3.0's synthio loudness changes,
and AutoPan's gain notes met both.

Panning's sign reversed, so the pairing panning=+1 for the left table put it
on the right. Every sweep test is symmetric and stayed green; Centre shows it,
where -0.8 came out on the right. The pairing is swapped, and a new test holds
Centre to its side with the old pairing planted as SwappedSides.

A fresh voice renders at level 0 until its output crosses zero, and a gain
table never does, so the first block was silent and the gain stepped in after
it. The notes are pressed on a silent waveform for one block, which opens the
gate at once, and then take their tables. Without the prime six tests go red.

Part of #66.
Since CircuitPython 10.3.0 (audioif 4ec5718) a fresh mixer voice or synthio
note starts at level 0 and takes its level only when its signal is zero or
changes sign. The first block of anything that does not cross zero in it -
a ramp, an impulse at frame 0, a gain table - came out silent, and the level
then stepped in at the block boundary, which is a click.

_component.open_level_gates plays silence on the voices for one pull, which
opens every gate at the level already set; the caller then gives the voices
their sources. MultibandCompressor does this in _play_voices, which already
ran after the macros. DeEsser now plays its six voices at the end of
construction, after the macros, instead of in the middle of it. AutoPan's
prime gets the same guard: audiocore.get_buffer is compiled out of
CircuitPython's default board builds, where the prime does nothing.

With the helper switched off, the seven DeEsser and MultibandCompressor tests
that went red at the pin move go red again.

Part of #66.
… accurate

audioif#77 split the biquads by ownership: synthio.Biquad, and so
audiofilters.Filter, runs CircuitPython's Q15 arithmetic on every target,
and the widened kernel is audiobiquad's alone. At the cebb7ca floor an 80 Hz
low shelf asked for +1.5 dB reads -7.65 dB through synthio, so tape lost its
head bump and five Saturation tests went red.

Saturation now chains audiobiquad shelves, and falls back to synthio only
where audiobiquad is missing; forcing that fallback turns the same five
tests red again. The shelves are a chain, so reset() and deinit() walk the
ones behind the output. The low-shelf resolution test reads audiobiquad,
where the claim now lives, and the README's note on how low a filter can go
says which node is accurate and why.

Part of #66.
…fixed

audioif#64 moved audiobiquad's float sections to transposed direct form II.
Three tests written to stay red on the old kernel's defects went green, and
each was right to say so.

BandPass T1 held the -0.50 dB miss at the knob stops, and said it would be
the test to announce audioif#64. Re-running the low-corner probe at the new
floor: 55 of 56 cells inside the 0.05 dB bar, stops included, and one miss,
-0.091 dB at f0 31.5 Hz with Q 32, now pinned by its own test. The class
docstring and the README row say so.

GraphicEQ's retired plant is green on every band now, not six of ten. Its
live plant, a patch jump on stale state, no longer slams from 5 to 1; from
2 to 1 it still reaches 2.72x steady against the check's 2x bar, and 1.32x
through the class, so the plant moves there and is held to that bar.

The CHANGELOG records all of #66.
@bdbarnett
bdbarnett merged commit 94b1c17 into main Sep 17, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

CI red since the audioif pin move to cebb7ca: 27 failures from five deliberate audioif changes

1 participant