Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No sound when unplugging and plugging audio device back in #271

Open
Raz-Hemo opened this issue Feb 28, 2020 · 2 comments
Open

No sound when unplugging and plugging audio device back in #271

Raz-Hemo opened this issue Feb 28, 2020 · 2 comments

Comments

@Raz-Hemo
Copy link

Say I unplug my headphones and plug them in again. What happens to me right now is that even after the replug, I have no audio output (from play_raw()).
I tried calling default_output_device() again but the problem persists - the function returns Some(Device), but calling play_raw() on it plays no sound.
Restarting my app works, though.

@forbjok
Copy link

forbjok commented May 29, 2021

Same issue. As far as I can tell the issue is that OutputStream ties itself to a specific physical device at the time of creation. This means that if the specific device it is tied to gets disconnected, it will stop working, and also that if you change the default output device at a later time, it will ignore the change and keep playing audio on the old device.

@Rodrigodd
Copy link

Rodrigodd commented Jun 5, 2022

I was looking at Rodio for reference in how it handle device disconnection (to use on my code), but it does not handle it. The relevant code:

rodio/src/stream.rs

Lines 198 to 230 in 0356d81

let error_callback = |err| eprintln!("an error occurred on output stream: {}", err);
match format.sample_format() {
cpal::SampleFormat::F32 => self.build_output_stream::<f32, _, _>(
&format.config(),
move |data, _| {
data.iter_mut()
.for_each(|d| *d = mixer_rx.next().unwrap_or(0f32))
},
error_callback,
),
cpal::SampleFormat::I16 => self.build_output_stream::<i16, _, _>(
&format.config(),
move |data, _| {
data.iter_mut()
.for_each(|d| *d = mixer_rx.next().map(|s| s.to_i16()).unwrap_or(0i16))
},
error_callback,
),
cpal::SampleFormat::U16 => self.build_output_stream::<u16, _, _>(
&format.config(),
move |data, _| {
data.iter_mut().for_each(|d| {
*d = mixer_rx
.next()
.map(|s| s.to_u16())
.unwrap_or(u16::max_value() / 2)
})
},
error_callback,
),
}
.map(|stream| (mixer_tx, stream))

The tricky part is that the previous Stream needs to be dropped and a new one created, but Stream is not Send so there is no way to do that in the error_callback (the callback must be Send). In my code I will probably need to handle the cpal state in another thread, and handle the error there by messaging, but this would not work for WebAssembly...

Edit: looking at kira, it does pretty much exactly what I describe, and doesn't handle device disconnection in WebAssembly (it may not even be necessary, on second thought).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants