Spatial & Reverb dont work with ogg
Examples that use ogg files still run, but no longer produce sound. Based on my testing, this problem seems to have been introduced in #753.
Could you share a little more about your system? Since everything works on our systems.
I'm running Arch Linux, EndeavourOS. My sound server is Pipewire.
I noticed that cargo r --example reverb prints out this message immediately: "Dropping OutputStream, audio playing through this stream will stop." If behaving as desired, it should instead play audio for a while, and then drop. If I use an mp3 instead of an ogg, the example works correctly.
I can reproduce the reverb issue 👍
Switching to the lewton decoder backend addresses it. We might need to make that the default again. It might be an issue similar to #769. As reverb uses buffered which needs the full duration.
Still strange that the music_ogg example does not work. @mfluehr Could you double check that cargo r --example music_ogg does not work?
I'd like to have this issue dug a little deeper before switching defaults again. First, to understand. Second, because unlike MP3, Ogg Vorbis files should have their duration reliably determinable always. So reverb, buffered reads and total duration should all be fine even if they are not today.
@dvdsk, I must've been a little sloppy when trying examples the first time. The only ones that seem broken are "reverb" and "spatial."
@dvdsk, I must've been a little sloppy when trying examples the first time. The only ones that seem broken are "reverb" and "spatial."
no worries :)
Then I can reproduce it all locally :)
Ah, I was banging my head trying rodio wondering why the sink stopped producing sounds whenever I added .buffered() or .repeat_infinite()...
I can confirm changing the backend (cargo add rodio --no-default-features --features lewton,playback) works around the issue.
Also, it's different from #769 in that .total_duration() returns a proper duration.. And actually with lewton it's not :)
This might help; printing this:
let a = rodio::Decoder::try_from(file)?;
println!("file duration {:?}", a.total_duration());
let b = a.buffered();
println!("buffered duration {:?}", b.total_duration());
println!("sample rate {:?}", b.sample_rate());
println!("channels {:?}", b.channels());
println!("span len {:?}", b.current_span_len());
with lewton (buffered audio works)
file duration None
buffered duration None
sample rate 44100
channels 2
span len Some(256)
with default:
file duration Some(124.577777777s)
buffered duration Some(124.577777777s)
sample rate 44100
channels 1
span len Some(0)
I suspect span length being wrong is a problem?
Anyway, I'll just use lewton for now.
Yes, clearly the span length. Thanks for that quick debugging.
Haven't gotten around to it yet, but my hunch is that the first chunk of Ogg data does not contain any samples, just metadata, and therefore our decoder mistakenly sets the span length to 0. And channels to 1! Instead, it should forward to the next chunk and start counting span length from there. Didn't check yet, just a hunch.
Side note: it should be possible to determine total_duration with lewton (or actually, ogg) also now that we've got the builder. We can find the last granule position for finite streams. Separate issue though.
Hypothesis confirmed, I'll submit a PR soon.
Working on this I got carried away :laughing: so a pretty large PR is incoming to fix alongside a host of other improvements.
Hello, I was wondering if my issue was linked to this one. I have a setup similar to mfluehr (Archlinux, Pipewire, Hyprland for WM). I reduced the problem to this snippet of code:
let stream_handle = rodio::OutputStreamBuilder::open_default_stream().unwrap();
let mixer = stream_handle.mixer();
let file = File::open("/path/to/file.ogg").unwrap();
let source = Decoder::try_from(file).unwrap();
mixer.add(source); // Direct use a mixer
std::thread::sleep(std::time::Duration::from_secs(60));
I have no sound output whereas wpctl show a correct stream as expected. I have no problem with mp3 files.
The thing that I find weird is that the Vorbis ogg file is working well when I go through a Sink like that:
let stream_handle = rodio::OutputStreamBuilder::open_default_stream().unwrap();
let sink = Sink::connect_new(&stream_handle.mixer());
let file = File::open("/path/to/file.ogg").unwrap();
let source = Decoder::try_from(file).unwrap();
sink.append(source); // Playing with a Sink instead of directly mixer.add()
std::thread::sleep(std::time::Duration::from_secs(60));
I hope this is helping. It will be my pleasure to do other tests if needed but please keep in mind that I do not know a lot about Rust.
It’s been fixed in #786.