mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 04:06:45 +01:00
flatten midi playback logic furter
This commit is contained in:
parent
f57589e83a
commit
2492537c32
1 changed files with 39 additions and 40 deletions
|
|
@ -24,48 +24,47 @@ pub trait MidiPlaybackApi: HasPlayPhrase + HasClock + HasMidiOuts {
|
||||||
if !self.clock().is_rolling() {
|
if !self.clock().is_rolling() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
let playing = self.play_phrase();
|
// If a phrase is playing, write a chunk of MIDI events from it to the output buffer.
|
||||||
if let Some((started, phrase)) = playing {
|
// If no phrase is playing, prepare for switchover immediately.
|
||||||
// If a phrase is playing, write a chunk of MIDI events from it to the output buffer
|
self.play_phrase().as_ref().map_or(true, |(started, phrase)|{
|
||||||
let mut next = false;
|
self.play_phrase_chunk(scope, note_buf, out, started, phrase)
|
||||||
let sample0 = scope.last_frame_time() as usize;
|
})
|
||||||
let samples = scope.n_frames() as usize;
|
}
|
||||||
let started0 = &self.clock().started;
|
|
||||||
let timebase = self.clock().timebase();
|
fn play_phrase_chunk (
|
||||||
let notes_out = self.notes_out();
|
&self,
|
||||||
let next_phrase = self.next_phrase();
|
scope: &ProcessScope,
|
||||||
|
note_buf: &mut Vec<u8>,
|
||||||
|
out: &mut [Vec<Vec<u8>>],
|
||||||
|
started: &Moment,
|
||||||
|
phrase: &Option<Arc<RwLock<Phrase>>>
|
||||||
|
) -> bool {
|
||||||
// First sample to populate. Greater than 0 means that the first
|
// First sample to populate. Greater than 0 means that the first
|
||||||
// pulse of the phrase falls somewhere in the middle of the chunk.
|
// pulse of the phrase falls somewhere in the middle of the chunk.
|
||||||
let sample = started.sample.get() as usize;
|
let sample = (scope.last_frame_time() as usize).saturating_sub(
|
||||||
let sample = sample + started0.read().unwrap().as_ref().unwrap().sample.get() as usize;
|
started.sample.get() as usize +
|
||||||
let sample = sample0.saturating_sub(sample);
|
self.clock().started.read().unwrap().as_ref().unwrap().sample.get() as usize
|
||||||
|
);
|
||||||
// Iterator that emits sample (index into output buffer at which to write MIDI event)
|
// Iterator that emits sample (index into output buffer at which to write MIDI event)
|
||||||
// paired with pulse (index into phrase from which to take the MIDI event) for each
|
// paired with pulse (index into phrase from which to take the MIDI event) for each
|
||||||
// sample of the output buffer that corresponds to a MIDI pulse.
|
// sample of the output buffer that corresponds to a MIDI pulse.
|
||||||
let pulses = timebase.pulses_between_samples(sample, sample + samples);
|
let pulses = self.clock().timebase().pulses_between_samples(sample, sample + scope.n_frames() as usize);
|
||||||
// Notes active during current chunk.
|
// Notes active during current chunk.
|
||||||
let notes = &mut notes_out.write().unwrap();
|
let notes = &mut self.notes_out().write().unwrap();
|
||||||
|
let length = phrase.as_ref().map_or(0, |p|p.read().unwrap().length);
|
||||||
for (sample, pulse) in pulses {
|
for (sample, pulse) in pulses {
|
||||||
// If a next phrase is enqueued, and we're past the end of the current one,
|
// If a next phrase is enqueued, and we're past the end of the current one,
|
||||||
// break the loop here (FIXME count pulse correctly)
|
// break the loop here (FIXME count pulse correctly)
|
||||||
next = next_phrase.is_some() && if let Some(ref phrase) = phrase {
|
let past_end = if phrase.is_some() { pulse >= length } else { true };
|
||||||
pulse >= phrase.read().unwrap().length
|
if self.next_phrase().is_some() && past_end {
|
||||||
} else {
|
return true
|
||||||
true
|
|
||||||
};
|
|
||||||
if next {
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
// If there's a currently playing phrase, output notes from it to buffer:
|
// If there's a currently playing phrase, output notes from it to buffer:
|
||||||
if let Some(ref phrase) = phrase {
|
if let Some(ref phrase) = phrase {
|
||||||
Self::play_pulse(phrase, pulse, sample, note_buf, out, notes)
|
Self::play_pulse(phrase, pulse, sample, note_buf, out, notes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
next
|
false
|
||||||
} else {
|
|
||||||
// If no phrase is playing, prepare for switchover immediately
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn play_pulse (
|
fn play_pulse (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue