You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(audio): 32-voice polyphony, smooth retriggering, and silent panic
- increase `Audio::kVoiceCount` and `StreamManager::kMaxStreams` to 32
- change retrigger behavior to start a new voice while fading out older voices in the same group
- make panic clear the trigger queue and quickly fade out active voices instead of hard-cut stopping
- remove all `Serial` logging from firmware code
- delete `todo.md`
- update `README.md` and `docs/documentation.md` to match current behavior
Copy file name to clipboardExpand all lines: docs/documentation.md
+14-22Lines changed: 14 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -100,7 +100,7 @@ Minimal format:
100
100
Notes:
101
101
102
102
-`note`: `0..127`
103
-
-`panic_note`: optional `0..127`; when received as MIDI NOTE ON, all active voices are stopped immediately
103
+
-`panic_note`: optional `0..127`; when received as MIDI NOTE ON, all active voices are quickly faded out
104
104
-`playback_mode`: optional `"shot"` or `"loop"` stored per assignment/sample
105
105
-`volume`: clamped to `0..100`
106
106
-`volume = 100`: full per-voice level (before dynamic mixer headroom)
@@ -124,14 +124,13 @@ Current pipeline (recently updated):
124
124
125
125
Playback engine behavior:
126
126
127
-
- fixed `8`-voice playback pool (`Audio::kVoiceCount`),
127
+
- fixed `32`-voice playback pool (`Audio::kVoiceCount`),
128
128
- each trigger allocates a free voice slot when available,
129
-
- retriggering the same sample reuses its active voice slot when possible (previous instance is stopped and restarted from frame `0`, so the sample does not layer with itself),
129
+
- retriggering the same sample starts a new voice instance and requests short fade-out on already active voices in the same retrigger group,
130
130
- if all voices are active, the incoming trigger steals the oldest active voice (deterministic `oldest-voice` policy),
131
-
- if incoming MIDI NOTE ON matches configured panic note, all currently active voices are stopped,
131
+
- if incoming MIDI NOTE ON matches configured panic note, all currently active voices are quickly faded out and pending trigger backlog is cleared,
132
132
- works for both SD-streamed and RAM-backed sample playback,
133
-
- SD-streamed voices use per-voice read-ahead RAM buffers that are refilled by a dedicated `stream_refill`
134
-
task; the audio update loop consumes already buffered data (no direct SD read in the critical mix loop),
- per-voice mixer gain uses dynamic headroom (`kDynamicMixMinGain..kDynamicMixMaxGain`) based on active voice count; master output passes through a limiter with make-up gain to increase loudness while controlling clipping.
136
135
- trigger events are sent through a queue from UI/MIDI domain to dedicated audio task (no direct playback calls from UI code path).
- To enable/disable a log group, edit `include/debug_flags.h` and set the given flag to `true`/`false`, then rebuild and flash firmware (`make upload-main`).
180
+
- Debug flag constants are still defined in code, but main firmware no longer emits diagnostic logs to `Serial`.
181
+
-`DebugFlags::kRuntimeRamUsageLogIntervalMs = 5000` remains as a timing constant used by gated runtime checks.
188
182
189
183
### `include/input.h`
190
184
@@ -209,10 +203,9 @@ Assignment rules:
209
203
210
204
### `src/audio.cpp`
211
205
212
-
- Voice fade-in to reduce trigger click: `kVoiceFadeInUs` (default `0`, feature inactive to avoid transient chopping on percussive sounds; set non-zero microseconds to enable)
0 commit comments