Repository navigation
audiograph: a phaser, a glide, LFO shapes and a clocked sample-and-hold - #303
Merged
Merged
Conversation
Four node kinds, added after OUT so the existing kinds keep their numbers, on CPython, MicroPython and CircuitPython alike. No node file outside audiograph changed. PHASER calls the all-pass kernel audiobiquad.AllPass uses, on one channel, with its frequency, feedback and mix as parameters and the stage count as the build argument. It matches AllPass at 0 counts fed the same settings each 256-frame block. LAG glides a pitch CV to each new note with the bend riding on top: a constant-time line with off, on and legato-only modes, or a one-pole. It matches vrack's two GlideCore classes at 0 counts and 1 count. LFO_SHAPE adds a sine, a falling saw, a square and a random level drawn at each cycle's start beside the triangle, all from the triangle's phase. The triangle renders the same bytes as before. The shapes match vrack's LFOCore on that phase (sine within 1 count, saw and square exact); the phase itself runs up to 0.06% off its rate, as it always has. SAMPLE_HOLD latches its signal at every rising clock edge with an optional one-pole lag (vrack's SampleAndHoldCore, 0 counts, 1 with a lag), or, with the clock open, refreshes at a rate through audioshaper's sample-and-hold kernel (0 counts against audioshaper.SampleHold). audiodsp_graph.c now includes audiodsp_fp_contract.h, as every other float file in src/shared does, so no target fuses its multiply-adds. tests/parity/graph_nodes_probe.py renders all four, and verify_graph.py compares it across interpreters beside the runner's probe: CPython, MicroPython and CircuitPython unix agree on all 307200 samples. Four new planted faults, one per node, each make it fail; CI runs them first. tests/test_cpython_audiograph_nodes.py holds each node to what it stands in for.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Four node kinds for
audiograph, so the rest of the polysynths can run as one C graph: Poly6's phase mode, glide and portamento, the LFO shapes their LFO modules use, and sample-and-hold. They are on all three bindings, and no node file outside audiograph changed.PHASERaudiobiquad.AllPasson one channel, through the same kernel: stages set at build (arg), with frequency, feedback and mixAllPass, 0 counts, fed the same settings each 256-frame blockLAGdsp/glide.pyanddsp/utility.pyGlideCore, 0 counts and 1 countLFO_SHAPELFOCore's shapes on that phase: sine 1 count, saw and square 0; the triangle is byte-identical to mainSAMPLE_HOLDSampleAndHoldCoreat 0 counts, 1 with a lag;audioshaper.SampleHoldat 0Across interpreters,
tests/parity/graph_nodes_probe.pyrenders all four andverify_graph.pynow compares it beside the runner's probe. CPython, MicroPython unix and CircuitPython unix agree on all 307,200 samples, and the runner's probe still agrees on its 41,221. Each of the four new planted faults (a phaser frequency a block late, a legato flag flipped, a shape switch a block late, a clock edge a sample late) makes the comparison fail, and CI runs them first.Faults planted in the C, one per node, each failed
tests/test_cpython_audiograph_nodes.pyand were then reverted. They were: the phaser's mix never configured, the glide's ramp one step short, the saw rising, and the hold latching on falling edges.Also worth knowing:
LFOCorestays within 5e-5. Fixing it would move the triangle, so it stays, anddocs/audiograph.mdsays so.audiodsp_graph.cnow includesaudiodsp_fp_contract.h, as every other float file insrc/shareddoes. On x86-64 nothing moves (both probes are byte-identical to main). On a target that fuses multiply-adds, the graph now renders what the desktop does.