Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
965f710
Pin audiodsp at the Phase 7 node batch (bd7f409), and qualify audiode…
bdbarnett Oct 14, 2026
1a0aea3
Pin audiodsp at 9e72eac, the 7b candidate for v0.6.6rc3: the loop shi…
bdbarnett Oct 14, 2026
e469326
Pin audiodsp at f7a86c9, the 7b candidate for v0.6.6rc3
bdbarnett Oct 14, 2026
b65e719
AUDIODSP_PIN: rewrap the 7b note
bdbarnett Oct 14, 2026
4476df3
Kit: nogb runs every patch on its own and on all three interpreters
bdbarnett Oct 14, 2026
0ec69f5
Pin audiodsp at v0.6.6rc3, the release of the Phase 7 node batch
bdbarnett Oct 14, 2026
7837870
Flanger: a thin class on audiodelays.Flanger; both old flangers deleted
bdbarnett Oct 14, 2026
684cbd3
Kit: nogb takes patches=, so a slow class runs a patch at a time
bdbarnett Oct 14, 2026
66da35a
Vibrato: its CPython re-blocking sources pull the graph in-graph, not…
bdbarnett Oct 14, 2026
e7cb533
DeEsser: reset builds its Splitters again instead of pulling them empty
bdbarnett Oct 14, 2026
ba888e0
Distortion: the scoop patches build without get_buffer
bdbarnett Oct 14, 2026
7d8df15
Distortion: say why the skipped charge changes nothing, and hold ever…
bdbarnett Oct 14, 2026
afdc2ee
Flanger: follow the host's meter as well as its tempo; the attacker's…
bdbarnett Oct 14, 2026
95ca8df
Flanger: the meter follow keeps the base's NaN rule and its path
bdbarnett Oct 14, 2026
e32593e
Kit: the fresh check, a reset that comes back as a fresh instance fro…
bdbarnett Oct 14, 2026
6d92e30
Saturation: a reset plays no stale block, and latency after the lean …
bdbarnett Oct 14, 2026
1a1b7d9
MultiTapDelay: the Time move after a reset, held as an expected failu…
bdbarnett Oct 14, 2026
78848f9
Saturation: a reset onto Mix 0 inside a rack leaves the graph un-stra…
bdbarnett Oct 14, 2026
3cd82ec
DigitalDelay and SlapbackDelay: a fresh instance is patch 0, so a res…
bdbarnett Oct 14, 2026
8b43d39
Saturation: Bias is folded into the table, so silence answers silence…
bdbarnett Oct 14, 2026
6a9741e
DeEsser: a reset is a fresh instance at patch 0
bdbarnett Oct 14, 2026
7f99044
Kit fresh: boot is informational, never red
bdbarnett Oct 14, 2026
6294bdd
MultiTapDelay: the Time move after a reset is a normal test, for audi…
bdbarnett Oct 14, 2026
87e107c
Phaser: a bar is the host's time signature, and transport_changed() f…
bdbarnett Oct 14, 2026
f0fd093
ConvolutionReverb: state the input ceiling, -21 dBFS for a synthesize…
bdbarnett Oct 14, 2026
2d064e2
One answer to a macro value off the grid: clamp, NaN to the bottom stop
bdbarnett Oct 14, 2026
433ec6d
Vibrato and Fuzz: E1 P4 declared with its cause, PR kept live; the ki…
bdbarnett Oct 14, 2026
3d15e5e
AirSpace: a reset from a longer patch reports a fresh instance's tail
bdbarnett Oct 14, 2026
04256d2
Flanger: a bar is the host's time signature, numerator x 4 / denominator
bdbarnett Oct 14, 2026
e7a1c27
DeEsser: a reset part-way through a source buffer keeps the frames it…
bdbarnett Oct 14, 2026
e697f20
Lifecycle: declare Saturation's coupling residue and DeEsser's post-r…
bdbarnett Oct 14, 2026
749bcef
ConvolutionReverb: four patch rooms carry a level trim, so every patc…
bdbarnett Oct 14, 2026
d97a031
Pin audiodsp at v0.6.6rc4
bdbarnett Oct 14, 2026
9f33642
Exciter, Compressor, Distortion, Overdrive: a reset arms the output m…
bdbarnett Oct 14, 2026
1ff6b47
Tremolo, AutoPan, RingMod: a reset starts the LFO again
bdbarnett Oct 14, 2026
e3fbeaf
ParametricEQ, DynamicEQ, MultibandCompressor: a reset leaves no stale…
bdbarnett Oct 14, 2026
6665486
Phaser: a bar is the host's time signature, and transport_changed() f…
bdbarnett Oct 14, 2026
a9fcebe
Phaser: a reset starts the sweep again
bdbarnett Oct 14, 2026
425bef9
DynamicEQ, MultibandCompressor: the reset's walk leaves the stock Mix…
bdbarnett Oct 14, 2026
6e70be7
Merge branch 'effects-p7/7e-flanger' into effects-p7/land
bdbarnett Oct 14, 2026
7e52323
Merge branch 'effects-p7/7d-getbuffer' into effects-p7/land
bdbarnett Oct 14, 2026
73e9e8e
Merge branch 'effects-p7/7d-rest' into effects-p7/land
bdbarnett Oct 14, 2026
2a36009
A reset re-arms lazily, so it takes nothing from the source; Bitcrush…
bdbarnett Oct 14, 2026
642b80a
ConvolutionReverb: every patch takes at least -12 dBFS; -21 dBFS stay…
bdbarnett Oct 14, 2026
40301d6
Cost tool: the +options rows run the loop shifter, so they take v0.6.…
bdbarnett Oct 14, 2026
6063792
PitchShifter: Feedback's stack restated at v0.6.6rc4: the rail at uni…
bdbarnett Oct 14, 2026
d02d9fa
ShimmerHall: a held G3 lands on the octave, and the climb fades at th…
bdbarnett Oct 14, 2026
57dfe2c
Harmonizer: the ramp probe reads a quiet first channel, where the nod…
bdbarnett Oct 14, 2026
6ed056c
Merge branch 'effects-p7/7d-reset' into effects-p7/land
bdbarnett Oct 14, 2026
d003eea
Kit fresh: declare the stock tier's reset before the first pull (Flan…
bdbarnett Oct 14, 2026
596fd8b
A reset arms from the source where get_buffer is compiled out, and th…
bdbarnett Oct 14, 2026
a06b921
DeEsser: its option defaults by name, the shape the kit's ctor cells …
bdbarnett Oct 14, 2026
4a786aa
Kit args: back at patch 0 reads patch 0's values, not a fresh instance's
bdbarnett Oct 14, 2026
5e946a6
Kit fresh: declare the pitch shifters' reset on CircuitPython's own P…
bdbarnett Oct 14, 2026
c40f584
Reset after a rebuild: the lazy silence and Ports are dropped once a …
bdbarnett Oct 14, 2026
491eff7
Clamp a huge macro value, and keep the last good transport on Phaser …
bdbarnett Oct 14, 2026
c99d362
ConvolutionReverb: a wet trim that follows Damping, and an input ceil…
bdbarnett Oct 14, 2026
7d31130
ConvolutionReverb: the wet trim is a soft knee on a Decay x Damping f…
bdbarnett Oct 14, 2026
18aaa78
ConvolutionReverb: the wet trim is read off the room, through a soft …
bdbarnett Oct 14, 2026
acc632f
A reset onto settings that route around the graph leaves it unstrande…
bdbarnett Oct 14, 2026
5ac0310
Lifecycle matrix: ShimmerHall's 144 CircuitPython-own cells, counted …
bdbarnett Oct 14, 2026
f827e92
Merge branch 'effects-p7/land-fixes' into effects-p7/land
bdbarnett Oct 14, 2026
956a9bf
Pin audiodsp at v0.6.6rc5
bdbarnett Oct 14, 2026
4dfd8d9
Kit fresh: Overdrive's mono first block (audiocomponents#142) covers …
bdbarnett Oct 14, 2026
13b89fb
Kit's own test: the control clamps the huge values the bad-macro cell…
bdbarnett Oct 14, 2026
9ede2b8
audioeffects README: all 45 classes by group, with a latency table at…
bdbarnett Oct 14, 2026
ec28669
Tremolo: a knob moves the LFO in place instead of restarting it
bdbarnett Oct 14, 2026
38d0abe
Saturation: Bias sounds over its whole travel (tube reach +-1.25 V of…
bdbarnett Oct 14, 2026
c16f213
Bitcrusher: the dither tail bound covers maximum Dither, and is None …
bdbarnett Oct 14, 2026
3a190a8
Fuzz: tail_samples is None with Bias off centre
bdbarnett Oct 14, 2026
49892df
Saturation tests: say why the clean class misses TU1 at Bias's stops
bdbarnett Oct 14, 2026
9f37039
Retire _core.py and the pre-contract classes the rebuilds replaced
bdbarnett Oct 14, 2026
acc8ca0
Changelog: Tremolo's knobs, and Fuzz's and Bitcrusher's tail bounds
bdbarnett Oct 14, 2026
5e04643
Convolve node tests: name the class tests that cover the node now
bdbarnett Oct 14, 2026
4890b72
Vibrato: Engage follows Rise on every interpreter, on the node's own …
bdbarnett Oct 14, 2026
ac7309c
Saturation: say Output can clip at full input, declare the all-at-top…
bdbarnett Oct 14, 2026
d597366
Without get_buffer, pull through a scratch mixer voice: MultiTapDelay…
bdbarnett Oct 14, 2026
59aa825
Kit: declare Overdrive's E10-patch p6 nogb cell; drop the back-to-bac…
bdbarnett Oct 14, 2026
a81f0c7
Saturation: a gain move in silence with Hysteresis on plays nothing
bdbarnett Oct 14, 2026
415f403
Mix 0 before the first pull is the wire; Clean Edge no longer cracks
bdbarnett Oct 14, 2026
0b29acc
LAZY_BUILD hands up through _pull where it exists; tests follow the l…
bdbarnett Oct 14, 2026
1bef9b1
Merge branch 'effects-p7/fix-d' into effects-p7/land
bdbarnett Oct 14, 2026
d83fe9e
Merge branch 'effects-p7/fix-b' into effects-p7/land
bdbarnett Oct 14, 2026
1b101ff
Merge branch 'effects-p7/fix-c' into effects-p7/land
bdbarnett Oct 14, 2026
e35b840
Merge branch 'effects-p7/fix-a' into effects-p7/land
bdbarnett Oct 14, 2026
ddca05e
Merge branch 'effects-p7/readme' into effects-p7/land
bdbarnett Oct 14, 2026
4c2996b
Pin audiodsp at v0.6.6rc6
bdbarnett Oct 14, 2026
12d6d5e
Without get_buffer the build always has _pull_node: drop the dead guards
bdbarnett Oct 14, 2026
1256a5b
Lifecycle matrix test: LIFECYCLE_CLASSES reaches every class, with th…
bdbarnett Oct 14, 2026
f7c0702
audioeffects README: Tremolo's default and L1 words, and only the tes…
bdbarnett Oct 14, 2026
f0d0c92
Lifecycle: declare Tremolo's E1 P4, as Vibrato's is
bdbarnett Oct 14, 2026
bd2ea38
MultiTapDelay tests: LIFECYCLE_MICROPYTHON and LIFECYCLE_CIRCUITPYTHO…
bdbarnett Oct 14, 2026
bcbf362
Limiter: Delivery Ceiling - lean for the ESP32-S3; MultibandCompresso…
bdbarnett Oct 14, 2026
574dbeb
Kit: declare Saturation's Output +12 cells on a 0 dBFS sine
bdbarnett Oct 14, 2026
dc04abd
Merge branch 'effects-p7/lean' into effects-p7/land
bdbarnett Oct 14, 2026
1633cd1
WIP lifecycle F1, F2, F7: lazy re-arm on controls, Overdrive LAZY_BUI…
bdbarnett Oct 15, 2026
51a94bb
WIP: re-point without reset; Compressor primes the routed stage
bdbarnett Oct 15, 2026
dbdc6cf
Mix back up from 0 plays nothing from before, in six classes (7f F3)
bdbarnett Oct 15, 2026
5dbed97
Phaser: a Drive, Mix, Feedback or Stages move no longer replays the s…
bdbarnett Oct 15, 2026
8094188
Vibrato: Rate, Depth and Delay moves glide; Level arms the same on ev…
bdbarnett Oct 15, 2026
78fdbab
Saturation: clear the incoming shaper with a reset on the lean route …
bdbarnett Oct 15, 2026
03e7940
test_first_pull: DeEsser's head-node replay is not this cause
bdbarnett Oct 15, 2026
b53bea4
Lifecycle: declare Vibrato's 1 LSB rounding flip on E6-p0 at patch 5
bdbarnett Oct 15, 2026
3e84461
Vibrato: a new clock law goes to the node, which swaps it at zero dep…
bdbarnett Oct 15, 2026
38c949c
Saturation: clear the incoming shaper only when the outgoing one repo…
bdbarnett Oct 15, 2026
24e805f
Merge branch 'effects-p7/lc-1' into effects-p7/land
bdbarnett Oct 15, 2026
680b790
Merge branch 'effects-p7/lc-2' into effects-p7/land
bdbarnett Oct 15, 2026
dadb99d
Merge branch 'effects-p7/lc-3' into effects-p7/land
bdbarnett Oct 15, 2026
f9c0242
Pin audiodsp v0.6.6rc8 (f83ddc6); the Splitter bypass-return cases ru…
bdbarnett Oct 15, 2026
a7d5e38
CabinetSim: the clamp test reads the kit's huge-value cells too
bdbarnett Oct 15, 2026
7b46bec
Restate two plants the lazy re-arm made inert (lc-1)
bdbarnett Oct 15, 2026
5bb4f59
Fuzz: the lean route charges the pole for every block, as a build wit…
bdbarnett Oct 15, 2026
451a4e7
Merge branch 'effects-p7/lc-1' into effects-p7/land (5bb4f59)
bdbarnett Oct 15, 2026
dd6fcf8
Saturation: the cold-start step on un-bypass is a known red (#160)
bdbarnett Oct 15, 2026
00440eb
Bitcrusher: the band limit's first section lets go of a tap's chunk o…
bdbarnett Oct 15, 2026
a136871
Lifecycle gate: every class the package serves, its reds written down
bdbarnett Oct 15, 2026
dcb72fc
LIFECYCLE.md: the matrix test gates every class
bdbarnett Oct 15, 2026
0c055b9
TapeDelay: a balance move glides at audiodsp rc8
bdbarnett Oct 15, 2026
abbbdc6
Kit: Overdrive's nogb pole-charge row covers the five E10 cells lazy …
bdbarnett Oct 15, 2026
f9c0a4c
Overdrive: #142's mono fresh-build half is closed by the lazy build
bdbarnett Oct 15, 2026
e4eedef
Lifecycle: Distortion's patch-7 pre-pull residue is #161
bdbarnett Oct 15, 2026
c165d94
Lifecycle: LowPass, BandPass and Notch's Frequency-to-bottom rows are…
bdbarnett Oct 15, 2026
11de77c
CI: a pull request's lifecycle gate runs only the classes its change …
bdbarnett Oct 15, 2026
b40d8f8
CI: a shared change's pull request runs a nine-class lifecycle sample…
bdbarnett Oct 15, 2026
b8e44d7
Pin audiodsp v0.6.6rc9 (96abd34): a biquad coefficient move walks ove…
bdbarnett Oct 15, 2026
9220e91
LowPass, BandPass, Notch: a Frequency move's ring stays inside even t…
bdbarnett Oct 15, 2026
cc3db98
Lifecycle gate at audiodsp rc9: #162's rows come out
bdbarnett Oct 15, 2026
ec96a4a
DynamicEQ: a Frequency move's ring stays inside the old bound at rc9
bdbarnett Oct 15, 2026
2dfd584
Octaver: a patch picked before playback starts its filters there at r…
bdbarnett Oct 15, 2026
95aafce
GraphicEQ at rc9: the detent fault bites as a departure from a fresh …
bdbarnett Oct 15, 2026
c86f544
Kit graph: the exhausted probe is a block short of the render
bdbarnett Oct 15, 2026
33064be
CI: a pull request checks out its history, so the lifecycle scope wor…
bdbarnett Oct 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ on:
branches: [main]
paths-ignore: ['docs/**', 'README.md', 'ROADMAP.md', 'CHANGELOG.md', 'AGENTS.md', 'LICENSE']
pull_request:
# `labeled` too: adding the `lifecycle: all classes` label re-runs the
# pull request with the whole lifecycle matrix (see the test step).
types: [opened, synchronize, reopened, labeled]
paths-ignore: ['docs/**', 'README.md', 'ROADMAP.md', 'CHANGELOG.md', 'AGENTS.md', 'LICENSE']
# The full matrix on demand, for a branch that should see every Python
# before it merges rather than after.
Expand Down Expand Up @@ -47,8 +50,30 @@ jobs:
- os: macos-latest
python: "3.13"
runs-on: ${{ matrix.os }}
env:
# The lifecycle matrices (quick mode). All 45 classes take about 4.4
# CPU hours, over an hour on this runner, and the 13 audiodsp nodes
# under them half an hour more on one worker, so a pull request runs
# only what its change can move: the class or node whose own code
# changed, and when a shared file changed (the base class, the
# matrix, the pin) a fixed sample of each, nine classes in about 13
# minutes and four nodes in about five (SAMPLE in
# tests/test_lifecycle_matrix.py, NODE_SAMPLE in
# tests/test_node_matrix.py). A push to main runs every class and
# every node, and so does a manual run (workflow_dispatch) or a pull
# request labelled `lifecycle: all classes`.
LIFECYCLE_CHANGED_FROM: "${{ github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'lifecycle: all classes') && format('origin/{0}', github.base_ref) || '' }}"
steps:
# A pull request fetches its history, so the matrices can ask git what
# the change touches against origin/<base> (LIFECYCLE_CHANGED_FROM).
# Written `!= ... && 1 || 0` because `== ... && 0 || 1` is always 1:
# 0 is false in an expression, so the `||` took over and every pull
# request checked out at depth 1. With no base to diff from, the
# matrix then fell back to all 45 classes, and a pull request ran
# 1 h 43 min. A base git cannot diff from is now an error instead.
- uses: actions/checkout@v7
with:
fetch-depth: ${{ github.event_name != 'pull_request' && 1 || 0 }}
- uses: actions/setup-python@v7
with:
python-version: ${{ matrix.python }}
Expand Down Expand Up @@ -109,6 +134,17 @@ jobs:
# a test. The tests would generate them too; this makes it explicit.
- run: python tools/effect_probes/make_probes.py --ensure

# What the two matrices will run, in the log where a reader can check
# it, and a scope git cannot work out fails here by name.
- name: Show the lifecycle scope
shell: bash
run: >-
python -c "from tests.test_lifecycle_matrix import classes;
from tests.test_node_matrix import names;
print('base:', '${LIFECYCLE_CHANGED_FROM:-none, all}');
print('classes:', ' '.join(classes()) or 'none');
print('nodes:', ' '.join(names()) or 'none')"

# The same tests `python -m unittest discover -s tests -p "test_*.py"`
# finds, spread across every core the runner has: serially the suite
# takes over an hour. A test that writes a file writes it into its own
Expand Down
54 changes: 53 additions & 1 deletion AUDIODSP_PIN
Original file line number Diff line number Diff line change
Expand Up @@ -345,5 +345,57 @@
# holds its line still at mix 0 (#226); audiovorbis (#238, #239); and an
# fmod-free angle reduction for the RP2040 (#225).
#
# 2026-10-13: v0.6.6rc1 -> f7a86c9, the effects program's Phase 7 node batch
# (step 7b): the candidate for audiodsp's next pre-release, v0.6.6rc3, and
# the final pin of the phase. Named by commit until the tag is cut; the tag
# names the same source. What moves beneath the components, by `git log
# v0.6.6rc1..f7a86c9 -- src`: audiodelays.Flanger lets go of a looped source
# that comes back empty and gives a stalled one silence, instead of spinning
# the pull; audioecho.FeedbackDelay's upward loop_semitones writes its line
# through a band limit at 0.7 of the frequency the next pass would carry to
# Nyquist, so a climb fades out at the top instead of folding back; and both
# shifters (the loop's two taps and audiodelays.PitchShift's splice) move a
# splice's incoming side into phase with the outgoing one, so a held note
# plays its shifted pitch, and a chord its notes, instead of cancelling.
# Unshifted and downward FeedbackDelay renders, silence and a lone click
# through either shifter, and a frozen PitchShift window render the bytes they
# did.
#
# Moved to v0.6.6rc3 (a9d36e6) on 2026-10-13: the release of the commit
# above (audiodsp#245, #247), the same node tree as f7a86c9 outside VERSION
# and CHANGELOG.md, so CI can install it from GitHub.
#
#
# Moved to v0.6.6rc4 (8d5c282) on 2026-10-14: MultiTapDelay's reset puts the
# write heads back where a fresh node has them, and audioconvolve.Convolver
# gains wet_gain (default 1.0, byte-identical there), which
# ConvolutionReverb uses to trim its four darkest rooms (audiodsp#248).
#
# Moved to v0.6.6rc5 (b278d32) on 2026-10-14: audioconvolve.Convolver gains
# room_peak_gain and room_peak_gain_for, the reading ConvolutionReverb's wet
# trim is computed from. Every render is byte-identical to rc4's.
#
# Moved to v0.6.6rc6 (9399602) on 2026-10-14: audioecho.FeedbackDelay gains
# wow_depth_ramp_ms, which Vibrato's Engage rides so its Rise ramps on every
# interpreter, and audioshaper.Waveshaper gains recentre(), which
# Saturation calls so a gain move in silence with Hysteresis on plays
# nothing. Every render is byte-identical to rc5's at the defaults of both.
#
# Moved to v0.6.6rc8 (f83ddc6) on 2026-10-14, by way of rc7: the CPython
# extension no longer crashes in garbage collection while a RawSample still
# exports a buffer; audiodynamics.Dynamics writes a mono block at its own
# stride, so short source buffers leave no stale frames; audioroute.Splitter
# gains clear(), which six classes call to drop what the ring held from
# before a bypass when Mix comes back up; and audioecho.FeedbackDelay takes
# a new wow_shape by dipping the depth to zero and swapping there, which
# Vibrato hands its clock law to. Every other render is byte-identical to
# rc6's.
#
# Moved to v0.6.6rc9 (96abd34) on 2026-10-15: audiobiquad.Biquad walks a
# coefficient move over 20 ms instead of keeping its state through the jump,
# so LowPass, BandPass and Notch no longer thump at full scale when
# Frequency jumps to the bottom (audiocomponents#162). Static renders are
# byte-identical to rc8's; only renders across a coefficient move change.
#
# <ref> <commit> -- ref is what CI installs (git+https://...@<ref>)
v0.6.6rc1 30cbbf619751ab6ff7c40d99336907af0a081fa6
v0.6.6rc9 96abd345344eb356f1af5de24e320bfcf778cb8d
Loading
Loading