Skip to content

amy.c: Chained oscs are evaluated backwards from the end of the chain. - #1200

Merged
dpwe merged 1 commit into
mainfrom
chain_tail_recurse
Sep 29, 2026
Merged

dpwe merged 1 commit into
mainfrom
chain_tail_recurse

Conversation

@dpwe

@dpwe dpwe commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

Claude informed me that, counter to my understanding, filter (and distortion) applied to the chain up until that point in the chain; I expected them to apply to everything after the filtering osc (so a filter osc at the head of a chain filters the entire chain). I'm not sure when this got turned around (since that's how the original Juno voices worked), but the fix (head-recursing on chained osc) simplified the code, since the only thing special about a SILENT osc now is that it applies its envelope to the cumulated sum.

@github-actions

Copy link
Copy Markdown
Contributor

🎛️ AMY HW CI (AMYboard bench)

Flashed this PR's AMY (LoadTestChord: 6-voice Juno patch=1, one held note every 2 s) onto the physical AMYboard and measured the smoothed render load as the chord grows — back-to-back with the same sketch built at the PR's merge base, so Δ is this PR's own cost.

✅ PASS — the bench ran the test to completion.

notes held main @ 61e1a1e this PR Δ
1 992 995 +3
2 1148 1157 +9
3 1717 1725 +8
4 1878 1900 +22
5 2493 2492 -1
6 2627 2613 -14

Full chord settled render μs: 2614 (was 2627, Δ -0.5%) (peak 2618, 39 samples)

⬇️ Artifacts: serial log · load trace · report

Self-hosted bench (amyboardci). FAIL means only that the test could not run — the load values are informational, with no threshold and no audio compare. See tools/arduino_loadsweep/.

@dpwe
dpwe merged commit fb73e56 into main Sep 29, 2026
12 checks passed
@bwhitman

Copy link
Copy Markdown
Collaborator

⛓️ tulipcc integration PR opened

This merge was pinned into tulipcc for full-system CI: shorepine/tulipcc#1382

Test it there and merge that PR to move tulipcc onto this AMY.

MinoruInachi added a commit to MinoruInachi/amy that referenced this pull request Oct 4, 2026
Brings in amy up to 1.2.190 (e153f7d): the render lock (shorepine#1205), chained
oscs evaluated tail-first (shorepine#1200), MIDI CC output and midi_cc naming an AMY
parameter directly (shorepine#1175), a PCM render gain ramp (shorepine#1208), no osc
allocation on the ingest path, and the docs that go with them.

One conflict, in src/amy.c: upstream grew its own lock abstraction for
ESP_PLATFORM (a FreeRTOS mutex behind lock_init/lock_take/lock_give) where
we had a bare SemaphoreHandle_t plus esp_rom_sys.h. Took upstream's side,
and dropped our a84e093 render-in-flight counter with it: upstream's
render lock (f11a552, 2812743) closes the same FREE_OSC-under-render race
more thoroughly -- the render thread holds it for a whole block and a patch
load holds it across its flush -- and it was measured, where ours spun for
up to 50 ms. Nothing else of ours changed; src/amy.c is now identical to
upstream/main.

f11a552 lists tulipcc's native render loops as needing the wrap
themselves, but they do not: every tulipcc path reaches a render through an
amy entry point that already takes the lock. The Tab5 sets
platform.multithread = 0, so its audio task's amy_render_audio() takes the
branch that grabs it around esp_render_on_cores() + amy_fill_buffer();
Tulip CC keeps the default multithread = 1 and renders in amy's own
esp_fill_audio_buffer_task; AMYboard-in-VCV pulls blocks with
amy_simple_fill_buffer(). All three are wrapped upstream.

make ctest: all passed. make test: 135 tests pass, no failures, including
our TestAllNotesOffNoteZero at err=-100.0 dB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants