audio: Don't use linear volume (#348)
Fixes https://github.com/pop-os/cosmic-applets/issues/335. This calculates volume as a percentage of `Volume::NORMAL`, which seems to be the correct way to display PulseAudio volumes to the user. This matches `cosmic-osd`, and seems to match alsamixer.
This commit is contained in:
parent
631e59276e
commit
08a334fc13
1 changed files with 25 additions and 17 deletions
|
|
@ -32,7 +32,7 @@ use cosmic::{Element, Theme};
|
||||||
use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
|
use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
|
||||||
use iced::wayland::popup::{destroy_popup, get_popup};
|
use iced::wayland::popup::{destroy_popup, get_popup};
|
||||||
use iced::widget::container;
|
use iced::widget::container;
|
||||||
use libpulse_binding::volume::VolumeLinear;
|
use libpulse_binding::volume::Volume;
|
||||||
use mpris2_zbus::player::PlaybackStatus;
|
use mpris2_zbus::player::PlaybackStatus;
|
||||||
use mpris_subscription::MprisRequest;
|
use mpris_subscription::MprisRequest;
|
||||||
use mpris_subscription::MprisUpdate;
|
use mpris_subscription::MprisUpdate;
|
||||||
|
|
@ -84,7 +84,7 @@ impl Audio {
|
||||||
};
|
};
|
||||||
|
|
||||||
let volume = output.volume.avg();
|
let volume = output.volume.avg();
|
||||||
let output_volume = VolumeLinear::from(volume).0;
|
let output_volume = volume_to_percent(volume);
|
||||||
if volume.is_muted() {
|
if volume.is_muted() {
|
||||||
self.icon_name = "audio-volume-muted-symbolic".to_string();
|
self.icon_name = "audio-volume-muted-symbolic".to_string();
|
||||||
} else if output_volume < 0.33 {
|
} else if output_volume < 0.33 {
|
||||||
|
|
@ -110,7 +110,7 @@ impl Audio {
|
||||||
};
|
};
|
||||||
|
|
||||||
let volume = input.volume.avg();
|
let volume = input.volume.avg();
|
||||||
let input_volume = VolumeLinear::from(volume).0;
|
let input_volume = volume_to_percent(volume);
|
||||||
if volume.is_muted() || input_volume == 0.0 {
|
if volume.is_muted() || input_volume == 0.0 {
|
||||||
self.input_icon_name = "microphone-sensitivity-muted-symbolic".to_string();
|
self.input_icon_name = "microphone-sensitivity-muted-symbolic".to_string();
|
||||||
} else if input_volume < 0.33 {
|
} else if input_volume < 0.33 {
|
||||||
|
|
@ -335,10 +335,9 @@ impl cosmic::Application for Audio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::SetOutputVolume(vol) => {
|
Message::SetOutputVolume(vol) => {
|
||||||
self.current_output.as_mut().map(|o| {
|
self.current_output
|
||||||
o.volume
|
.as_mut()
|
||||||
.set(o.volume.len(), VolumeLinear(vol / 100.0).into())
|
.map(|o| o.volume.set(o.volume.len(), percent_to_volume(vol)));
|
||||||
});
|
|
||||||
self.apply_output_volume();
|
self.apply_output_volume();
|
||||||
if let PulseState::Connected(connection) = &mut self.pulse_state {
|
if let PulseState::Connected(connection) = &mut self.pulse_state {
|
||||||
if let Some(device) = &self.current_output {
|
if let Some(device) = &self.current_output {
|
||||||
|
|
@ -352,10 +351,9 @@ impl cosmic::Application for Audio {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Message::SetInputVolume(vol) => {
|
Message::SetInputVolume(vol) => {
|
||||||
self.current_input.as_mut().map(|i| {
|
self.current_input
|
||||||
i.volume
|
.as_mut()
|
||||||
.set(i.volume.len(), VolumeLinear(vol / 100.0).into())
|
.map(|i| i.volume.set(i.volume.len(), percent_to_volume(vol)));
|
||||||
});
|
|
||||||
self.apply_input_volume();
|
self.apply_input_volume();
|
||||||
if let PulseState::Connected(connection) = &mut self.pulse_state {
|
if let PulseState::Connected(connection) = &mut self.pulse_state {
|
||||||
if let Some(device) = &self.current_input {
|
if let Some(device) = &self.current_input {
|
||||||
|
|
@ -596,20 +594,18 @@ impl cosmic::Application for Audio {
|
||||||
|
|
||||||
fn view_window(&self, _id: window::Id) -> Element<Message> {
|
fn view_window(&self, _id: window::Id) -> Element<Message> {
|
||||||
let audio_disabled = matches!(self.pulse_state, PulseState::Disconnected(_));
|
let audio_disabled = matches!(self.pulse_state, PulseState::Disconnected(_));
|
||||||
let out_f64 = VolumeLinear::from(
|
let out_f64 = volume_to_percent(
|
||||||
self.current_output
|
self.current_output
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|o| o.volume.avg())
|
.map(|o| o.volume.avg())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
)
|
);
|
||||||
.0 * 100.0;
|
let in_f64 = volume_to_percent(
|
||||||
let in_f64 = VolumeLinear::from(
|
|
||||||
self.current_input
|
self.current_input
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|o| o.volume.avg())
|
.map(|o| o.volume.avg())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
)
|
);
|
||||||
.0 * 100.0;
|
|
||||||
|
|
||||||
let mut audio_content = if audio_disabled {
|
let mut audio_content = if audio_disabled {
|
||||||
column![padded_control(
|
column![padded_control(
|
||||||
|
|
@ -868,3 +864,15 @@ impl Default for IsOpen {
|
||||||
Self::None
|
Self::None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn volume_to_percent(volume: Volume) -> f64 {
|
||||||
|
volume.0 as f64 * 100. / Volume::NORMAL.0 as f64
|
||||||
|
}
|
||||||
|
|
||||||
|
fn percent_to_volume(percent: f64) -> Volume {
|
||||||
|
Volume(
|
||||||
|
(percent / 100. * Volume::NORMAL.0 as f64)
|
||||||
|
.clamp(0., Volume::NORMAL.0 as f64)
|
||||||
|
.round() as u32,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue