RustAudio / cpal

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

Extremely distorted audio on Windows with Razer 7.1 Surround Sound #892

Open nigrodev opened 5 months ago

nigrodev commented 5 months ago

All crates that depend on cpal, such as rodio or kira have their audio distorted when I'm using the 7.1 Surround Sound audio output device on Windows.

This has been happening for a long time, but I only started testing it now. All the games that use the Bevy Engine (which currently uses cpal for audio) have this "distorted effect" for me.

The distortion only happens when I'm using the 7.1 audio output device, when I use the normal one (High Definition Audio Device) the audio plays normally.

image

And turning off surround audio in Razer's software doesn't make any difference to the noise. The problem is using the audio output device.

image

I used the following code and recorded the audio with Audacity. The recording is exactly what I hear.

let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let file = BufReader::new(File::open("Portal2-3x26_Still_Alive_Radio Mix_Clean.mp3").unwrap());
let source = Decoder::new(file).unwrap();
stream_handle.play_raw(source.convert_samples()).unwrap();

thread::sleep(Duration::from_millis(10000));

Inside the ZIP file is the normal and distorted mp3 audios. The only difference between the two is that I used different output devices (the distorted audio is from the 7.1 device): Download the audios here!

watsom27 commented 2 months ago

I know this issue has been open for a while, but I have been having similar crackling/bad sound issues on windows in my current project.

I am not sure how much of the code you are able to tweak, but i have found that my windows machine defaults to using the u8 sample format, whereas my MacOs device defaults to f32 and does not suffer from the same issues.

I wrote a small hack to print out what formats were available on my Windows machine and got the following:

for config in device.supported_output_configs().unwrap() {
    println!("Config: {}", config.sample_format());
}
Config: u8
Config: i16
Config: i32
Config: f32

After forcing cpal to use the f32 sample format with another hack, the issues seemed to go away.

let config = device.supported_output_configs().unwrap().find(|config| config.sample_format().is_float()).unwrap().with_max_sample_rate();

I am wondering if there just isn't enough precision in the u8 sample format for good quality audio?

All of this is just speculation, however, I wonder if prioritising the highest precision format might be beneficial?

nigrodev commented 2 months ago

For my specific case using “7.1 surround audio” in Windows, the f32 sample format is already the default.

I looked into it further and discovered that the i32 sample format is the one that works. Using this format the audio works as expected, but not with the default (f32). I have no idea why this happens.

watsom27 commented 2 months ago

How strange