WIP: clap

This commit is contained in:
2026-02-20 22:14:21 +01:00
parent 12752e0167
commit 00d6eb2f1f
76 changed files with 9103 additions and 143 deletions

View File

@@ -9,10 +9,14 @@ pub use timing::{substeps_in_window, StepTiming, SyncTime};
// AnalysisHandle and SequencerHandle are used by src/bin/desktop.rs
#[allow(unused_imports)]
pub use audio::{build_stream, AnalysisHandle, AudioStreamConfig, ScopeBuffer, SpectrumBuffer};
pub use audio::{
build_stream, spawn_analysis_thread, AnalysisHandle, AudioStreamConfig, ScopeBuffer,
SpectrumBuffer,
};
pub use link::LinkState;
#[allow(unused_imports)]
pub use sequencer::{
spawn_sequencer, AudioCommand, MidiCommand, PatternChange, PatternSnapshot, SeqCommand,
SequencerConfig, SequencerHandle, SequencerSnapshot, StepSnapshot,
parse_midi_command, spawn_sequencer, AudioCommand, MidiCommand, PatternChange,
PatternSnapshot, SeqCommand, SequencerConfig, SequencerHandle, SequencerSnapshot,
SequencerState, SharedSequencerState, StepSnapshot, TickInput, TickOutput, TimestampedCommand,
};

View File

@@ -166,7 +166,26 @@ pub struct SequencerSnapshot {
pub event_count: usize,
}
impl From<&SharedSequencerState> for SequencerSnapshot {
fn from(s: &SharedSequencerState) -> Self {
Self {
active_patterns: s.active_patterns.clone(),
step_traces: Arc::clone(&s.step_traces),
event_count: s.event_count,
}
}
}
impl SequencerSnapshot {
#[allow(dead_code)]
pub fn empty() -> Self {
Self {
active_patterns: Vec::new(),
step_traces: Arc::new(HashMap::new()),
event_count: 0,
}
}
pub fn is_playing(&self, bank: usize, pattern: usize) -> bool {
self.active_patterns
.iter()
@@ -452,7 +471,7 @@ impl RunsCounter {
}
}
pub(crate) struct TickInput {
pub struct TickInput {
pub commands: Vec<SeqCommand>,
pub playing: bool,
pub beat: f64,
@@ -463,11 +482,8 @@ pub(crate) struct TickInput {
pub nudge_secs: f64,
pub current_time_us: SyncTime,
pub engine_time: f64,
#[cfg(feature = "desktop")]
pub mouse_x: f64,
#[cfg(feature = "desktop")]
pub mouse_y: f64,
#[cfg(feature = "desktop")]
pub mouse_down: f64,
}
@@ -476,7 +492,7 @@ pub struct TimestampedCommand {
pub time: Option<f64>,
}
pub(crate) struct TickOutput {
pub struct TickOutput {
pub audio_commands: Vec<TimestampedCommand>,
pub new_tempo: Option<f64>,
pub shared_state: SharedSequencerState,
@@ -528,7 +544,7 @@ fn format_chain_key(buf: &mut String, bank: usize, pattern: usize) -> &str {
buf
}
pub(crate) struct SequencerState {
pub struct SequencerState {
audio_state: AudioState,
pattern_cache: PatternCache,
pending_updates: HashMap<(usize, usize), PatternSnapshot>,
@@ -710,11 +726,8 @@ impl SequencerState {
input.nudge_secs,
input.current_time_us,
input.engine_time,
#[cfg(feature = "desktop")]
input.mouse_x,
#[cfg(feature = "desktop")]
input.mouse_y,
#[cfg(feature = "desktop")]
input.mouse_down,
);
@@ -842,9 +855,9 @@ impl SequencerState {
nudge_secs: f64,
_current_time_us: SyncTime,
engine_time: f64,
#[cfg(feature = "desktop")] mouse_x: f64,
#[cfg(feature = "desktop")] mouse_y: f64,
#[cfg(feature = "desktop")] mouse_down: f64,
mouse_x: f64,
mouse_y: f64,
mouse_down: f64,
) -> StepResult {
self.buf_audio_commands.clear();
self.buf_completed_iterations.clear();
@@ -924,11 +937,8 @@ impl SequencerState {
cc_access: self.cc_access.as_deref(),
speed_key,
chain_key,
#[cfg(feature = "desktop")]
mouse_x,
#[cfg(feature = "desktop")]
mouse_y,
#[cfg(feature = "desktop")]
mouse_down,
};
if let Some(script) = resolved_script {
@@ -1170,10 +1180,16 @@ fn sequencer_loop(
engine_time,
#[cfg(feature = "desktop")]
mouse_x: f32::from_bits(mouse_x.load(Ordering::Relaxed)) as f64,
#[cfg(not(feature = "desktop"))]
mouse_x: 0.5,
#[cfg(feature = "desktop")]
mouse_y: f32::from_bits(mouse_y.load(Ordering::Relaxed)) as f64,
#[cfg(not(feature = "desktop"))]
mouse_y: 0.5,
#[cfg(feature = "desktop")]
mouse_down: f32::from_bits(mouse_down.load(Ordering::Relaxed)) as f64,
#[cfg(not(feature = "desktop"))]
mouse_down: 0.0,
};
let output = seq_state.tick(input);
@@ -1231,7 +1247,7 @@ fn sequencer_loop(
}
}
fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>, f64)> {
pub fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>, f64)> {
if !cmd.starts_with("/midi/") {
return None;
}
@@ -1384,11 +1400,8 @@ mod tests {
nudge_secs: 0.0,
current_time_us: 0,
engine_time: 0.0,
#[cfg(feature = "desktop")]
mouse_x: 0.5,
#[cfg(feature = "desktop")]
mouse_y: 0.5,
#[cfg(feature = "desktop")]
mouse_down: 0.0,
}
}
@@ -1405,11 +1418,8 @@ mod tests {
nudge_secs: 0.0,
current_time_us: 0,
engine_time: 0.0,
#[cfg(feature = "desktop")]
mouse_x: 0.5,
#[cfg(feature = "desktop")]
mouse_y: 0.5,
#[cfg(feature = "desktop")]
mouse_down: 0.0,
}
}