Skip to content

Conversation

@ArthurGibert
Copy link
Contributor

@ArthurGibert ArthurGibert commented Jan 6, 2026

Add param to change button behavior.

@chmanie chmanie force-pushed the feat/control-improvements branch from e78ea04 to 1da86f1 Compare January 6, 2026 20:08
@coderabbitai
Copy link

coderabbitai bot commented Jan 6, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Expanded button configuration options: select button mode (Mute, CC toggle, or CC momentary), assign MIDI channel, and configure MIDI CC value.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

The control application extended its parameter configuration from 9 to 12 parameters by adding button-specific settings: button mode, MIDI channel, and MIDI CC. Runtime execution now includes conditional muted behavior based on button mode, a new button release handler task, and updated serialization paths to accommodate the new fields.

Changes

Cohort / File(s) Summary
Parameter Expansion & Serialization
faderpunk/src/apps/control.rs
Extended PARAMS constant from 9 to 12. Added Params struct fields: button_mode (usize), button_ch (MidiChannel), button_cc (MidiCc). Updated from_values and to_values methods to handle new fields. Extended CONFIG with three new parameters: Button mode (enum: ["Mute", "CC toggle", "CC momentary"]), Button Channel, and Button CC.
Runtime Control Flow & Button Handling
faderpunk/src/apps/control.rs
Introduced three-mode button behavior (mode 0: default/mute, mode 1: CC toggle, mode 2: CC momentary). Added rev_button_handler task for button release events. Muted behavior now conditional on button_mode. Button handler extended to support mode-specific LED and MIDI CC actions. Main loop updated to join5 concurrent tasks instead of join4.

Sequence Diagram

sequenceDiagram
    participant User as User<br/>(Button)
    participant Handler as Button Handler
    participant ModeSwitch as Mode Logic
    participant LED as LED Control
    participant MIDI as MIDI Output
    participant RevHandler as Button Release<br/>Handler

    User->>Handler: Button Press
    Handler->>ModeSwitch: Check button_mode
    
    alt Mode 0: Mute
        ModeSwitch->>Handler: Use default behavior
        Handler->>LED: Toggle LED
    else Mode 1: CC Toggle
        ModeSwitch->>Handler: Toggle mode
        Handler->>LED: Update LED
        Handler->>MIDI: Send CC (button_ch, button_cc)
    else Mode 2: CC Momentary
        ModeSwitch->>Handler: Momentary press
        Handler->>LED: Light LED
        Handler->>MIDI: Send CC ON (button_ch, button_cc)
        Note over User,RevHandler: Button held...
        User->>RevHandler: Button Release
        RevHandler->>LED: Clear LED
        RevHandler->>MIDI: Send CC OFF (button_ch, button_cc)
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 Three button modes, a rabbit's delight,
Mute, toggle, momentary—each one just right!
With handlers hopping and LEDs aglow,
The fader control reigns supreme, don't you know? 🎚️

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The title 'Improvements to Control' is vague and generic, using non-descriptive language that doesn't convey what was specifically changed. Use a more specific title like 'Add CC button modes to control app' to clearly indicate the main change introduced in this PR.
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The description mentions adding a parameter to change button behavior and sending MIDI without interpolation, which aligns with the changeset's addition of button mode configurations and MIDI handling.
✨ Finishing touches
  • 📝 Generate docstrings

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI Agents
In @faderpunk/src/apps/control.rs:
- Around line 118-121: The deserializer now expects three new fields
(button_mode, button_ch, button_cc) before midi_out which breaks older 9-value
payloads; update the deserialization logic that processes values (the code using
values[...] to set button_mode, button_ch, button_cc, midi_out) to handle both
old and new formats by: check if values.len() == 9 then deserialize using the
old order, set button_mode, button_ch, button_cc to sensible defaults (e.g.,
default enum variants or 0) and map the old midi_out value accordingly;
otherwise when values.len() >= 12 parse the new fields as currently implemented.
Also add an optional version field or schema marker to the stored format for
future migrations and adjust the same deserialization path to prefer the
explicit version when present.
🧹 Nitpick comments (4)
faderpunk/src/apps/control.rs (4)

2-2: Remove unused join4 import.

The code now uses join5 (line 460), making the join4 import unnecessary.

🔎 Proposed cleanup
-    join::{join4, join5},
+    join::join5,

289-293: Consider clarifying muted state behavior in CC modes.

When button_mode != 0 (CC toggle/momentary modes), the muted state is forced to false for output calculations, but the button handler (lines 382-386) still toggles and persists the muted flag in storage. This creates a hidden state that only affects behavior when switching back to Mute mode.

While this may be intentional to preserve user preference, consider either:

  • Adding a comment explaining this design decision
  • Only toggling/saving muted state when button_mode == 0 to make the behavior more explicit

405-418: Consider efficiency: rev_button_handler runs even when not needed.

When button_mode != 2, this task waits for button events but performs no action (lines 413-416 are skipped). This wastes CPU cycles processing button events unnecessarily.

Consider one of these approaches:

  • Conditionally spawn rev_button_handler only when button_mode == 2
  • Use select to allow early termination when parameters change
  • Move the button_mode == 2 check before the event wait
🔎 Suggested optimization
 let rev_button_handler = async {
     loop {
+        if button_mode != 2 {
+            // Skip unnecessary event processing in non-momentary modes
+            embassy_futures::yield_now().await;
+            continue;
+        }
+
         if !on_release {
             buttons.wait_for_up(0).await;
         } else {
             buttons.wait_for_down(0).await;
         }
-
-        if button_mode == 2 {
-            leds.unset(0, Led::Button);
-            midi_button.send_cc(button_cc, 0).await;
-        }
+        leds.unset(0, Led::Button);
+        midi_button.send_cc(button_cc, 0).await;
     }
 };

Note: This assumes button_mode doesn't change at runtime. If it does, a more sophisticated approach using select would be needed.


443-454: Scene loading doesn't synchronize MIDI state in CC toggle mode.

When loading a scene with save_state enabled, the LED is updated to reflect the stored muted state (lines 448-452), but no corresponding MIDI CC message is sent. In CC toggle mode (button_mode == 1), this creates a mismatch: the LED shows the loaded state, but external MIDI devices don't receive the update.

Consider sending the appropriate CC value when loading scenes in mode 1:

🔎 Suggested fix for scene MIDI sync
                 SceneEvent::LoadSscene(scene) => {
                     storage.load_from_scene(scene).await;
                     if save_state {
                         let muted = storage.query(|s| s.muted);
                         muted_glob.set(muted);
-                        if muted {
-                            leds.unset(0, Led::Button);
-                        } else {
-                            leds.set(0, Led::Button, led_color, Brightness::Lower);
+                        if button_mode == 1 {
+                            // Sync MIDI state in CC toggle mode
+                            if muted {
+                                leds.unset(0, Led::Button);
+                                midi_button.send_cc(button_cc, 0).await;
+                            } else {
+                                leds.set(0, Led::Button, led_color, Brightness::Lower);
+                                midi_button.send_cc(button_cc, 4095).await;
+                            }
+                        } else if button_mode == 0 {
+                            // Original mute mode behavior
+                            if muted {
+                                leds.unset(0, Led::Button);
+                            } else {
+                                leds.set(0, Led::Button, led_color, Brightness::Lower);
+                            }
                         }
                     }
                 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5a83ad9 and 1da86f1.

📒 Files selected for processing (1)
  • faderpunk/src/apps/control.rs
🧰 Additional context used
🧬 Code graph analysis (1)
faderpunk/src/apps/control.rs (1)
libfp/src/lib.rs (31)
  • default (122-125)
  • default (988-990)
  • default (1010-1012)
  • default (1103-1105)
  • from (176-183)
  • from (222-238)
  • from (575-577)
  • from (581-601)
  • from (623-631)
  • from (732-734)
  • from (738-740)
  • from (744-746)
  • from (750-752)
  • from (756-758)
  • from (762-764)
  • from (768-770)
  • from (774-776)
  • from (780-782)
  • from (786-788)
  • from (792-794)
  • from_value (242-247)
  • from_value (483-488)
  • from_value (525-530)
  • from_value (605-610)
  • from_value (943-948)
  • from_value (955-960)
  • from_value (979-984)
  • from_value (1016-1021)
  • from_value (1038-1043)
  • from_value (1081-1086)
  • from_value (1094-1099)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build Firmware (Check)
🔇 Additional comments (2)
faderpunk/src/apps/control.rs (2)

387-402: LGTM: Button mode logic correctly implements toggle and momentary behaviors.

The conditional logic properly handles:

  • Mode 0/1: LED state follows the toggled muted flag
  • Mode 1: Additional CC messages sent based on state
  • Mode 2: Momentary press handled (release handled in rev_button_handler)

460-467: LGTM: Correctly updated to join5 for the additional concurrent task.

The five concurrent tasks are properly integrated:

  1. main_loop - Output calculation and LED updates
  2. button_handler - Button press/release handling
  3. rev_button_handler - Complementary button event handler for momentary mode
  4. fader_event_handler - Fader change processing
  5. scene_handler - Scene load/save operations

Copy link
Member

@chmanie chmanie left a comment

Choose a reason for hiding this comment

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

Should be great! Only one comment here

}
}
};
let rev_button_handler = async {
Copy link
Member

Choose a reason for hiding this comment

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

I would probably only initialize one of the two handlers, based on the on_release param, then you can save one future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I won't be able to do this till next week unfortunately. Feel free to edit the commit if you want.

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.

3 participants