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,
}
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![];
for channel in self.sample.channels.iter() {
chunk.push(channel[self.position..self.position+frames].into());
};
self.position = self.position + frames;
chunk
if self.position < self.sample.end {
let start = self.position.min(self.sample.end);
let end = (self.position + frames).min(self.sample.end);
for channel in self.sample.channels.iter() {
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 mut mixed = vec![vec![0.0;scope.n_frames() as usize];channel_count];
// emit currently playing voices
for voice in self.voices.iter_mut() {
let 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;
// Emit next chunk of each currently playing voice,
// removing voices that have completed playing.
let mut voices = vec![];
std::mem::swap(&mut voices, &mut self.voices);
loop {
if voices.len() < 1 {
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() {