in src/backend/buffer_manager.rs [266:322]
fn pull_data(&mut self, data: *mut c_void, needed_samples: usize) {
assert_eq!(needed_samples % self.output_channel_count(), 0);
let needed_frames = needed_samples / self.output_channel_count();
let to_pull = needed_frames * self.stored_channel_count();
match &mut self.consumer {
IntegerRingBufferConsumer(p) => {
let input: &mut [i16] =
unsafe { slice::from_raw_parts_mut::<i16>(data as *mut i16, needed_samples) };
let pulled = p.pop_slice(input);
if pulled < to_pull {
cubeb_alog!(
"Underrun during input data pull: (needed: {}, available: {})",
to_pull,
pulled
);
for i in 0..(to_pull - pulled) {
input[pulled + i] = 0;
}
}
if needed_samples > to_pull {
// Mono upmix. This can happen with voice processing.
let mut write_idx = needed_samples;
for read_idx in (0..to_pull).rev() {
write_idx -= self.output_channel_count();
for offset in 0..self.output_channel_count() {
input[write_idx + offset] = input[read_idx];
}
}
}
}
FloatRingBufferConsumer(p) => {
let input: &mut [f32] =
unsafe { slice::from_raw_parts_mut::<f32>(data as *mut f32, needed_samples) };
let pulled = p.pop_slice(input);
if pulled < to_pull {
cubeb_alog!(
"Underrun during input data pull: (needed: {}, available: {})",
to_pull,
pulled
);
for i in 0..(to_pull - pulled) {
input[pulled + i] = 0.0;
}
}
if needed_samples > to_pull {
// Mono upmix. This can happen with voice processing.
let mut write_idx = needed_samples;
for read_idx in (0..to_pull).rev() {
write_idx -= self.output_channel_count();
for offset in 0..self.output_channel_count() {
input[write_idx + offset] = input[read_idx];
}
}
}
}
}
}