Skip to content

Commit 59482ed

Browse files
authored
Merge pull request #1362 from fabienjuif/hotfix_librespot_0.7
chore: bump librespot to 0.7.1
2 parents b59217a + 31e6368 commit 59482ed

11 files changed

Lines changed: 905 additions & 806 deletions

File tree

Cargo.lock

Lines changed: 695 additions & 624 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@ sha-1 = "0.10"
2626
tokio = {version = "1.44.2", features = ["signal", "rt-multi-thread", "process", "io-std"] }
2727
tokio-stream = "0.1.7"
2828
url = "2.2.2"
29-
librespot-audio = { version = "0.6", default-features = false }
30-
librespot-playback = { version = "0.6", default-features = false }
31-
librespot-core = "0.6"
32-
librespot-discovery = "0.6"
33-
librespot-connect = "0.6"
34-
librespot-metadata = "0.6"
35-
librespot-protocol = "0.6"
36-
librespot-oauth = "0.6"
29+
librespot-audio = { version = "0.7.1", default-features = false }
30+
librespot-playback = { version = "0.7.1", default-features = false }
31+
librespot-core = "0.7.1"
32+
librespot-discovery = "0.7.1"
33+
librespot-connect = "0.7.1"
34+
librespot-metadata = "0.7.1"
35+
librespot-protocol = "0.7.1"
36+
librespot-oauth = "0.7.1"
3737
toml = "0.8.19"
3838
color-eyre = "0.6"
3939
directories = "6.0.0"
@@ -61,7 +61,7 @@ env_logger = "0.11"
6161
[features]
6262
alsa_backend = ["librespot-playback/alsa-backend", "dep:alsa"]
6363
dbus_mpris = ["dep:dbus", "dep:dbus-tokio", "dep:dbus-crossroads"]
64-
default = ["alsa_backend"]
64+
default = ["alsa_backend", "pulseaudio_backend", "dbus_mpris"]
6565
portaudio_backend = ["librespot-playback/portaudio-backend"]
6666
pulseaudio_backend = ["librespot-playback/pulseaudio-backend"]
6767
rodio_backend = ["librespot-playback/rodio-backend"]

src/alsa_mixer.rs

Lines changed: 53 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
1+
use color_eyre::eyre::{self, Context, eyre};
12
use librespot_playback::mixer::{Mixer, MixerConfig};
23
use log::error;
3-
use std::error::Error;
4+
use std::sync::{Arc, Mutex, MutexGuard};
45

5-
#[derive(Clone)]
66
pub struct AlsaMixer {
7-
pub device: String,
8-
pub mixer: String,
9-
pub linear_scaling: bool,
7+
pub mixer: Arc<Mutex<alsa::Mixer>>,
8+
pub config: MixerConfig,
109
}
1110

1211
impl AlsaMixer {
13-
fn set_volume_with_err(&self, volume: u16) -> Result<(), Box<dyn Error>> {
14-
let mixer = alsa::mixer::Mixer::new(&self.device, false)?;
15-
16-
let selem_id = alsa::mixer::SelemId::new(&self.mixer, 0);
17-
let elem = mixer.find_selem(&selem_id).ok_or_else(|| {
18-
format!(
19-
"Couldn't find selem with name '{}'.",
20-
selem_id.get_name().unwrap_or("unnamed")
12+
fn get_selem<'a>(
13+
&'a self,
14+
lock: &'a MutexGuard<'a, alsa::Mixer>,
15+
) -> eyre::Result<alsa::mixer::Selem<'a>> {
16+
let selem_id = alsa::mixer::SelemId::new(&self.config.control, self.config.index);
17+
let selem = lock.find_selem(&selem_id).ok_or_else(|| {
18+
eyre!(
19+
"No control with name '{}' in alsa device '{}'",
20+
self.config.control,
21+
self.config.device,
2122
)
2223
})?;
23-
24+
Ok(selem)
25+
}
26+
fn set_volume_with_err(&self, volume: u16) -> eyre::Result<()> {
27+
let lock = self.mixer.lock().expect("lock shouldn't be poisoned");
28+
let elem = self.get_selem(&lock)?;
2429
let (min, max) = elem.get_playback_volume_range();
2530

2631
let volume_steps = (max - min) as f64;
27-
let normalised_volume = if self.linear_scaling {
32+
let normalised_volume = if matches!(
33+
self.config.volume_ctrl,
34+
librespot_playback::config::VolumeCtrl::Linear
35+
) {
2836
(((volume as f64) / (u16::MAX as f64)) * volume_steps) as i64 + min
2937
} else {
3038
((volume as f64 + 1.0).log((u16::MAX as f64) + 1.0) * volume_steps).floor() as i64 + min
@@ -33,39 +41,41 @@ impl AlsaMixer {
3341
elem.set_playback_volume_all(normalised_volume)?;
3442
Ok(())
3543
}
44+
45+
fn get_volume_with_err(&self) -> eyre::Result<u16> {
46+
let lock = self.mixer.lock().expect("lock shouldn't be poisoned");
47+
let elem = self.get_selem(&lock)?;
48+
let (min, max) = elem.get_playback_volume_range();
49+
let volume_steps = (max - min) as f64;
50+
let vol = elem.get_playback_volume(alsa::mixer::SelemChannelId::mono())?;
51+
let normalized_volume = if matches!(
52+
self.config.volume_ctrl,
53+
librespot_playback::config::VolumeCtrl::Linear
54+
) {
55+
((vol - min) as f64 * u16::MAX as f64 / volume_steps).floor() as u16
56+
} else {
57+
((u16::MAX as f64 + 1.0).powf(((vol - min) as f64) / volume_steps) - 1.0).floor() as u16
58+
};
59+
Ok(normalized_volume)
60+
}
3661
}
3762

3863
impl Mixer for AlsaMixer {
39-
fn open(_: MixerConfig) -> AlsaMixer {
40-
AlsaMixer {
41-
device: "default".to_string(),
42-
mixer: "Master".to_string(),
43-
linear_scaling: false,
44-
}
64+
fn open(config: MixerConfig) -> Result<AlsaMixer, librespot_core::Error> {
65+
let mixer = alsa::Mixer::new(&config.device, false)
66+
.wrap_err("failed to open mixer")
67+
.map_err(librespot_core::Error::invalid_argument)?;
68+
Ok(AlsaMixer {
69+
mixer: Arc::new(Mutex::new(mixer)),
70+
config,
71+
})
4572
}
4673

4774
fn volume(&self) -> u16 {
48-
let selem_id = alsa::mixer::SelemId::new(&self.mixer, 0);
49-
let mixer = alsa::mixer::Mixer::new(&self.device, false).ok();
50-
let vol = mixer
51-
.as_ref()
52-
.and_then(|mixer| mixer.find_selem(&selem_id))
53-
.and_then(|elem| {
54-
let (min, max) = elem.get_playback_volume_range();
55-
elem.get_playback_volume(alsa::mixer::SelemChannelId::mono())
56-
.ok()
57-
.map(|volume| {
58-
(((volume - min) as f64 / (max - min) as f64) * (u16::MAX as f64)).floor()
59-
as u16
60-
})
61-
});
62-
match vol {
63-
Some(vol) => vol,
64-
None => {
65-
error!(
66-
"Couldn't read volume from alsa device with name \"{}\".",
67-
self.device
68-
);
75+
match self.get_volume_with_err() {
76+
Ok(vol) => vol,
77+
Err(err) => {
78+
error!("failed to get volume from alsa device: {err:?}");
6979
0
7080
}
7181
}
@@ -74,7 +84,7 @@ impl Mixer for AlsaMixer {
7484
fn set_volume(&self, volume: u16) {
7585
match self.set_volume_with_err(volume) {
7686
Ok(_) => (),
77-
Err(e) => error!("Couldn't set volume: {:?}", e),
87+
Err(err) => error!("Couldn't set volume of alsa device: {err:?}"),
7888
}
7989
}
8090
}

src/config.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ pub enum DeviceType {
6969
UnknownSpotify,
7070
CarThing,
7171
Observer,
72-
HomeThing,
7372
}
7473

7574
impl From<DeviceType> for LSDeviceType {
@@ -93,7 +92,6 @@ impl From<DeviceType> for LSDeviceType {
9392
DeviceType::UnknownSpotify => LSDeviceType::UnknownSpotify,
9493
DeviceType::CarThing => LSDeviceType::CarThing,
9594
DeviceType::Observer => LSDeviceType::Observer,
96-
DeviceType::HomeThing => LSDeviceType::HomeThing,
9795
}
9896
}
9997
}
@@ -600,7 +598,7 @@ impl SharedConfigValues {
600598
}
601599

602600
pub(crate) fn get_config_file() -> Option<PathBuf> {
603-
let etc_conf = format!("/etc/{}", CONFIG_FILE_NAME);
601+
let etc_conf = format!("/etc/{CONFIG_FILE_NAME}");
604602
let dirs = directories::ProjectDirs::from("", "", "spotifyd")?;
605603
let mut path = dirs.config_dir().to_path_buf();
606604
path.push(CONFIG_FILE_NAME);
@@ -626,7 +624,7 @@ pub(crate) struct SpotifydConfig {
626624
pub(crate) audio_device: Option<String>,
627625
pub(crate) audio_format: LSAudioFormat,
628626
pub(crate) volume_controller: VolumeController,
629-
pub(crate) initial_volume: Option<u16>,
627+
pub(crate) initial_volume: u16,
630628
pub(crate) device_name: String,
631629
pub(crate) player_config: PlayerConfig,
632630
pub(crate) session_config: SessionConfig,
@@ -675,7 +673,8 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
675673
.volume_controller
676674
.unwrap_or(VolumeController::SoftVolume);
677675

678-
let initial_volume: Option<u16> = config
676+
let default_initial_volume = 90;
677+
let initial_volume: u16 = config
679678
.shared_config
680679
.initial_volume
681680
.filter(|val| {
@@ -686,7 +685,8 @@ pub(crate) fn get_internal_config(config: CliConfig) -> SpotifydConfig {
686685
false
687686
}
688687
})
689-
.map(|volume| (volume as i32 * (u16::MAX as i32) / 100) as u16);
688+
.map(|volume| (volume as i32 * (u16::MAX as i32) / 100) as u16)
689+
.unwrap_or((default_initial_volume * (u16::MAX as i32) / 100) as u16);
690690

691691
let device_name = config
692692
.shared_config

0 commit comments

Comments
 (0)