diff --git a/src/commands/run.rs b/src/commands/run.rs index 943f6c5..d2190e8 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -1,8 +1,8 @@ -use std::io::Read; +use std::{io::Read, sync::{Arc, Mutex}}; -use cpal::{traits::{DeviceTrait, HostTrait}, Device}; +use cpal::{traits::{DeviceTrait, HostTrait, StreamTrait}, Device}; -use crate::args::Run; +use crate::{args::Run, device::virtual_device}; pub fn run(run: Run) { let config = std::path::Path::new(&run.config); @@ -32,19 +32,19 @@ pub fn run(run: Run) { let mut virtual_devices = Vec::new(); for virtual_device in config.virtual_devices { let device = crate::device::virtual_device::VirtualDevice::new(virtual_device.name, virtual_device.channels, virtual_device.sample_rate); - virtual_devices.push(device); + virtual_devices.push(Arc::new(Mutex::new(device))); } - for input_route in config.routes.input { + for input_route in &config.routes.input { println!("Input: {}", input_route.name); println!(" Virtual device: {}", input_route.virtual_device); - if virtual_devices.iter().any(|device| device.name == input_route.virtual_device) { + if virtual_devices.iter().any(|device| device.lock().unwrap().name == input_route.virtual_device) { println!(" Found"); } else { println!(" Not found"); } - match input_route.device { + match &input_route.device { crate::config::Device::Local { local } => { println!(" Local device: {}", local.name); if input_devices @@ -66,16 +66,16 @@ pub fn run(run: Run) { } } - for output_route in config.routes.output { + for output_route in &config.routes.output { println!("Output: {}", output_route.name); println!(" Virtual device: {}", output_route.input.virtual_device); - if virtual_devices.iter().any(|device| device.name == output_route.input.virtual_device) { + if virtual_devices.iter().any(|device| device.lock().unwrap().name == output_route.input.virtual_device) { println!(" Found"); } else { println!(" Not found"); } - match output_route.device { + match &output_route.device { crate::config::Device::Local { local } => { println!(" Local device: {}", local.name); if output_devices @@ -96,4 +96,38 @@ pub fn run(run: Run) { } } } + + // attach real device to virtual device + for input_route in &config.routes.input { + match &input_route.device { + crate::config::Device::Local { local } => { + let device = input_devices + .iter() + .find(|device| device.name().unwrap() == local.name) + .unwrap(); + let config = device.default_input_config().unwrap(); + let channels = config.channels(); + let virtual_devices = virtual_devices.iter().filter(|device| device.lock().unwrap().name == input_route.virtual_device).map(|d| d.clone()).collect::>(); + let mut stream = device.build_input_stream( + &config.into(), + { + move |data, _| { + for (i, buffer) in data.chunks(channels as usize).enumerate() { + let buffer = buffer.to_vec(); + for virtual_device in &virtual_devices { + virtual_device.lock().unwrap().write_input(i as u8, buffer.clone()); + } + } + } + }, + move |err| eprintln!("An error occurred on the input stream: {}", err), + None + ).unwrap(); + stream.play().unwrap(); + } + crate::config::Device::Remote { remote } => { + unimplemented!(); + } + } + } } diff --git a/src/device/virtual_device.rs b/src/device/virtual_device.rs index 550befe..82e4e82 100644 --- a/src/device/virtual_device.rs +++ b/src/device/virtual_device.rs @@ -3,7 +3,7 @@ pub struct VirtualDevice { pub channels: u8, pub sample_rate: u32, output_index: Vec, - output_buffer: Vec>, + output_buffer: Vec>, } impl VirtualDevice { @@ -27,7 +27,7 @@ impl VirtualDevice { self.output_index.len() - 1 } - pub fn take_output(&mut self, index: usize, channel: u8, take_size: usize) -> Option> { + pub fn take_output(&mut self, index: usize, channel: u8, take_size: usize) -> Option> { let mut buffer = Vec::with_capacity(take_size); let start = self.output_index[index]; let end = start + take_size; @@ -54,7 +54,7 @@ impl VirtualDevice { Some(buffer) } - pub fn write_input(&mut self, channel: u8, buffer: Vec) { + pub fn write_input(&mut self, channel: u8, buffer: Vec) { self.output_buffer[channel as usize].extend(buffer); } } \ No newline at end of file