midi_cc can name an AMY parameter directly (#1175, part 1) - #1191
Conversation
A MIDI mapping payload that starts with a digit is now a parameter list
instead of a wire command template:
ic<C>,<L>,<N>,<X>,<O>,<P>[,<OSC>][,<P>,<OSC>...]
P is an enum params id, exported to Python/JS as amy.PARAM_* (generated
from amy.h by scripts/gen_param_constants.py, which compiles against the
header so the computed enum values are the real ones). OSC is
voice-relative; a lone P means osc 0. Up to 4 P,OSC pairs share a value.
A direct mapping sets the matching amy_event field and sends the event
to the synth by the ordinary path, so values are in amy.send() units,
reach every voice, and bus params go to the synth's bus. Only params
with a plain event field are mappable; note-shaped params, osc refs,
breakpoints and resets are refused, and a refused payload no longer
deletes the mapping already on that CC. Integer params are rounded.
This is the groundwork for midi_cc_output, which will use the same
P,OSC form to echo parameter changes out as MIDI CCs.
Also: midi_mapping_init now checks its allocation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PykXkeeWw2aRpC6PLfpqTQ
🎛️ AMY HW CI (AMYboard bench)Flashed this PR's AMY (LoadTestChord: 6-voice Juno ✅ PASS — the bench ran the test to completion.
Full chord settled render μs: 2633 (was 2600, Δ +1.3%) (peak 2640, 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 |
⛓️ tulipcc integration PR openedThis merge was pinned into tulipcc for full-system CI: shorepine/tulipcc#1379 Test it there and merge that PR to move tulipcc onto this AMY. |
Part 1 of #1175: the direct-parameter form of
midi_cc, whichmidi_cc_outputwill mirror in a follow-up.A mapping payload that starts with a digit is a parameter list instead of a wire command template (the forms can't collide, since no wire command starts with a digit):
How it's done
amy.PARAM_*constants for everyenum paramsentry.scripts/gen_param_constants.py(run from the existingconstants.pyrule) compiles a tiny program againstamy.h, so the computed enum values are the compiler's rather than parsed from comments, which are stale (NO_PARAM // 210is really 234). ThePARAM_prefix keepsFREQ,BUS,MODEetc. from shadowing anything inamy.. It uses$(HOSTCC)(defaultcc), not$(CC), so a cross build still works.amy_api.generated.jsis regenerated to match.amy_eventfield (aparam_fieldstable inmidi_mappings.c) and sends the event to the synth down the ordinary path. So:amy.send()units (Hz forfilter_freq, linear drive, …), with no second copy of the logfreq/log2/logdrive conversions;OSC;PARAM_VOLUME,PARAM_REVERB_LEVEL,PARAM_BUS_DIST_*, …) go to the synth's bus.MIDI_NOTE/VELOCITY, osc references (CHAINED_OSC,MOD_SOURCE_*,ALGO_SOURCE_*), breakpoints, resets,LATENCYandBUSare refused. So isMODE, becauseevent_addresses_oscs()doesn't countmode, so a synth-addressed mode change is dropped today (template form too; left alone here).midi_mapping_initdidn't check itsmalloc_caps.Tests
tests/test_midi_cc_param.c, added tomake ctest. It covers:P,OSCtargetsmake ctest: all pass.make test: 90 pass / 43 "fail" at ~-99 dB error. That result is identical on unmodifiedmainin this environment, so it's float noise, not this change.Follow-up (part 2):
midi_cc_output(iC) with the sameC,L,N,X,O,P[,OSC]form, hooked besidenote_output_handle_eventinpatches_event_has_voices. Decisions:note_outputMIDI channel, otherwise the synth number;note_output;It will only send when the target queue is the live delta queue.
note_outputlooks like it has the same issue when events are stored into a patch; that's worth a separate small fix.🤖 Generated with Claude Code
https://claude.ai/code/session_01PykXkeeWw2aRpC6PLfpqTQ
Generated by Claude Code