RustAudio / rodio

Rust audio playback library
Apache License 2.0
1.68k stars 217 forks source link

ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred #290

Open OoLunar opened 4 years ago

OoLunar commented 4 years ago

I have the following function:

fn play_many() {
    let music_files = match tinyfiledialogs::open_file_dialog_multi("Choose your songs", dirs::audio_dir().unwrap().to_str().unwrap(), Some((&["*.mp3", "*.ogg", "*.wav"], "Audio Files"))) {
        Some(files) => files,
        _ => return ask_for_exit(),
    };
    let device: rodio::Device = rodio::default_output_device().unwrap();
    let sink: rodio::Sink = rodio::Sink::new(&device);
    let _: Vec<_> = music_files
        .iter()
        .map(|song: &std::string::String| {
            println!("Playing '{}'", std::path::Path::new(&song).file_stem().and_then(std::ffi::OsStr::to_str).unwrap());
            let file = std::fs::File::open(&song).unwrap();
            sink.append(rodio::Decoder::new(BufReader::new(file)).unwrap());
            sink.sleep_until_end();
        })
        .collect();
}

However, on the first half(ish?) seconds, I get the error ALSA lib pcm.c:8526:(snd_pcm_recover) underrun occurred. This also causes some audio mishaps. After doing some Googling, this error happens when a null byte it passed. The files I'm playing are raw .mp3 files, I don't believe there to be any null bytes. This doesn't happen with any other music player either. Any clue?

Rua commented 4 years ago

I have also been getting this error on rare occasions, but I don't know what triggers it so I can't reproduce.

aryakaul commented 4 years ago

Also getting this. Like Rua, I can't figure out how to reproduce it

OoLunar commented 4 years ago

It makes me wonder if it's caused by some other outside factor

aryakaul commented 4 years ago

At least in my use case, I've found that the 0.10 release of rodio doesn't have this issue.

OoLunar commented 4 years ago

Time to compare and contrast code!

nphyx commented 3 years ago

getting the same thing on rodio 0.11, with large FLAC sources. I thought maybe the BufReader initially reading the file was underrunning so I increased its capacity significantly, but that only seems to delay the problem somewhat.

I would be happy to insert some larger buffers between steps but I'm not sure that's doable. I don't see any way to tweak the rest of the chain from decoder to sink to device.

0xpr03 commented 3 years ago

I've seen this on 0.13 while paused on a mp3-VBR. grafik

OS is ubuntu 20.04 But I have no sound issues.

mattdm commented 3 years ago

FWIW I'm getting this every time Bevy initializes its audio system; that's got rodio 0.13.

(I'm on Fedora Workstation 34 pre-release with pipewire, fwiw.)

Ixentus commented 3 years ago

Also getting this error every other time when Bevy loads audio. Didn't have this problem before switching from PulseAudio to PipeWire 0.3.24. Haven't noticed any other audio applications misbehaving.

spareleg commented 3 years ago

Same problem on Linux with PipeWire 0.3.24

OoLunar commented 3 years ago

Rereading my original post, or makes me wonder if Rodio doesn't strip null bytes.

We're getting a bunch of "Hey me too" comments, which isn't very helpful. Could we get some code of what y'all are doing and see what's in common? Is this specifically to Linux, or does it apply to other OS' too? If it does apply to Linux, which Distros and audio software are y'all using?

I'm using Ubuntu and PulseAudio.

spareleg commented 3 years ago

The code I used is the first example from docs (how to play an audio file). I tried to run this example on all 3 linux distros that I use: Arch, Manjaro, Fedora. And result is always the same: no sound and error ALSA lib pcm.c:8545:(snd_pcm_recover) underrun occurred. The common thing in my case is the PipeWire set as default output. I also have packages like pipewire-alsa, pipewire-pulse, pipewire-jack installed which makes programs with alsa/jack/pa output having working sound too even if they don't support pipewire directly.

AbhisarAnand commented 3 years ago

I found this on another thread: https://bbs.archlinux.org/viewtopic.php?id=185736

Maybe this helps?

ghost commented 2 years ago

I have the same issue, I can reproduce it with the example basic:

$ cargo run --example=basic
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s
     Running `target/debug/examples/basic`
Started beep1
Started beep2
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
Started beep3
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
Stopped beep1
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
Stopped beep3
cargo run --example=basic  7.68s user 0.32s system 91% cpu 8.768 total
$

Another run:

$ cargo run --example=basic
    Finished dev [unoptimized + debuginfo] target(s) in 0.33s
     Running `target/debug/examples/basic`
Started beep1
Started beep2
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
Started beep3
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
Stopped beep1
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
Stopped beep3
ALSA lib pcm.c:8559:(snd_pcm_recover) underrun occurred
cargo run --example=basic  7.52s user 0.29s system 86% cpu 8.993 total
$

System info:

$ uname -srvmo
Linux 5.15.5-arch1-1 #1 SMP PREEMPT Thu, 25 Nov 2021 22:09:33 +0000 x86_64 GNU/Linux
$

I'm using Arch Linux, I have installed pulseaudio-alsa.

tluijken commented 2 years ago

I also have the same issue on Fedora35 using Pipewire and I was wondering if there was any progress regarding this issue? I am experiencing the same as OP. However, I noticed this only happens to me whenever I clone a buffered source. The same goes if I use the repeat_infinte() call, which also clones the source under the hood.

So while this runs like a charm:

stream_handle.play_raw(sample.convert_samples());

these 2 options result in the underrun error:

stream_handle.play_raw(sample.buffered().clone().convert_samples());
// repeat_infinite also buffers and clones the original sample
stream_handle.play_raw(sample.repeat_infinite().convert_samples());
TristanDebrunner commented 1 year ago

Also ran into this. I've got a short WAV file that I'm repeating while a button is pressed. This code would cause the error once each time sound started (SOUND_FILE is the wav, stored in a static Cursor<&[u8]>):

let mut sink = Sink::try_new(&handle)?;

let mut running = false;
loop {
    match rx.recv()? {
        ButtonEvent::Pressed => if !running {
            println!("Starting sound");
            sink = Sink::try_new(&handle)?;
            sink.append(Decoder::new_wav(SOUND_FILE.clone())?.repeat_infinite());
            running = true;
        }
        ButtonEvent::Released => if running {
            println!("Stopping sound");
            sink.stop();
            running = false;
        }
    }
}

But this code does not cause the error:

let mut sink = Sink::try_new(&handle)?;

let sound = Decoder::new_wav(SOUND_FILE.clone())?.repeat_infinite();

let mut running = false;
loop {
    match rx.recv()? {
        ButtonEvent::Pressed => if !running {
            println!("Starting sound");
            sink = Sink::try_new(&handle)?;
            sink.append(sound.clone());
            running = true;
        }
        ButtonEvent::Released => if running {
            println!("Stopping sound");
            sink.stop();
            running = false;
        }
    }
}

I'm running on a Raspberry Pi with Raspberry Pi OS's default sound implementation (I have to admit I don't actually know what that is)

matanox commented 5 months ago

Maybe you hit into it also outside of using this particular project. E.g. on my system I get the same error (albeit on a slightly different line of code) by just letting the linux q4vl2 camera tool record video from my webcam:

ALSA lib pcm.c:8568:(snd_pcm_recover) underrun occurred