cpal icon indicating copy to clipboard operation
cpal copied to clipboard

Slow enumeration of output devices on Windows

Open adrian17 opened this issue 1 year ago • 2 comments

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.

adrian17 avatar Mar 19 '24 18:03 adrian17

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.

j-n-f avatar Jul 03 '24 02:07 j-n-f

I think the problem is that when asking for input or output devices (but not when calling just host.devices()) it enumerates all formats that the devices support to check if it's an input or output device. This should be a quite simple optimization.

jesnor avatar Oct 15 '24 11:10 jesnor