RustAudio / rodio

Rust audio playback library
Apache License 2.0
1.8k stars 235 forks source link

No Sound but no errors. #173

Open AnneKitsune opened 6 years ago

AnneKitsune commented 6 years ago

Using pulseaudio-alsa-jack bridged, as well as pulseaudio + alsa only.

None of the examples of rodio produce sound, but they do create the audio sink inside of pulseaudio (pavucontrol).

There is no errors. cpal's examples are working fine.

Using arch linux, latest version of everything mentionned previously.

jojolepro-8% aplay -v Playing raw data 'stdin' : Unsigned 8 bit, Rate 8000 Hz, Mono Plug PCM: ALSA <-> PulseAudio PCM I/O Plugin Its setup is: stream : PLAYBACK access : RW_INTERLEAVED format : U8 subformat : STD channels : 1 rate : 8000 exact rate : 8000 (8000/1) msbits : 8 buffer_size : 4000 period_size : 1000 period_time : 125000 tstamp_mode : NONE tstamp_type : GETTIMEOFDAY period_step : 1 avail_min : 1000 period_event : 0 start_threshold : 4000 stop_threshold : 4000 silence_threshold: 0 silence_size : 0 boundary : 9007199254740992000

Ilphrin commented 6 years ago

Hi there!

I have exactly the same problem here, no errors, but no sound using Pop_OS! on Oryx Pro. But in pavucontrol I can say that a Sink is launched

dbrgn commented 5 years ago

Exactly the same symptoms here :slightly_smiling_face:

Aplay works:

$ aplay -v /tmp/rodio/examples/beep.wav
Playing WAVE '/tmp/rodio/examples/beep.wav' : Signed 16 bit Little Endian, Rate 44100 Hz, Mono
Plug PCM: ALSA <-> PulseAudio PCM I/O Plugin
Its setup is:
  stream       : PLAYBACK
  access       : RW_INTERLEAVED
  format       : S16_LE
  subformat    : STD
  channels     : 1
  rate         : 44100
  exact rate   : 44100 (44100/1)
  msbits       : 16
  buffer_size  : 22050
  period_size  : 5512
  period_time  : 125000
  tstamp_mode  : NONE
  tstamp_type  : GETTIMEOFDAY
  period_step  : 1
  avail_min    : 5512
  period_event : 0
  start_threshold  : 22050
  stop_threshold   : 22050
  silence_threshold: 0
  silence_size : 0
  boundary     : 6206523236469964800
^CAborted by signal Interrupt...

If there's anything I can do to debug this, let me know.

AnneKitsune commented 5 years ago

I still have the issue, by the way :)

sparky8251 commented 4 years ago

I too am having these problems. I can't seem to figure out what's going on but I suspect it might have something to do with my default device being detected incorrectly? Originally it was pulling from an old ~/asoundrc and assuming I had jack despite me no longer having it installed. I removed that and set a default in /etc/puse/default.pa and now then I at least presume i got a proper default device back.

Forcing the device selection to "pulse" or the actual name of my device results in errors like (snd_pcm_dmix_open) unable to open slave.

Also, for some reason despite no errors being shown for the default I dont see the sink registered in pavucontrol like other reporters.

Unsure how my normal audio through pulse functions, but however it does it doesnt match up with whatever Rodio is trying to do.

peperunas commented 3 years ago

Hello, I confirm I have the same issue. I'm on Arch Linux, rodio 0.13.

Kingtous commented 2 years ago

Same issue here. I'm on Manjaro 21.2.6, rodio 0.15

Nadorrano commented 2 years ago

I solved the issue on Arch reinstalling pipewire. Apparently it was something related to pipewire messing up permissions.

davehorner commented 1 month ago

ubuntu 24.10 no audio no errors. on one machine I installed portaudio and then back to pipewire and it works but it gives error messages now. another clean install, and its silent. would like to figure out how to fix without causing the additional errors.

sudo apt install pulseaudio

sudo apt install pipewire-alsa pipewire-audio

----
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib pcm_oss.c:404:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_oss.c:404:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Connection refused

ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Connection refused
dvdsk commented 1 month ago

Hi there,

Thanks for the report. You clearly went trough a lot of effort to figure out what is going on. I'm almost certain (from the error output) this is a problem in Cpal (which rodio uses under the hood). Could you check that for us?

The easiest way to see if its a cpal issue is to run their beep example:

If the same issue repeats please let them know. And in either case let us know.

davehorner commented 1 month ago

cpal beep works fine. interesting behavior. I wrote an sdl2 app that uses rodio and it works fine.

[package]
name = "sdl2"
version = "0.1.0"
edition = "2021"

[dependencies]
rdev = {version="0.5.3", features=["unstable_grab"]}
rodio = "0.19.0"
winapi = "0.3.9"
winit = "0.30.5"

[target.'cfg(windows)'.dependencies]
sdl2 = { version = "0.37", default-features = false, features = ["ttf", "image", "gfx", "mixer", "static-link", "use-vcpkg"] }

[target.'cfg(unix)'.dependencies]
sdl2 = { version = "0.37" }

[target.'cfg(windows)'.package.metadata.vcpkg]
dependencies = ["sdl2", "sdl2-image[libjpeg-turbo,tiff,libwebp]", "sdl2-ttf", "sdl2-gfx", "sdl2-mixer"]
git = "https://github.com/microsoft/vcpkg"
rev = "2024.05.24" # release 2024.05.24

[target.'cfg(windows)'.package.metadata.vcpkg.target]
x86_64-pc-windows-msvc = { triplet = "x64-windows-static-md" }

[target.'cfg(linux)'.package.metadata.vcpkg.target]
x86_64-unknown-linux-gnu = { triplet = "x64-linux" }

below code makes noise on machine post uninstall-install run around. it did not work clean install.

use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use rodio::{OutputStream, Sink};
use std::fs::File;
use std::io::BufReader;

fn main() {
    // Initialize SDL2
    let sdl_context = sdl2::init().unwrap();
    let video_subsystem = sdl_context.video().unwrap();

    // Create a hidden window (required to capture keyboard events)
    let _window = video_subsystem
        .window("Sound Trigger", 800, 600)
        .position_centered()
        // .hidden()
        .build()
        .unwrap();

    // Create audio output stream
    let (_stream, stream_handle) = OutputStream::try_default().unwrap();

    // Initialize the event pump to capture keyboard events
    let mut event_pump = sdl_context.event_pump().unwrap();

    'running: loop {
        // Poll for events
        for event in event_pump.poll_iter() {
            match event {
                Event::Quit { .. } => break 'running,
                Event::KeyDown {
                    keycode: Some(Keycode::LAlt),
                    ..
                } => {
                    // Check if the Windows key (LGUI) is also pressed
                    // if keymod.contains(Mod::LGUIMOD) {
                        play_sound(&stream_handle);
                    // }
                }
                _ => {}
            }
        }
    }
}

// Function to play sound
fn play_sound(stream_handle: &rodio::OutputStreamHandle) {
    // Load the sound file
    let file = File::open("stereol.wav").unwrap();
    let source = rodio::Decoder::new(BufReader::new(file)).unwrap();

    // Play the sound
    let sink = Sink::try_new(stream_handle).unwrap();
    sink.append(source);
    sink.detach(); // Detach to allow it to play asynchronously
}

same machine same rodio...

[dependencies]
rdev = {version="0.5.3", features=["unstable_grab"]}
rodio = "0.19.0"
winapi = "0.3.9"
winit = "0.30.5"

this one is silent.

#[cfg(target_os = "linux")]
use rdev::{grab, Event};

use rdev::{EventType, Key};
#[cfg(target_os = "windows")]
use rdev::listen;
use rodio::{OutputStream, Sink};
use std::fs::File;
use std::io::BufReader;
use std::sync::{Arc, Mutex};
use std::collections::HashSet;

#[cfg(target_os = "windows")]
extern crate winapi;

use std::thread;
use std::ptr;
#[cfg(target_os = "windows")]
use winapi::shared::windef::HHOOK;
#[cfg(target_os = "windows")]
use winapi::shared::minwindef::{LRESULT, WPARAM, LPARAM};
#[cfg(target_os = "windows")]
use winapi::um::winuser::{WH_KEYBOARD_LL, KBDLLHOOKSTRUCT, WM_KEYDOWN, VK_CAPITAL};
#[cfg(target_os = "windows")]
use winapi::um::winuser::{SetWindowsHookExW, CallNextHookEx, UnhookWindowsHookEx, GetMessageW};

#[cfg(target_os = "windows")]
static mut HOOK: Option<HHOOK> = None;
static mut STREAM_HANDLE: Option<Arc<rodio::OutputStreamHandle>> = None;

#[cfg(target_os = "windows")]
unsafe extern "system" fn hook_proc(n_code: i32, w_param: WPARAM, l_param: LPARAM) -> LRESULT {
    if n_code >= 0 {
        let kb_struct = *(l_param as *const KBDLLHOOKSTRUCT);
        if kb_struct.vkCode == VK_CAPITAL.try_into().unwrap() {
            // Play sound when Caps Lock is pressed
            if w_param as u32 == WM_KEYDOWN {
                if let Some(ref handle) = STREAM_HANDLE {
                    println!("Caps Lock pressed! Playing sound...");
                    play_sound(handle);
                }
            }
            // Prevent Caps Lock toggle
            return 1;
        }
    }
    CallNextHookEx(ptr::null_mut(), n_code, w_param, l_param)
}

#[cfg(target_os = "windows")]
fn set_hook() {
    unsafe {
        let hook = SetWindowsHookExW(
            WH_KEYBOARD_LL,
            Some(hook_proc),
            ptr::null_mut(),
            0,
        );
        HOOK = Some(hook);
    }
}

#[cfg(target_os = "windows")]
fn remove_hook() {
    unsafe {
        if let Some(hook) = HOOK {
            UnhookWindowsHookEx(hook);
            HOOK = None;
        }
    }
}

fn main() {
    let (_stream, stream_handle) = OutputStream::try_default().unwrap();
    let stream_handle = Arc::new(stream_handle);

    // Assign stream_handle to the static global variable
    unsafe {
        STREAM_HANDLE = Some(stream_handle.clone());
    }

    let keys_pressed = Arc::new(Mutex::new(HashSet::new()));

    println!("Listening for Windows + Alt key combination...");

    #[cfg(target_os = "windows")]
    {
        // Set up the Caps Lock bypass hook
        thread::spawn(|| {
            set_hook();
            // Keep the hook alive
            let mut msg = unsafe { std::mem::zeroed() };
            unsafe { GetMessageW(&mut msg, ptr::null_mut(), 0, 0); }
            remove_hook();
        });

        // Listen for other key events
        if let Err(error) = listen(move |event| {
            let mut keys_pressed = keys_pressed.lock().unwrap();
            match event.event_type {
                EventType::KeyPress(key) => {
                    keys_pressed.insert(key);
                    println!("{:?}", key);
                    handle_keypress(&keys_pressed, &stream_handle);
                }
                EventType::KeyRelease(key) => {
                    keys_pressed.remove(&key);
                }
                _ => {}
            }
        }) {
            eprintln!("Error: {:?}", error);
        }
    }

    #[cfg(target_os = "linux")]
    {
        // Grab key events on Linux and disable Caps Lock
        let callback = {
            let keys_pressed = keys_pressed.clone();
            let stream_handle = stream_handle.clone();
            move |event: Event| -> Option<Event> {
                let mut keys_pressed = keys_pressed.lock().unwrap();
                match event.event_type {
                    EventType::KeyPress(key) => {
                        keys_pressed.insert(key);
                        println!("{:?}", key);
                        handle_keypress(&keys_pressed, &stream_handle);
                    }
                    EventType::KeyRelease(key) => {
                        keys_pressed.remove(&key);
                    }
                    _ => {}
                }
                if let EventType::KeyPress(Key::CapsLock) = event.event_type {
                    println!("Caps Lock detected! Playing sound...");
                    play_sound(&stream_handle);
                    None  // Disable CapsLock
                } else {
                    Some(event)
                }
            }
        };

        if let Err(error) = grab(callback) {
            println!("Error: {:?}", error);
        }
    }
}

fn handle_keypress(keys_pressed: &HashSet<Key>, stream_handle: &Arc<rodio::OutputStreamHandle>) {
    if keys_pressed.contains(&Key::MetaLeft) || keys_pressed.contains(&Key::MetaRight) {
        if keys_pressed.contains(&Key::Alt) {
            println!("Windows + Alt detected! Playing sound...");
            play_sound(stream_handle);
        }
        if keys_pressed.contains(&Key::AltGr) {
            println!("Windows + AltGr detected! Playing sound...");
            play_sound(stream_handle);
        }
        if keys_pressed.contains(&Key::ControlLeft) || keys_pressed.contains(&Key::ControlRight) {
            println!("Windows + Ctrl detected! Playing sound...");
            play_sound(stream_handle);
        }
        if keys_pressed.contains(&Key::KeyZ) {
            println!("Windows + Z detected. Exiting program.");
            std::process::exit(0);
        }
    }
}

fn play_sound(stream_handle: &Arc<rodio::OutputStreamHandle>) {
    if let Ok(file) = File::open("stereol.wav") {
        let source = rodio::Decoder::new(BufReader::new(file)).unwrap();
        let sink = Sink::try_new(stream_handle).unwrap();
        sink.append(source);
        sink.detach();
    } else {
        println!("Error: Could not open the sound file.");
    }
}

I think I have to go through the uninstall install...which leaves the machine's audio with spurious errors I'd like to avoid - on one machine it works as does all the system sound but these errors are present.

both apps run fine on windows.

dvdsk commented 1 month ago

could you try the beep example again with this commit: 7b21251afde5ff8f2b1b1a2a299d714ee5b10f04

That is the exact version rodio is using. If that breaks beep then a simple patch can solve the issue for now until cpal releases a new version.

davehorner commented 1 month ago

cargo run --example beep @ 7b21251afde5ff8f2b1b1a2a299d714ee5b10f04 works. sdl2 works, the other does not.

dvdsk commented 1 month ago

I am having trouble reproducing it on my system. If you are okay with trying a few more things we can continue isolating the issue.

Can you run the rodio example music_wav. (clone the repo then `cargo run --example music_wav)

davehorner commented 1 month ago

I can try some more; the machine that is exhibiting the behavior where one sample works and the other doesn't left the building and I have to wait until the weekend to see again. The other ubuntu 24.10 is in a strange state, All of the other apps are not working with audio now and rodio is! aplay -l shows devices, i didn't have jackd installed I tried doing that to resolve the issue; no. I will follow with results as I can.

This machine where rodio works; the sdl2 example does not work and the other does. so strange! music_wav@latest on this machine produces no sound or errors. run as root; it produces sound.

dvdsk commented 1 month ago

its quite the mystery you have found here. I'm gonna dive in the interface with cpal and see what I can find. I will be honest with you, this might take a long while as it sounds so very very strange.

davehorner commented 1 month ago

pretty cool we have two implementations to see differing behavior (what's diff?!); but yes a mystery indeed. killing silent no error errors is not an easy task. we might have a chance at catching something. i appreciate your help and code.

when you say having trouble reproducing, are you saying they both work for you?

OS was loaded on an external ssd. the machine that left, I have the drive booted on another machine and it is reproducing the sdl2 working and the other not. (I will call the other sample walt from here on out)

running as root does not cause walt to produce sound. running cargo run --example music_wav does produce sound as non-root user.

davehorner commented 1 month ago

if you have any suggestions for me to explore further let me know; its sorta an upstream ubuntu issue with portaudio and pipewire. I'm not sure how to go about reporting or what channels appropriate. it's not just ubuntu the other comments suggest it happens elsewhere. if you'd like me to get the samples in a repo I can do that...

davehorner commented 1 month ago

cpal run --example beep makes sound on machine1 (where sdl2 works) cpal run --example beep does not make sound on machine 2 (where walt works) there will be a clean install machine 3;

the beep output from cpal on machine 2/1 both look the same:

    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.04s
     Running `target/debug/examples/beep`
Output device: default
Default output config: SupportedStreamConfig { channels: 2, sample_rate: SampleRate(44100), buffer_size: Range { min: 1, max: 4194304 }, sample_format: F32 }

interesting machine 2 rodio walt makes sound at all as everything else doesn't make sound (including cpal beep...which is what rodio is ultimately using).

davehorner commented 1 month ago

rebooted machine2. all the programs are working. :-{ joy. a moving target. well I'm thankful for sound again tho.

davehorner commented 1 month ago

machine 2 all programs worked for a while; now sdl2 is working and walt is silent. the following errors persist. beep works for machine 2 now.

Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
Cannot connect to server socket err = No such file or directory
Cannot connect to server request channel
jack server is not running or cannot be started
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
JackShmReadWritePtr::~JackShmReadWritePtr - Init not done for -1, skipping unlock
ALSA lib pcm_oss.c:404:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pcm_oss.c:404:(_snd_pcm_oss_open) Cannot open device /dev/dsp
ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Connection refused

ALSA lib pulse.c:242:(pulse_connect) PulseAudio: Unable to connect: Connection refused
dvdsk commented 1 month ago

its sorta an upstream ubuntu issue with portaudio and pipewire.

I think it might be. I have no idea on how to report those however.

cpal run --example beep does not make sound on machine 2 (where walt works)

I would open an issue on the cpal issue tracker, they are more knowledgeable about os interaction. And you can reproduce it using their beep example. If that does not pan out (or maybe as part of that issue?) you might try the ask ubuntu forum. They are generally quite knowledgeable and if its a ubuntu/config problem they might be able to assist.

The errors still sound to me like cpal is trying to find a way to output sound but it cannot find jack or pulseaudio nor any other method to get the sound to the os.