UPDATED: This issue is officially a bug.
I'm adding a reverb effect following this example, but panic
when trying to play the sink.
thread '<unnamed>' panicked at /feelslikehome/.cargo/registry/src/index.crates.io-6f17d22bba15001f/rodio-0.19.0/src/conversions/channels.rs:100:13:
attempt to subtract with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
fatal runtime error: Rust panics must be rethrown
This is what I did:
fn main() {
// This snippet is from the example
let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
let sink = rodio::Sink::try_new(&handle).unwrap();
let file = std::fs::File::open("assets/music.ogg").unwrap();
// This is originally a function that returns (Mode, Sink, Stream) tuple
match Decoder::new(BufReader::new(file)) {
Ok(decoder) => {
let mode = get_mode();
if mode == Mode::Bass {
// Duration is just an arbitrary number, I tried 0, milliseconds, etc.
let reverb = decoder.buffered().reverb(Duration::from_secs(30), 1.0);
sink.append(reverb);
} else {
sink.append(decoder);
}
// Try playing it right away, it panicked!
sink.play();
Some((mode, sink, stream))
}
Err(e) => {
info!("Failed to create decoder: {:?}", e);
None
}
}
}
fn get_mode() -> Mode {
Mode::Bass
}
enum Mode {
case Bass
}
I suspect calling the buffered()
is the problem, but it is needed because the reverb requires a clone
-able source. There's no API to unbuffered
the decoder. When I tried to play the sink right away, it was also panic
.
Any pointers?
This is officially a bug. I posted the solution here to solve the panic
. The bug is in the size_hint
function of the channels.rs
rodio
. This line:
(size + consumed) / self.from as usize * self.to as usize
- self.next_output_sample_pos as usize
Becomes:
((size + consumed) / self.from as usize * self.to as usize).saturating_sub(self.next_output_sample_pos as usize)