MIDI Documentation and optional mouse event support

This commit is contained in:
2026-02-01 00:51:56 +01:00
parent 96e7fb6bc4
commit 5b4a6ddd14
14 changed files with 401 additions and 3 deletions

View File

@@ -1,6 +1,8 @@
use arc_swap::ArcSwap;
use crossbeam_channel::{bounded, Receiver, Sender, TrySendError};
use std::collections::HashMap;
#[cfg(feature = "desktop")]
use std::sync::atomic::AtomicU32;
use std::sync::atomic::{AtomicI64, AtomicU64};
use std::sync::Arc;
use std::thread::{self, JoinHandle};
@@ -232,6 +234,12 @@ pub struct SequencerConfig {
pub sample_rate: Arc<std::sync::atomic::AtomicU32>,
pub lookahead_ms: Arc<std::sync::atomic::AtomicU32>,
pub cc_memory: Option<CcMemory>,
#[cfg(feature = "desktop")]
pub mouse_x: Arc<AtomicU32>,
#[cfg(feature = "desktop")]
pub mouse_y: Arc<AtomicU32>,
#[cfg(feature = "desktop")]
pub mouse_down: Arc<AtomicU32>,
}
#[allow(clippy::too_many_arguments)]
@@ -257,6 +265,13 @@ pub fn spawn_sequencer(
let audio_tx_for_thread = Arc::clone(&audio_tx);
let midi_tx_for_thread = Arc::clone(&midi_tx);
#[cfg(feature = "desktop")]
let mouse_x = config.mouse_x;
#[cfg(feature = "desktop")]
let mouse_y = config.mouse_y;
#[cfg(feature = "desktop")]
let mouse_down = config.mouse_down;
let thread = thread::Builder::new()
.name("sequencer".into())
.spawn(move || {
@@ -277,6 +292,12 @@ pub fn spawn_sequencer(
config.sample_rate,
config.lookahead_ms,
config.cc_memory,
#[cfg(feature = "desktop")]
mouse_x,
#[cfg(feature = "desktop")]
mouse_y,
#[cfg(feature = "desktop")]
mouse_down,
);
})
.expect("Failed to spawn sequencer thread");
@@ -407,6 +428,12 @@ pub(crate) struct TickInput {
pub current_time_us: i64,
pub engine_time: f64,
pub lookahead_secs: f64,
#[cfg(feature = "desktop")]
pub mouse_x: f64,
#[cfg(feature = "desktop")]
pub mouse_y: f64,
#[cfg(feature = "desktop")]
pub mouse_down: f64,
}
pub struct TimestampedCommand {
@@ -591,6 +618,12 @@ impl SequencerState {
input.current_time_us,
input.engine_time,
input.lookahead_secs,
#[cfg(feature = "desktop")]
input.mouse_x,
#[cfg(feature = "desktop")]
input.mouse_y,
#[cfg(feature = "desktop")]
input.mouse_down,
);
let vars = self.read_variables(&steps.completed_iterations, &stopped, steps.any_step_fired);
@@ -684,6 +717,9 @@ impl SequencerState {
_current_time_us: i64,
engine_time: f64,
lookahead_secs: f64,
#[cfg(feature = "desktop")] mouse_x: f64,
#[cfg(feature = "desktop")] mouse_y: f64,
#[cfg(feature = "desktop")] mouse_down: f64,
) -> StepResult {
self.buf_audio_commands.clear();
let mut result = StepResult {
@@ -746,6 +782,12 @@ impl SequencerState {
fill,
nudge_secs,
cc_memory: self.cc_memory.clone(),
#[cfg(feature = "desktop")]
mouse_x,
#[cfg(feature = "desktop")]
mouse_y,
#[cfg(feature = "desktop")]
mouse_down,
};
if let Some(script) = resolved_script {
let mut trace = ExecutionTrace::default();
@@ -902,6 +944,9 @@ fn sequencer_loop(
sample_rate: Arc<std::sync::atomic::AtomicU32>,
lookahead_ms: Arc<std::sync::atomic::AtomicU32>,
cc_memory: Option<CcMemory>,
#[cfg(feature = "desktop")] mouse_x: Arc<AtomicU32>,
#[cfg(feature = "desktop")] mouse_y: Arc<AtomicU32>,
#[cfg(feature = "desktop")] mouse_down: Arc<AtomicU32>,
) {
use std::sync::atomic::Ordering;
@@ -943,6 +988,12 @@ fn sequencer_loop(
current_time_us,
engine_time,
lookahead_secs,
#[cfg(feature = "desktop")]
mouse_x: f32::from_bits(mouse_x.load(Ordering::Relaxed)) as f64,
#[cfg(feature = "desktop")]
mouse_y: f32::from_bits(mouse_y.load(Ordering::Relaxed)) as f64,
#[cfg(feature = "desktop")]
mouse_down: f32::from_bits(mouse_down.load(Ordering::Relaxed)) as f64,
};
let output = seq_state.tick(input);
@@ -1141,6 +1192,12 @@ mod tests {
current_time_us: 0,
engine_time: 0.0,
lookahead_secs: 0.0,
#[cfg(feature = "desktop")]
mouse_x: 0.5,
#[cfg(feature = "desktop")]
mouse_y: 0.5,
#[cfg(feature = "desktop")]
mouse_down: 0.0,
}
}
@@ -1156,6 +1213,12 @@ mod tests {
current_time_us: 0,
engine_time: 0.0,
lookahead_secs: 0.0,
#[cfg(feature = "desktop")]
mouse_x: 0.5,
#[cfg(feature = "desktop")]
mouse_y: 0.5,
#[cfg(feature = "desktop")]
mouse_down: 0.0,
}
}