feat(sound): volume amplification
This adds toggles that allow increasing volume to 150% for both the sink and source.
This commit is contained in:
parent
bd7fc2a2f2
commit
0e5054a4c5
4 changed files with 104 additions and 12 deletions
|
|
@ -7,12 +7,17 @@ use cosmic::{
|
||||||
surface,
|
surface,
|
||||||
widget::{self, settings},
|
widget::{self, settings},
|
||||||
};
|
};
|
||||||
|
use cosmic_config::{Config, ConfigGet, ConfigSet};
|
||||||
use cosmic_settings_page::{self as page, Section, section};
|
use cosmic_settings_page::{self as page, Section, section};
|
||||||
use slab::Slab;
|
use slab::Slab;
|
||||||
use slotmap::SlotMap;
|
use slotmap::SlotMap;
|
||||||
|
|
||||||
use cosmic_settings_subscriptions::sound as subscription;
|
use cosmic_settings_subscriptions::sound as subscription;
|
||||||
|
|
||||||
|
const AUDIO_CONFIG: &str = "com.system76.CosmicAudio";
|
||||||
|
const AMPLIFICATION_SINK: &str = "amplification_sink";
|
||||||
|
const AMPLIFICATION_SOURCE: &str = "amplification_source";
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
/// Change the balance of the active sink.
|
/// Change the balance of the active sink.
|
||||||
|
|
@ -25,6 +30,8 @@ pub enum Message {
|
||||||
SinkProfileChanged(usize),
|
SinkProfileChanged(usize),
|
||||||
/// Request to change the default output volume.
|
/// Request to change the default output volume.
|
||||||
SinkVolumeChanged(u32),
|
SinkVolumeChanged(u32),
|
||||||
|
/// Toggle amplification for sink
|
||||||
|
ToggleOverAmplificationSink(bool),
|
||||||
/// Change the default input output.
|
/// Change the default input output.
|
||||||
SourceChanged(usize),
|
SourceChanged(usize),
|
||||||
/// Toggle the mute status of the input output.
|
/// Toggle the mute status of the input output.
|
||||||
|
|
@ -33,6 +40,8 @@ pub enum Message {
|
||||||
SourceProfileChanged(usize),
|
SourceProfileChanged(usize),
|
||||||
/// Request to change the input volume.
|
/// Request to change the input volume.
|
||||||
SourceVolumeChanged(u32),
|
SourceVolumeChanged(u32),
|
||||||
|
/// Toggle amplification for sink
|
||||||
|
ToggleOverAmplificationSource(bool),
|
||||||
/// Messages handled by the sound module in cosmic-settings-subscriptions
|
/// Messages handled by the sound module in cosmic-settings-subscriptions
|
||||||
Subscription(subscription::Message),
|
Subscription(subscription::Message),
|
||||||
/// Surface Action
|
/// Surface Action
|
||||||
|
|
@ -61,9 +70,29 @@ impl Into<Message> for subscription::Message {
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
entity: page::Entity,
|
entity: page::Entity,
|
||||||
model: subscription::Model,
|
model: subscription::Model,
|
||||||
|
sound_config: Option<Config>,
|
||||||
|
amplification_sink: bool,
|
||||||
|
amplification_source: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl page::Page<crate::pages::Message> for Page {
|
impl page::Page<crate::pages::Message> for Page {
|
||||||
|
fn on_enter(&mut self) -> cosmic::Task<crate::pages::Message> {
|
||||||
|
match Config::new(AUDIO_CONFIG, 1) {
|
||||||
|
Ok(config) => {
|
||||||
|
self.amplification_sink = config.get::<bool>(AMPLIFICATION_SINK).unwrap_or(true);
|
||||||
|
self.amplification_source =
|
||||||
|
config.get::<bool>(AMPLIFICATION_SOURCE).unwrap_or(false);
|
||||||
|
self.sound_config = Some(config);
|
||||||
|
}
|
||||||
|
Err(why) => {
|
||||||
|
tracing::error!(?why, "Failed to load sound config");
|
||||||
|
self.amplification_sink = true;
|
||||||
|
self.amplification_source = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Task::none()
|
||||||
|
}
|
||||||
|
|
||||||
fn content(
|
fn content(
|
||||||
&self,
|
&self,
|
||||||
sections: &mut SlotMap<section::Entity, Section<crate::pages::Message>>,
|
sections: &mut SlotMap<section::Entity, Section<crate::pages::Message>>,
|
||||||
|
|
@ -131,6 +160,16 @@ impl Page {
|
||||||
.map(|message| Message::Subscription(message).into());
|
.map(|message| Message::Subscription(message).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::ToggleOverAmplificationSink(enabled) => {
|
||||||
|
self.amplification_sink = enabled;
|
||||||
|
|
||||||
|
if let Some(config) = &self.sound_config {
|
||||||
|
if let Err(why) = config.set(AMPLIFICATION_SINK, enabled) {
|
||||||
|
tracing::error!(?why, "Failed to save over amplification setting");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message::SourceChanged(pos) => {
|
Message::SourceChanged(pos) => {
|
||||||
return self
|
return self
|
||||||
.model
|
.model
|
||||||
|
|
@ -154,6 +193,16 @@ impl Page {
|
||||||
.map(|message| Message::Subscription(message).into());
|
.map(|message| Message::Subscription(message).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Message::ToggleOverAmplificationSource(enabled) => {
|
||||||
|
self.amplification_source = enabled;
|
||||||
|
|
||||||
|
if let Some(config) = &self.sound_config {
|
||||||
|
if let Err(why) = config.set(AMPLIFICATION_SOURCE, enabled) {
|
||||||
|
tracing::error!(?why, "Failed to save over amplification setting");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Message::Subscription(message) => {
|
Message::Subscription(message) => {
|
||||||
return self
|
return self
|
||||||
.model
|
.model
|
||||||
|
|
@ -175,6 +224,8 @@ fn input() -> Section<crate::pages::Message> {
|
||||||
let device = descriptions.insert(fl!("sound-input", "device"));
|
let device = descriptions.insert(fl!("sound-input", "device"));
|
||||||
let _level = descriptions.insert(fl!("sound-input", "level"));
|
let _level = descriptions.insert(fl!("sound-input", "level"));
|
||||||
let profile = descriptions.insert(fl!("profile"));
|
let profile = descriptions.insert(fl!("profile"));
|
||||||
|
let amplification = descriptions.insert(fl!("amplification"));
|
||||||
|
let amplification_desc = descriptions.insert(fl!("amplification", "desc"));
|
||||||
|
|
||||||
Section::default()
|
Section::default()
|
||||||
.title(fl!("sound-input"))
|
.title(fl!("sound-input"))
|
||||||
|
|
@ -184,6 +235,17 @@ fn input() -> Section<crate::pages::Message> {
|
||||||
return widget::row().into();
|
return widget::row().into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let slider = if page.amplification_source {
|
||||||
|
widget::slider(0..=150, page.model.source_volume, |change| {
|
||||||
|
Message::SourceVolumeChanged(change).into()
|
||||||
|
})
|
||||||
|
.breakpoints(&[100])
|
||||||
|
} else {
|
||||||
|
widget::slider(0..=100, page.model.source_volume, |change| {
|
||||||
|
Message::SourceVolumeChanged(change).into()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
let volume_control = widget::row::with_capacity(4)
|
let volume_control = widget::row::with_capacity(4)
|
||||||
.align_y(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.push(
|
.push(
|
||||||
|
|
@ -200,12 +262,7 @@ fn input() -> Section<crate::pages::Message> {
|
||||||
.align_x(Alignment::Center),
|
.align_x(Alignment::Center),
|
||||||
)
|
)
|
||||||
.push(widget::horizontal_space().width(8))
|
.push(widget::horizontal_space().width(8))
|
||||||
.push(
|
.push(slider);
|
||||||
widget::slider(0..=150, page.model.source_volume, |change| {
|
|
||||||
Message::SourceVolumeChanged(change).into()
|
|
||||||
})
|
|
||||||
.breakpoints(&[100]),
|
|
||||||
);
|
|
||||||
let devices = widget::dropdown::popup_dropdown(
|
let devices = widget::dropdown::popup_dropdown(
|
||||||
page.model.sources(),
|
page.model.sources(),
|
||||||
Some(page.model.active_source().unwrap_or(0)),
|
Some(page.model.active_source().unwrap_or(0)),
|
||||||
|
|
@ -240,6 +297,15 @@ fn input() -> Section<crate::pages::Message> {
|
||||||
controls = controls.add(settings::item(&*section.descriptions[profile], dropdown));
|
controls = controls.add(settings::item(&*section.descriptions[profile], dropdown));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controls = controls.add(
|
||||||
|
settings::item::builder(&*section.descriptions[amplification])
|
||||||
|
.description(&*section.descriptions[amplification_desc])
|
||||||
|
.control(
|
||||||
|
widget::toggler(page.amplification_source)
|
||||||
|
.on_toggle(|t| Message::ToggleOverAmplificationSource(t).into()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
Element::from(controls)
|
Element::from(controls)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -255,11 +321,24 @@ fn output() -> Section<crate::pages::Message> {
|
||||||
let left = descriptions.insert(fl!("sound-output", "left"));
|
let left = descriptions.insert(fl!("sound-output", "left"));
|
||||||
let right = descriptions.insert(fl!("sound-output", "right"));
|
let right = descriptions.insert(fl!("sound-output", "right"));
|
||||||
// let balance = descriptions.insert(fl!("sound-output", "balance"));
|
// let balance = descriptions.insert(fl!("sound-output", "balance"));
|
||||||
|
let amplification = descriptions.insert(fl!("amplification"));
|
||||||
|
let amplification_desc = descriptions.insert(fl!("amplification", "desc"));
|
||||||
|
|
||||||
Section::default()
|
Section::default()
|
||||||
.title(fl!("sound-output"))
|
.title(fl!("sound-output"))
|
||||||
.descriptions(descriptions)
|
.descriptions(descriptions)
|
||||||
.view::<Page>(move |_binder, page, section| {
|
.view::<Page>(move |_binder, page, section| {
|
||||||
|
let slider = if page.amplification_sink {
|
||||||
|
widget::slider(0..=150, page.model.sink_volume, |change| {
|
||||||
|
Message::SinkVolumeChanged(change).into()
|
||||||
|
})
|
||||||
|
.breakpoints(&[100])
|
||||||
|
} else {
|
||||||
|
widget::slider(0..=100, page.model.sink_volume, |change| {
|
||||||
|
Message::SinkVolumeChanged(change).into()
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
let volume_control = widget::row::with_capacity(4)
|
let volume_control = widget::row::with_capacity(4)
|
||||||
.align_y(Alignment::Center)
|
.align_y(Alignment::Center)
|
||||||
.push(
|
.push(
|
||||||
|
|
@ -276,12 +355,7 @@ fn output() -> Section<crate::pages::Message> {
|
||||||
.align_x(Alignment::Center),
|
.align_x(Alignment::Center),
|
||||||
)
|
)
|
||||||
.push(widget::horizontal_space().width(8))
|
.push(widget::horizontal_space().width(8))
|
||||||
.push(
|
.push(slider);
|
||||||
widget::slider(0..=150, page.model.sink_volume, |change| {
|
|
||||||
Message::SinkVolumeChanged(change).into()
|
|
||||||
})
|
|
||||||
.breakpoints(&[100]),
|
|
||||||
);
|
|
||||||
|
|
||||||
let devices = widget::dropdown::popup_dropdown(
|
let devices = widget::dropdown::popup_dropdown(
|
||||||
page.model.sinks(),
|
page.model.sinks(),
|
||||||
|
|
@ -344,6 +418,15 @@ fn output() -> Section<crate::pages::Message> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controls = controls.add(
|
||||||
|
settings::item::builder(&*section.descriptions[amplification])
|
||||||
|
.description(&*section.descriptions[amplification_desc])
|
||||||
|
.control(
|
||||||
|
widget::toggler(page.amplification_sink)
|
||||||
|
.on_toggle(|t| Message::ToggleOverAmplificationSink(t).into()),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
Element::from(controls)
|
Element::from(controls)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -473,6 +473,9 @@ sound-input = Input
|
||||||
.device = Input device
|
.device = Input device
|
||||||
.level = Input level
|
.level = Input level
|
||||||
|
|
||||||
|
amplification = Amplification
|
||||||
|
.desc = Allows raising the volume to 150%.
|
||||||
|
|
||||||
sound-alerts = Alerts
|
sound-alerts = Alerts
|
||||||
.volume = Alerts volume
|
.volume = Alerts volume
|
||||||
.sound = Alerts sound
|
.sound = Alerts sound
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,9 @@ sound-input = Улаз
|
||||||
.device = Улазни уређај
|
.device = Улазни уређај
|
||||||
.level = Ниво улаза
|
.level = Ниво улаза
|
||||||
|
|
||||||
|
amplification = Појачавање
|
||||||
|
.desc = Омогућава повећање јачине звука до 150%.
|
||||||
|
|
||||||
sound-alerts = Упозорења
|
sound-alerts = Упозорења
|
||||||
.volume = Јачина звука упозорења
|
.volume = Јачина звука упозорења
|
||||||
.sound = Звук упозорења
|
.sound = Звук упозорења
|
||||||
|
|
|
||||||
|
|
@ -474,6 +474,9 @@ sound-input = Ulaz
|
||||||
.device = Ulazni uređaj
|
.device = Ulazni uređaj
|
||||||
.level = Nivo ulaza
|
.level = Nivo ulaza
|
||||||
|
|
||||||
|
amplification = Pojačavanje
|
||||||
|
.desc = Omogućava povećanje jačine zvuka do 150%.
|
||||||
|
|
||||||
sound-alerts = Upozorenja
|
sound-alerts = Upozorenja
|
||||||
.volume = Jačina zvuka upozorenja
|
.volume = Jačina zvuka upozorenja
|
||||||
.sound = Zvuk upozorenja
|
.sound = Zvuk upozorenja
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue