Pattern mute and so on
This commit is contained in:
@@ -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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user