Files
maudio-router/src/device/virtual_device.rs

97 lines
3.1 KiB
Rust

use std::collections::HashMap;
use crate::audio::resampling::resampling;
pub struct VirtualDevice {
pub name: String,
pub channels: u8,
pub sample_rate: u32,
output_index: HashMap<u32, Vec<usize>>,
output_buffer: HashMap<u32, Vec<Vec<f32>>>,
}
impl VirtualDevice {
pub fn new(name: String, channels: u8, sample_rate: u32) -> Self {
VirtualDevice {
name,
channels,
sample_rate,
output_index: HashMap::new(),
output_buffer: HashMap::new(),
}
}
#[inline]
fn get_min_index(&self, sample_rate: u32) -> usize {
*self.output_index[&sample_rate].iter().min().unwrap_or(&0)
}
pub fn add_output(&mut self, sample_rate: u32) -> usize {
if let std::collections::hash_map::Entry::Vacant(e) = self.output_index.entry(sample_rate) {
e.insert(Vec::new());
self.output_buffer
.insert(sample_rate, vec![vec![]; self.channels as usize]);
}
let min_index = self.get_min_index(sample_rate);
self.output_index
.get_mut(&sample_rate)
.unwrap()
.push(min_index);
self.output_index[&sample_rate].len() - 1
}
pub fn take_output(
&mut self,
index: usize,
channels: u8,
sample_rate: u32,
take_size: usize,
) -> Option<Vec<Vec<f32>>> {
let mut buffer = vec![Vec::with_capacity(take_size); channels as usize];
let start = self.output_index[&sample_rate][index];
let end = start + take_size;
for channel in 0..channels {
if end >= self.output_buffer[&sample_rate][channel as usize].len() {
println!(
"End of buffer: {}, {}[{}]",
end,
self.output_buffer[&sample_rate][channel as usize].len(),
channel as usize
);
return None;
}
}
for i in start..end {
for channel in 0..channels {
buffer[channel as usize]
.push(self.output_buffer[&sample_rate][channel as usize][i]);
}
}
self.output_index.get_mut(&sample_rate).unwrap()[index] = end;
let min = self.get_min_index(sample_rate);
if min != 0 {
for i in 0..self.channels as usize {
let len = self.output_buffer[&sample_rate][i].len();
self.output_buffer.get_mut(&sample_rate).unwrap()[i]
.drain(0..(if len < min { len } else { min }));
}
for i in 0..self.output_index.len() {
self.output_index.get_mut(&sample_rate).unwrap()[i] -= min;
}
}
Some(buffer)
}
pub fn write_input_multiple_channels(&mut self, input_buffer: &[Vec<f32>]) {
for (sample_rate, buffer) in self.output_buffer.iter_mut() {
let buffer_resample = resampling(self.sample_rate, *sample_rate, input_buffer.to_vec());
(0..self.channels as usize).for_each(|i| buffer[i].extend(buffer_resample[i].iter()));
}
}
}