don't die after playing 1st sample

This commit is contained in:
🪞👃🪞 2024-06-29 23:05:50 +03:00
parent 1672cbfc68
commit 2b4f28ae36

View file

@ -5,13 +5,19 @@ pub struct Voice {
position: usize, position: usize,
} }
impl Voice { impl Voice {
fn chunk (&mut self, frames: usize) -> Vec<Vec<f32>> { fn chunk (&mut self, frames: usize) -> Option<Vec<Vec<f32>>> {
let mut chunk = vec![]; let mut chunk = vec![];
for channel in self.sample.channels.iter() { if self.position < self.sample.end {
chunk.push(channel[self.position..self.position+frames].into()); let start = self.position.min(self.sample.end);
}; let end = (self.position + frames).min(self.sample.end);
self.position = self.position + frames; for channel in self.sample.channels.iter() {
chunk chunk.push(channel[start..end].into());
};
self.position = self.position + frames;
Some(chunk)
} else {
None
}
} }
} }
@ -68,14 +74,23 @@ impl Sampler {
let channel_count = self.audio_outs.len(); let channel_count = self.audio_outs.len();
let mut mixed = vec![vec![0.0;scope.n_frames() as usize];channel_count]; let mut mixed = vec![vec![0.0;scope.n_frames() as usize];channel_count];
// emit currently playing voices // Emit next chunk of each currently playing voice,
for voice in self.voices.iter_mut() { // removing voices that have completed playing.
let chunk = voice.chunk(scope.n_frames() as usize); let mut voices = vec![];
for (i, channel) in chunk.iter().enumerate() { std::mem::swap(&mut voices, &mut self.voices);
let buffer = &mut mixed[i % channel_count]; loop {
for (i, sample) in channel.iter().enumerate() { if voices.len() < 1 {
buffer[i] += sample; break
}
let mut voice = voices.swap_remove(0);
if let Some(chunk) = voice.chunk(scope.n_frames() as usize) {
for (i, channel) in chunk.iter().enumerate() {
let buffer = &mut mixed[i % channel_count];
for (i, sample) in channel.iter().enumerate() {
buffer[i] += sample;
}
} }
self.voices.push(voice);
} }
} }
for (i, port) in self.audio_outs.iter_mut().enumerate() { for (i, port) in self.audio_outs.iter_mut().enumerate() {