Pattern mute and so on

This commit is contained in:
2026-02-02 16:27:11 +01:00
parent 7c14ce7634
commit 39ca7de169
29 changed files with 518 additions and 58 deletions

View File

@@ -115,6 +115,10 @@ pub enum SeqCommand {
pattern: usize,
quantization: LaunchQuantization,
},
SetMuteState {
muted: std::collections::HashSet<(usize, usize)>,
soloed: std::collections::HashSet<(usize, usize)>,
},
StopAll,
Shutdown,
}
@@ -551,6 +555,8 @@ pub(crate) struct SequencerState {
buf_audio_commands: Vec<TimestampedCommand>,
cc_access: Option<Arc<dyn CcAccess>>,
active_notes: HashMap<(u8, u8, u8), ActiveNote>,
muted: std::collections::HashSet<(usize, usize)>,
soloed: std::collections::HashSet<(usize, usize)>,
}
impl SequencerState {
@@ -575,9 +581,22 @@ impl SequencerState {
buf_audio_commands: Vec::new(),
cc_access,
active_notes: HashMap::new(),
muted: std::collections::HashSet::new(),
soloed: std::collections::HashSet::new(),
}
}
fn is_effectively_muted(&self, bank: usize, pattern: usize) -> bool {
let key = (bank, pattern);
if self.muted.contains(&key) {
return true;
}
if !self.soloed.is_empty() && !self.soloed.contains(&key) {
return true;
}
false
}
fn process_commands(&mut self, commands: Vec<SeqCommand>) {
for cmd in commands {
match cmd {
@@ -619,6 +638,28 @@ impl SequencerState {
});
}
}
SeqCommand::SetMuteState { muted, soloed } => {
let newly_muted: Vec<(usize, usize)> = self
.audio_state
.active_patterns
.keys()
.filter(|id| {
let key = (id.bank, id.pattern);
let was_muted = self.is_effectively_muted(id.bank, id.pattern);
let now_muted = muted.contains(&key)
|| (!soloed.is_empty() && !soloed.contains(&key));
!was_muted && now_muted
})
.map(|id| (id.bank, id.pattern))
.collect();
self.muted = muted;
self.soloed = soloed;
if !newly_muted.is_empty() {
self.audio_state.flush_midi_notes = true;
}
}
SeqCommand::StopAll => {
self.audio_state.active_patterns.clear();
self.audio_state.pending_starts.clear();
@@ -783,6 +824,9 @@ impl SequencerState {
}
}
let muted_snapshot = self.muted.clone();
let soloed_snapshot = self.soloed.clone();
for (_id, active) in self.audio_state.active_patterns.iter_mut() {
let Some(pattern) = self.pattern_cache.get(active.bank, active.pattern) else {
continue;
@@ -807,6 +851,10 @@ impl SequencerState {
.unwrap_or(false);
if step.active && has_script {
let key = (active.bank, active.pattern);
let is_muted = muted_snapshot.contains(&key)
|| (!soloed_snapshot.is_empty() && !soloed_snapshot.contains(&key));
let source_idx = pattern.resolve_source(step_idx);
let runs = self.runs_counter.get_and_increment(
active.bank,
@@ -845,18 +893,20 @@ impl SequencerState {
std::mem::take(&mut trace),
);
let event_time = if lookahead_secs > 0.0 {
Some(engine_time + lookahead_secs)
} else {
None
};
if !is_muted {
let event_time = if lookahead_secs > 0.0 {
Some(engine_time + lookahead_secs)
} else {
None
};
for cmd in cmds {
self.event_count += 1;
self.buf_audio_commands.push(TimestampedCommand {
cmd,
time: event_time,
});
for cmd in cmds {
self.event_count += 1;
self.buf_audio_commands.push(TimestampedCommand {
cmd,
time: event_time,
});
}
}
}
}