Music not playing and no errors
So it is not playing anything and I just took the code off your docs so idk (and it's not giving me an invalid file or anything not even logging anything)
Kernal: linux Os: arch Rodio v: 0.14.0 Cargo v: 1.53.0 Rust v: 2018
// Get a output stream handle to the default physical sound device
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
// Load a sound from a file, using a path relative to Cargo.toml
let file = BufReader::new(File::open("doom.ogg").unwrap());
// Decode that sound file into a source
let source = Decoder::new(file).unwrap();
// Play the sound directly on the device
stream_handle.play_raw(source.convert_samples());
// The sound plays in a separate audio thread,
// so we need to keep the main thread alive while it's playing.
std::thread::sleep(std::time::Duration::from_secs(5));
I had the same issue with this code (not relying on any external files):
fn main() {
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let source = SineWave::new(10_000);
stream_handle.play_raw(source.convert_samples()).unwrap();
std::thread::sleep(std::time::Duration::from_secs(3));
}
It turned out that running the code in tmux caused no audio to be produced, but in a regular terminal things worked fine. I'm not sure why that is.
I was able to get both the play_raw() and Sink version working in tmux, however, when I tried to extract the audio playing part into it's own struct, I found that it would exhibit this behavior unless the sink was declared and defined in main(). The source could be defined outside of main() (I created the source and appended it from a struct method). I'm unsure if this info will help pin the problem, but I thought I'd contribute my observations.
I can confirm @AjiBuster499 's observation that the Sink must be declared and defined in main(), otherwise no sound is played. This is in the context of a Dioxus app, for what it's worth.
I can also confirm that it must be declared/defined in main in a GTK4 app
verbose details here
works
use gtk::prelude::*;
use rodio::OutputStream;
use std::io::BufReader;
fn main() {
let application =
gtk::Application::new(Some("com.github.gtk-rs.examples.basic"), Default::default());
// Play beep
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let file = std::fs::File::open("assets/beep.wav").unwrap();
let beep1 = stream_handle.play_once(BufReader::new(file)).unwrap();
beep1.set_volume(0.2);
application.connect_activate(build_ui);
application.run();
}
fn build_ui(application: >k::Application) {
let window = gtk::ApplicationWindow::new(application);
window.set_title(Some("First GTK Program"));
window.set_default_size(350, 70);
let button = gtk::Button::with_label("Click me!");
window.set_child(Some(&button));
window.show();
}
does not work (plays fraction of beep and is cut off)
use gtk::prelude::*;
use rodio::OutputStream;
use std::io::BufReader;
fn main() {
let application =
gtk::Application::new(Some("com.github.gtk-rs.examples.basic"), Default::default());
application.connect_activate(build_ui);
application.run();
}
fn build_ui(application: >k::Application) {
let window = gtk::ApplicationWindow::new(application);
window.set_title(Some("First GTK Program"));
window.set_default_size(350, 70);
let button = gtk::Button::with_label("Click me!");
// Play beep
let (_stream, stream_handle) = OutputStream::try_default().unwrap();
let file = std::fs::File::open("assets/beep.wav").unwrap();
let beep1 = stream_handle.play_once(BufReader::new(file)).unwrap();
beep1.set_volume(0.2);
window.set_child(Some(&button));
window.show();
}
cargo.toml for extra detail
[package]
name = "helloworldplayer"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rodio = "0.16.0"
gtk = { version = "0.4", package = "gtk4", features = ["v4_8"] }
Just to confirm I had this same issue. I created a function that spun up a thread inside, and used a channel to communicate stopping to the sink. A stop function was returned. No errors, everything compiling fine but no music was planning. I moved the stream handle and sink out into the main thread, passed them into my function and then everything worked fine.
I initially came to the same conclusion as @AjiBuster499 but wanted to know what caused this. After experimenting and identifying the issue, I was able to find #330 which relates to this issue. In short:
As #330 states, the OutputStreamHandle confusingly is a reference to the OutputStream returned by OutputStream::try_default(), and if you do not capture the stream into a variable, the handle cannot point to the object. In the issue here, when the stream goes out of scope, the handle becomes worthless. The inner field of OutputStreamHandle is of type alloc::sync::Weak which explains this behavior.
Bevy handles using Weak and Strong in the same type very well. https://github.com/bevyengine/bevy/blob/f867319336541acb8ed80743c723effeb4be8896/crates/bevy_asset/src/handle.rs#L119
Hey folks, I am also facing a similar issue, not sure if it is related to the above mentioned use case.
thread::spawn(move ||{
let (_stream, handle) = OutputStream::try_default().expect("speaker broke");
let sink = Sink::try_new(&handle).expect("speaker on the left broke");
let source = Decoder::new(...);
sink.append(source);
sink.play();
loop {
match rx.blocking_recv() {
... // This is conditional logic for controlling the channel via different thread using channels
}
}
})
So, this above mentioned code doesn't produce any sound. But, here's the fun part, the one mentioned below does work
thread::spawn(move ||{
let (_stream, handle) = OutputStream::try_default().expect("speaker broke");
let sink = Sink::try_new(&handle).expect("speaker on the left broke");
let source = Decoder::new(...);
sink.append(source);
sink.sleep_until_end();
loop {
match rx.blocking_recv() {
... // This is conditional logic for controlling the channel via different thread using channels
}
}
})
But, this doesn't fall into my use case where, I need the current thread to handle the incoming message for the channel after starting the sink.
Can anyone please let me know, what might be causing this. Because, for testing I tried adding sleep delay after doing sink.play() in the first code snippet, but it still doesn't seem to work. I am not able to predict the behaviour of the code even after going through the source code of how Sink is written.
Yeah I was having a similar problem with no sound playing. After finding issue #330 I realized it might be the fact that after the stream variable is dropped, the handle doesn't work anymore. So now I keep the OutputStream variable and the OutputStreamHandle variable in the same struct so their lifetimes should be the same. And that works.
I think OutputStream either needs to use an Arc<...> ptr instead of Weak<...>, or OutputStreamHandle needs a lifetime parameter in its type towards the OutputStream variable.