Open the-drunk-coder opened 1 year ago
Seems like it must be a quirk of the ASIO API; the cpal ASIO host doesn't seem to have any spooky global state.
Hmm seems to have to do more with the device state rather than the driver state (if that's the correct terminology?).
This variant works:
use std::thread;
use anyhow;
use cpal::{
traits::{DeviceTrait, HostTrait},
};
fn main() -> anyhow::Result<()> {
let asio = asio_sys::Asio::new();
for name in asio.driver_names() {
println!("MAIN THREAD - found {}", name);
}
let handler = thread::spawn(move || {
let spawned_thread_host = cpal::host_from_id(cpal::HostId::Asio).unwrap();
if let Ok(devices) = spawned_thread_host.output_devices() {
let mut dev_count = 0;
for dev in devices {
dev_count += 1;
println!("SPAWNED THREAD - found device {}", dev.name().unwrap());
}
println!("SPAWNED THREAD - found {dev_count} devices");
} else {
println!("SPAWNED THREAD - can't find devices");
}
});
handler.join().unwrap();
Ok(())
}
So as a workaround, you can get the available device names from asio directly (not wrapped in a cpal host/device), and then pick the device in a different thread ...
Here's an interesting example (assuming Windows 11 + ASIO4ALLv2 as a platform):
I'd expect (as this doesn't seem to be a problem at all with other hosts) that both the main thread and the spawned thread can access the list of devices.
Turns out, this isn't the case. A list of devices is returned, but it's empty. If I comment out the statements in the main thread, the spawned thread can find all devices without problems.
Within the same thread, I can access the list of devices as often as I want.
I can't really explain this ... does anyone have a hint?
Best, N