librespot-org / librespot

Open Source Spotify client library
MIT License
4.46k stars 540 forks source link

`Could not get Alsa softvol dB range` when trying to control PipeWire volume via ALSA #1232

Open lmore377 opened 6 months ago

lmore377 commented 6 months ago

Describe the bug I'd like to use hardware volume control but my system uses PipeWire. I saw that there's a virtual pipewire device in aplay -L so I tried setting that as the mixer device/control but librespot just crashes with Could not get Alsa softvol dB range.

To reproduce Steps to reproduce the behavior:

  1. Launch librespot with -B alsa -m alsa -S "pipewire" -T "Master"

Log

$ librespot -B alsa -m alsa -S "pipewire" -T "Master" -v
[2023-12-13T19:33:17Z INFO  librespot] librespot 0.5.0-dev 886617e (Built on 2023-12-13, Build ID: UnrRWJYV, Profile: release)
[2023-12-13T19:33:17Z TRACE librespot] Command line argument(s):
[2023-12-13T19:33:17Z TRACE librespot]          B "alsa"
[2023-12-13T19:33:17Z TRACE librespot]          m "alsa"
[2023-12-13T19:33:17Z TRACE librespot]          S "pipewire"
[2023-12-13T19:33:17Z TRACE librespot]          T "Master"
[2023-12-13T19:33:17Z TRACE librespot]          v
[2023-12-13T19:33:17Z DEBUG librespot_core::session] new Session
[2023-12-13T19:33:17Z DEBUG librespot_discovery::server] Zeroconf server listening on 0.0.0.0:37789
[2023-12-13T19:33:17Z INFO  librespot_playback::mixer::alsamixer] Mixing with Alsa and volume control: Log(0.0) for device: pipewire with mixer control: Master,0
thread 'main' panicked at playback/src/mixer/alsamixer.rs:70:18:
Could not get Alsa softvol dB range: Error("snd_ctl_get_dB_range", ENOENT)
stack backtrace:
   0:     0x55c97545b4dc - std::backtrace_rs::backtrace::libunwind::trace::ha69d38c49f1bf263
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/../../backtrace/src/backtrace/libunwind.rs:93:5
   1:     0x55c97545b4dc - std::backtrace_rs::backtrace::trace_unsynchronized::h93125d0b85fd543c
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
   2:     0x55c97545b4dc - std::sys_common::backtrace::_print_fmt::h8d65f438e8343444
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:67:5
   3:     0x55c97545b4dc - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h41751d2af6c8033a
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:44:22
   4:     0x55c97548a0bc - core::fmt::rt::Argument::fmt::h5db2f552d8a28f63
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/rt.rs:138:9
   5:     0x55c97548a0bc - core::fmt::write::h99465148a27e4883
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/fmt/mod.rs:1114:21
   6:     0x55c975457cae - std::io::Write::write_fmt::hee8dfd57bd179ab2
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/io/mod.rs:1763:15
   7:     0x55c97545b2c4 - std::sys_common::backtrace::_print::h019a3cee3e814da4
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:47:5
   8:     0x55c97545b2c4 - std::sys_common::backtrace::print::h55694121c2ddf918
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:34:9
   9:     0x55c97545cad3 - std::panicking::default_hook::{{closure}}::h29cbe3da3891b0b0
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:272:22
  10:     0x55c97545c7f4 - std::panicking::default_hook::h881e76b2b8c74280
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:292:9
  11:     0x55c97545d055 - std::panicking::rust_panic_with_hook::hcc36e25b6e33969c
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:731:13
  12:     0x55c97545cf51 - std::panicking::begin_panic_handler::{{closure}}::ha415efb0f69f41f9
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:609:13
  13:     0x55c97545ba06 - std::sys_common::backtrace::__rust_end_short_backtrace::h395fe90f99451e4e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/sys_common/backtrace.rs:170:18
  14:     0x55c97545cca2 - rust_begin_unwind
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:597:5
  15:     0x55c974df6fc5 - core::panicking::panic_fmt::h452a83e54ecd764e
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/panicking.rs:72:14
  16:     0x55c974df74a3 - core::result::unwrap_failed::hed0fccbe07e724fc
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/result.rs:1652:5
  17:     0x55c974fa6517 - <librespot_playback::mixer::alsamixer::AlsaMixer as librespot_playback::mixer::Mixer>::open::h6ebf285ac6937038
  18:     0x55c974fb6196 - librespot_playback::mixer::mk_sink::h5f45d6b9ca4c2eda
  19:     0x55c974e18931 - <core::pin::Pin<P> as core::future::future::Future>::poll::h06d2ccd84614dc47
  20:     0x55c974e73c77 - tokio::runtime::scheduler::current_thread::Context::enter::h64b7bb7e8f27916f
  21:     0x55c974ec3b0a - tokio::runtime::context::set_scheduler::h85eab50ce4089352
  22:     0x55c974e7419a - tokio::runtime::scheduler::current_thread::CoreGuard::block_on::ha42ff9edfcb1c6f5
  23:     0x55c974ec4927 - tokio::runtime::context::runtime::enter_runtime::hbf8473d850bb89e2
  24:     0x55c974ea09bf - tokio::runtime::runtime::Runtime::block_on::he1780980ef582b20
  25:     0x55c974e336b7 - librespot::main::h1b7a2649e1d6cf2d
  26:     0x55c974ecc6a3 - std::sys_common::backtrace::__rust_begin_short_backtrace::h5778f22fc456b088
  27:     0x55c974ead669 - std::rt::lang_start::{{closure}}::hc2a94cefa3565f72
  28:     0x55c97545133b - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h14c5f6d1cd70a60f
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/core/src/ops/function.rs:284:13
  29:     0x55c97545133b - std::panicking::try::do_call::h2d02374ca451446a
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:504:40
  30:     0x55c97545133b - std::panicking::try::h9f7922394bf57392
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:468:19
  31:     0x55c97545133b - std::panic::catch_unwind::ha1600f9dd4ee7270
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panic.rs:142:14
  32:     0x55c97545133b - std::rt::lang_start_internal::{{closure}}::hfbd80e7d681b21a1
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/rt.rs:148:48
  33:     0x55c97545133b - std::panicking::try::do_call::heacaa33dbdaa16e0
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:504:40
  34:     0x55c97545133b - std::panicking::try::h637875f7c9db85ea
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panicking.rs:468:19
  35:     0x55c97545133b - std::panic::catch_unwind::h4caa9c0c78cb4c19
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/panic.rs:142:14
  36:     0x55c97545133b - std::rt::lang_start_internal::h2d6a60ec944b523d
                               at /rustc/a28077b28a02b92985b3a3faecf92813155f1ea1/library/std/src/rt.rs:148:20
  37:     0x55c974e33795 - main
  38:     0x7feb004981ca - <unknown>
  39:     0x7feb00498285 - __libc_start_main
  40:     0x55c974df77a1 - _start
  41:                0x0 - <unknown>
[2023-12-13T19:33:17Z DEBUG librespot_core::session] drop Session

Host (what you are running librespot on):

Additional Information: If it helps, here's the output of amixer

$ amixer -D pipewire
Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 10752 [16%] [on]
  Front Right: Playback 10752 [16%] [on]
Simple mixer control 'Capture',0
  Capabilities: cvolume cswitch cswitch-joined
  Capture channels: Front Left - Front Right
  Limits: Capture 0 - 65536
  Front Left: Capture 10752 [16%] [on]
  Front Right: Capture 10752 [16%] [on]
lmore377 commented 6 months ago

Bit of a hacky workaround, I changed line 59 in playback/src/mixer/alsamixer.rs to let (min_millibel, max_millibel) = if false

and that in combination with -e 100 makes volume control work as expected.

roderickvd commented 6 months ago

Obviously it should not crash. Best to make it gracefully handle devices like this and default to some sane value.