mirror of
https://github.com/mii443/maudio-router.git
synced 2025-08-22 16:05:35 +00:00
Virtual device works! but why?
This commit is contained in:
@ -6,7 +6,7 @@ use std::{
|
||||
|
||||
use cpal::{
|
||||
traits::{DeviceTrait, HostTrait, StreamTrait},
|
||||
Device,
|
||||
Device, Stream, StreamConfig, SupportedStreamConfig,
|
||||
};
|
||||
|
||||
use crate::{args::Run, device::virtual_device::VirtualDevice};
|
||||
@ -239,7 +239,7 @@ pub fn run(run: Run) {
|
||||
}
|
||||
}
|
||||
|
||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||
let mut threads = vec![];
|
||||
|
||||
for output_route in &config.routes.output {
|
||||
match &output_route.device {
|
||||
@ -250,7 +250,6 @@ pub fn run(run: Run) {
|
||||
.unwrap();
|
||||
let config = device.default_output_config().unwrap();
|
||||
|
||||
let channels = config.channels();
|
||||
let sample_rate = config.sample_rate().0;
|
||||
|
||||
let virtual_device = virtual_devices
|
||||
@ -261,82 +260,23 @@ pub fn run(run: Run) {
|
||||
.cloned()
|
||||
.collect::<Vec<_>>()[0]
|
||||
.clone();
|
||||
let index = virtual_device.lock().unwrap().add_output(sample_rate);
|
||||
|
||||
let stream = match config.sample_format() {
|
||||
cpal::SampleFormat::I8 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [i8], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
cpal::SampleFormat::I16 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [i16], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
cpal::SampleFormat::I32 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [i32], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
cpal::SampleFormat::F32 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [f32], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
sample_format => {
|
||||
eprintln!("Unsupported sample format: {:?}", sample_format);
|
||||
return;
|
||||
let thread = std::thread::spawn({
|
||||
let device = device.clone();
|
||||
move || {
|
||||
let stream = create_virtual_device_input_stream(
|
||||
config,
|
||||
device.clone(),
|
||||
virtual_device,
|
||||
);
|
||||
stream.play().unwrap();
|
||||
loop {
|
||||
std::thread::sleep(std::time::Duration::from_secs(1000));
|
||||
}
|
||||
}
|
||||
}
|
||||
.unwrap();
|
||||
});
|
||||
|
||||
stream.play().unwrap();
|
||||
streams.push(stream);
|
||||
threads.push(thread);
|
||||
}
|
||||
crate::config::Device::Remote { remote } => {
|
||||
unimplemented!();
|
||||
@ -349,6 +289,87 @@ pub fn run(run: Run) {
|
||||
}
|
||||
}
|
||||
|
||||
fn create_virtual_device_input_stream(
|
||||
config: SupportedStreamConfig,
|
||||
device: Device,
|
||||
virtual_device: Arc<Mutex<VirtualDevice>>,
|
||||
) -> Stream {
|
||||
let sample_rate = config.sample_rate().0;
|
||||
let channels = config.channels();
|
||||
let index = virtual_device.lock().unwrap().add_output(sample_rate);
|
||||
|
||||
match config.sample_format() {
|
||||
cpal::SampleFormat::I8 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [i8], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
cpal::SampleFormat::I16 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [i16], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
cpal::SampleFormat::I32 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [i32], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
cpal::SampleFormat::F32 => device.build_output_stream(
|
||||
&config.into(),
|
||||
{
|
||||
move |data: &mut [f32], _| {
|
||||
output_callback(
|
||||
data,
|
||||
channels.into(),
|
||||
sample_rate,
|
||||
virtual_device.clone(),
|
||||
index,
|
||||
)
|
||||
}
|
||||
},
|
||||
move |err| eprintln!("An error occurred on the output stream: {}", err),
|
||||
None,
|
||||
),
|
||||
sample_format => {
|
||||
panic!("Unsupported sample format: {:?}", sample_format);
|
||||
}
|
||||
}
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
fn input_callback<T>(
|
||||
data: &[T],
|
||||
channels: usize,
|
||||
@ -376,12 +397,23 @@ fn output_callback<T>(
|
||||
{
|
||||
let mut virtual_device = virtual_device.lock().unwrap();
|
||||
let vd_channels = virtual_device.channels;
|
||||
let audio_data = virtual_device.take_output(
|
||||
let mut audio_data = virtual_device.take_output(
|
||||
index,
|
||||
min(channels as u8, vd_channels),
|
||||
sample_rate,
|
||||
data.len() / channels,
|
||||
);
|
||||
let mut count = 0;
|
||||
while audio_data.is_none() && count < 1 {
|
||||
audio_data = virtual_device.take_output(
|
||||
index,
|
||||
min(channels as u8, vd_channels),
|
||||
sample_rate,
|
||||
data.len() / channels,
|
||||
);
|
||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
||||
count += 1;
|
||||
}
|
||||
if audio_data.is_none() {
|
||||
println!("audio_data is none");
|
||||
return;
|
||||
|
Reference in New Issue
Block a user