Skip to content

Commit

Permalink
Add mute for Volume and Loudness
Browse files Browse the repository at this point in the history
  • Loading branch information
HEnquist committed Jan 23, 2021
1 parent 8af4eac commit 3a8f816
Show file tree
Hide file tree
Showing 6 changed files with 449 additions and 94 deletions.
55 changes: 45 additions & 10 deletions src/basicfilters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ pub struct Volume {
ramptime_in_chunks: usize,
current_volume: PrcFmt,
target_volume: f32,
target_linear_gain: PrcFmt,
mute: bool,
ramp_start: PrcFmt,
ramp_step: usize,
samplerate: usize,
Expand All @@ -38,18 +40,23 @@ impl Volume {
name: String,
ramp_time_ms: f32,
current_volume: f32,
mute: bool,
chunksize: usize,
samplerate: usize,
processing_status: Arc<RwLock<ProcessingStatus>>,
) -> Self {
let ramptime_in_chunks =
(ramp_time_ms / (1000.0 * chunksize as f32 / samplerate as f32)).round() as usize;
let tempgain: PrcFmt = 10.0;
let target_linear_gain = tempgain.powf(current_volume as PrcFmt / 20.0);
Volume {
name,
ramptime_in_chunks,
current_volume: current_volume as PrcFmt,
ramp_start: current_volume as PrcFmt,
target_volume: current_volume as f32,
target_linear_gain,
mute,
ramp_step: 0,
samplerate,
chunksize,
Expand All @@ -65,19 +72,27 @@ impl Volume {
processing_status: Arc<RwLock<ProcessingStatus>>,
) -> Self {
let current_volume = processing_status.read().unwrap().volume;
let mute = processing_status.read().unwrap().mute;
Volume::new(
name,
conf.ramp_time,
current_volume,
mute,
chunksize,
samplerate,
processing_status,
)
}

fn make_ramp(&self) -> Vec<PrcFmt> {
let target_volume = if self.mute {
-100.0
} else {
self.target_volume
};

let ramprange =
(self.target_volume as PrcFmt - self.ramp_start) / self.ramptime_in_chunks as PrcFmt;
(target_volume as PrcFmt - self.ramp_start) / self.ramptime_in_chunks as PrcFmt;
let stepsize = ramprange / self.chunksize as PrcFmt;
(0..self.chunksize)
.map(|val| {
Expand All @@ -99,27 +114,47 @@ impl Filter for Volume {

fn process_waveform(&mut self, waveform: &mut Vec<PrcFmt>) -> Res<()> {
let shared_vol = self.processing_status.read().unwrap().volume;
let shared_mute = self.processing_status.read().unwrap().mute;

// Volume setting changed
if (shared_vol - self.target_volume).abs() > 0.001 {
if (shared_vol - self.target_volume).abs() > 0.01 || self.mute != shared_mute {
if self.ramptime_in_chunks > 0 {
trace!("starting ramp {} -> {}", self.current_volume, shared_vol);
trace!(
"starting ramp: {} -> {}, mute: {}",
self.current_volume,
shared_vol,
shared_mute
);
self.ramp_start = self.current_volume;
self.target_volume = shared_vol;
self.ramp_step = 1;
} else {
self.current_volume = shared_vol as PrcFmt;
self.target_volume = shared_vol;
trace!(
"switch volume without ramp: {} -> {}, mute: {}",
self.current_volume,
shared_vol,
shared_mute
);
self.current_volume = if shared_mute {
0.0
} else {
shared_vol as PrcFmt
};
self.ramp_step = 0;
}
self.target_volume = shared_vol;
self.target_linear_gain = if shared_mute {
0.0
} else {
let tempgain: PrcFmt = 10.0;
tempgain.powf(shared_vol as PrcFmt / 20.0)
};
self.mute = shared_mute;
}

// Not in a ramp
if self.ramp_step == 0 {
//debug!("constant gain {}", self.current_volume);
let mut gain: PrcFmt = 10.0;
gain = gain.powf(self.current_volume as PrcFmt / 20.0);
for item in waveform.iter_mut() {
*item *= gain;
*item *= self.target_linear_gain;
}
}
// Ramping
Expand Down
12 changes: 11 additions & 1 deletion src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ fn main_process() -> i32 {
)
.arg(
Arg::with_name("gain")
.help("Set initial gain in dB for Volume filters")
.help("Set initial gain in dB for Volume and Loudness filters")
.short("g")
.long("gain")
.display_order(200)
Expand All @@ -410,6 +410,13 @@ fn main_process() -> i32 {
Err(String::from("Must be a number between -120 and +20"))
}),
)
.arg(
Arg::with_name("mute")
.help("Start with Volume and Loudness filters muted")
.short("m")
.long("mute")
.display_order(200),
)
.arg(
Arg::with_name("samplerate")
.help("Override samplerate in config")
Expand Down Expand Up @@ -601,6 +608,8 @@ fn main_process() -> i32 {
.map(|s| s.parse::<f32>().unwrap())
.unwrap_or(0.0);

let initial_mute = matches.is_present("mute");

config::OVERRIDES.write().unwrap().samplerate = matches
.value_of("samplerate")
.map(|s| s.parse::<usize>().unwrap());
Expand Down Expand Up @@ -668,6 +677,7 @@ fn main_process() -> i32 {
}));
let processing_status = Arc::new(RwLock::new(ProcessingStatus {
volume: initial_volume,
mute: initial_mute,
}));

let status_structs = StatusStructs {
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ pub struct PlaybackStatus {
#[derive(Clone, Debug)]
pub struct ProcessingStatus {
pub volume: f32,
pub mute: bool,
}

#[derive(Clone)]
Expand Down
53 changes: 43 additions & 10 deletions src/loudness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ pub struct Loudness {
ramptime_in_chunks: usize,
current_volume: PrcFmt,
target_volume: f32,
target_linear_gain: PrcFmt,
mute: bool,
ramp_start: PrcFmt,
ramp_step: usize,
samplerate: usize,
Expand Down Expand Up @@ -44,8 +46,11 @@ impl Loudness {
processing_status: Arc<RwLock<ProcessingStatus>>,
) -> Self {
let current_volume = processing_status.read().unwrap().volume;
let mute = processing_status.read().unwrap().mute;
let ramptime_in_chunks =
(conf.ramp_time / (1000.0 * chunksize as f32 / samplerate as f32)).round() as usize;
let tempgain: PrcFmt = 10.0;
let target_linear_gain = tempgain.powf(current_volume as PrcFmt / 20.0);
let relboost = get_rel_boost(current_volume, conf.reference_level);
let highshelf_conf = config::BiquadParameters::Highshelf {
freq: 3500.0,
Expand All @@ -69,6 +74,8 @@ impl Loudness {
current_volume: current_volume as PrcFmt,
ramp_start: current_volume as PrcFmt,
target_volume: current_volume as f32,
target_linear_gain,
mute,
reference_level: conf.reference_level,
high_boost: conf.high_boost,
low_boost: conf.low_boost,
Expand All @@ -82,8 +89,14 @@ impl Loudness {
}

fn make_ramp(&self) -> Vec<PrcFmt> {
let target_volume = if self.mute {
-100.0
} else {
self.target_volume
};

let ramprange =
(self.target_volume as PrcFmt - self.ramp_start) / self.ramptime_in_chunks as PrcFmt;
(target_volume as PrcFmt - self.ramp_start) / self.ramptime_in_chunks as PrcFmt;
let stepsize = ramprange / self.chunksize as PrcFmt;
(0..self.chunksize)
.map(|val| {
Expand All @@ -105,27 +118,47 @@ impl Filter for Loudness {

fn process_waveform(&mut self, waveform: &mut Vec<PrcFmt>) -> Res<()> {
let shared_vol = self.processing_status.read().unwrap().volume;
let shared_mute = self.processing_status.read().unwrap().mute;

// Volume setting changed
if (shared_vol - self.target_volume).abs() > 0.001 {
if (shared_vol - self.target_volume).abs() > 0.01 || self.mute != shared_mute {
if self.ramptime_in_chunks > 0 {
trace!("starting ramp {} -> {}", self.current_volume, shared_vol);
trace!(
"starting ramp: {} -> {}, mute: {}",
self.current_volume,
shared_vol,
shared_mute
);
self.ramp_start = self.current_volume;
self.target_volume = shared_vol;
self.ramp_step = 1;
} else {
self.current_volume = shared_vol as PrcFmt;
self.target_volume = shared_vol;
trace!(
"switch volume without ramp: {} -> {}, mute: {}",
self.current_volume,
shared_vol,
shared_mute
);
self.current_volume = if shared_mute {
0.0
} else {
shared_vol as PrcFmt
};
self.ramp_step = 0;
}
self.target_volume = shared_vol;
self.target_linear_gain = if shared_mute {
0.0
} else {
let tempgain: PrcFmt = 10.0;
tempgain.powf(shared_vol as PrcFmt / 20.0)
};
self.mute = shared_mute;
}

// Not in a ramp
if self.ramp_step == 0 {
//debug!("constant gain {}", self.current_volume);
let mut gain: PrcFmt = 10.0;
gain = gain.powf(self.current_volume as PrcFmt / 20.0);
for item in waveform.iter_mut() {
*item *= gain;
*item *= self.target_linear_gain;
}
}
// Ramping
Expand Down
Loading

0 comments on commit 3a8f816

Please sign in to comment.