RustAudio / cpal

Cross-platform audio I/O library in pure Rust
Apache License 2.0
2.62k stars 347 forks source link

Slow enumeration of output devices on Windows #867

Open adrian17 opened 5 months ago

adrian17 commented 5 months ago

Demo code:

use cpal::traits::{HostTrait, DeviceTrait};
fn main() {
    let audio_host = cpal::default_host();
    let mut t = std::time::Instant::now();
    if let Ok(devices) = audio_host.output_devices() {
        for device in devices {
            println!("{:?} {:?}", t.elapsed(), device.name());
            t = std::time::Instant::now();
        }
    }
}

Takes surprisingly slow on my machine:

108.0278ms Ok("Realtek Digital Output (Realtek(R) Audio)")
99.4321ms Ok("Realtek HD Audio 2nd output (Realtek(R) Audio)")

We query the output devices just before displaying them, which can cause a noticeable lag if there are more devices. A similar query on my linux VM takes <10ms per device.

j-n-f commented 2 months ago

Same here.

If I time from when I start interacting with cpal I can fetch the Host in less than 1ms.

It takes about 133ms from start to fetch the list of devices (host.output_devices()).

When I go to select a specific device by name and finally get it it's about 825ms from start.

I can't see anything that I could cache to try and speed things up (and then fall back on a complete scan if the usual device isn't found).

In my case < 1s is still pretty good, but what concerns me is that the lookup time scales with the number of devices (I have 3 on this host when using ASIO). @adrian17 sees about 100ms per device (guessing this is with the WASAPI driver), I'm seeing a little over 200ms with ASIO.