Skip to content

feat: Inline MIDI processing with expression and tuning CCs#111

Merged
nathansbradshaw merged 11 commits into
mainfrom
feat-midi-settings
Jul 17, 2026
Merged

feat: Inline MIDI processing with expression and tuning CCs#111
nathansbradshaw merged 11 commits into
mainfrom
feat-midi-settings

Conversation

@nathansbradshaw

Copy link
Copy Markdown
Contributor

Replace deferred batch MIDI task with inline event processing in audio_handler. MIDI events are now handled on every audio DMA completion (every 256 samples), eliminating scheduling overhead and ensuring reliable delivery.

Add support for:

  • CC7 (main volume, 0-127 → 0-10 range)
  • CC11 (expression, multiplies with volume)
  • Program Change (waveform selection)
  • CCs 36-43 (tuning parameters: bit rate, sample rate, formant, autotune, magnitude)

Add waveform compensation (1.4× sine, 1.2× triangle, 1.0× square/saw) so waveform choice doesn't affect perceived volume. Applied pre-limiter to prevent DAC clipping.

Replace deferred batch MIDI task with inline event processing in audio_handler. MIDI events are now handled on every audio DMA completion (every 256 samples), eliminating scheduling overhead and ensuring reliable delivery.

Add support for:
- CC7 (main volume, 0-127 → 0-10 range)
- CC11 (expression, multiplies with volume)
- Program Change (waveform selection)
- CCs 36-43 (tuning parameters: bit rate, sample rate, formant, autotune, magnitude)

Add waveform compensation (1.4× sine, 1.2× triangle, 1.0× square/saw) so waveform choice doesn't affect perceived volume. Applied pre-limiter to prevent DAC clipping.
Comment thread src/state_machine/mod.rs Outdated
/// Sets expression from an incoming MIDI CC11 value (0-127). Multiplies with
/// `volume` for final output gain — see `handler::audio_handler`.
pub fn set_expression_from_midi(&mut self, value: u8) {
self.expression = value as i8;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does the expression do? if it is just volume lets skip

Comment thread src/state_machine/mod.rs
/// waveform.
pub fn set_waveform_from_midi(&mut self, channel: u8, program: u8) {
if channel == 9 || program > 2 {
return;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignoring is fine for the channel but I think we should be mod wrapping for the programs over 2

Comment thread src/handler.rs Outdated
}
36..=43 => {
shared.app_state_machine.lock(|msm| {
msm.set_tuning_from_cc(controller, value);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this, and why is it multiple? Let's just ignore the ccs we do not have. We should have one to cycle the musical key

@nathansbradshaw
nathansbradshaw merged commit fea59a4 into main Jul 17, 2026
3 checks passed
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