Virtual device works! but why?

This commit is contained in:
mii443
2024-02-15 21:26:09 +09:00
parent 2a8d08a48e
commit 1949fbae94
7 changed files with 326 additions and 96 deletions

View File

@ -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;