From a6dfec305a53c6a7618b98f43a6b4b89cfb76102 Mon Sep 17 00:00:00 2001 From: Minijackson Date: Sun, 7 Oct 2018 23:40:35 +0200 Subject: Add support for PulseEffects --- src/pa_effects.rs | 125 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 src/pa_effects.rs (limited to 'src/pa_effects.rs') diff --git a/src/pa_effects.rs b/src/pa_effects.rs new file mode 100644 index 0000000..9ed0a1f --- /dev/null +++ b/src/pa_effects.rs @@ -0,0 +1,125 @@ +use cli::pa_effects::*; +use utils::*; +use Filter; + +use failure::Error; + +use serde_json; + +const DEFAULT_PRESET: &'static str = include_str!("../res/default-pa-effects-preset.json"); + +pub fn main(cmd: Command) -> Result<(), Error> { + use cli::pa_effects::Command::*; + + match cmd { + ExportPreset(args) => export_preset(args), + } +} + +fn export_preset(args: ExportPresetCli) -> Result<(), Error> { + debug!("Parsing base preset"); + let mut preset: serde_json::Value = match args.base_preset { + Some(file) => serde_json::from_str(&read_filearg_to_str(&file)?), + None => serde_json::from_str(&DEFAULT_PRESET), + }?; + + let filter = read_filter_from_arg(&args.file)?; + + preset["output"]["equalizer"] = filter_to_eq_preset(filter); + + println!("{}", preset); + Ok(()) +} + +fn filter_to_eq_preset(mut filter: Filter) -> serde_json::Value { + if filter.frequencies.len() > 30 { + info!("More than 30 frequencies specified, taking the approximative approach"); + filter = simplify_filter(filter); + } + + let mut equalizer: serde_json::Value = json!({ + "state": "true", + "num-bands": filter.frequencies.len(), + "input-gain": 0, + "output-gain": 0, + }); + + for (i, (frequency, coeff)) in filter + .frequencies + .into_iter() + .zip(filter.coefficients) + .enumerate() + { + equalizer[format!("band{}", i)] = json!({ + "gain": coeff, + "frequency": frequency, + "type": "peak", + }); + } + + equalizer +} + +fn simplify_filter(filter: Filter) -> Filter { + //let partition_size = (filter.frequencies.len() as f64 / 30f64).floor() as usize; + let mut partition_size = filter.frequencies.len() / 30; + let step_error = filter.frequencies.len() as f64 % 30f64; + if step_error != 0f64 { + info!("The approximation will be imperfect"); + partition_size += 1; + } + + //let mut cumulative_error = 0f64; + + let frequencies = filter.frequencies.chunks(partition_size).map(|vec| { + let sum: u32 = vec.iter().sum(); + sum / vec.len() as u32 + }).collect(); + + let coefficients = filter.coefficients.chunks(partition_size).map(|vec| { + let sum: f64 = vec.iter().sum(); + sum / vec.len() as f64 + }).collect(); + + Filter { + preamp: filter.preamp, + frequencies, coefficients + } +} + +/* +trait MultiPartitionnable { + type Item; + + fn multi_partition(self, size: usize, wanted_parts: usize) -> MultiPartition + where + Self: Iterator + Sized, + { + MultiPartition { + iter: self, + size, + wanted_parts, + cumulative_error: 0f64, + } + } +} + +impl MultiPartitionnable for Iterator { + type Item = I; +} + +struct MultiPartition { + iter: I, + size: usize, + wanted_parts: usize, + cumulative_error: f64, +} + +impl Iterator for MultiPartition { + type Item = Vec; + + fn next(&mut self) -> Option { + + } +} +*/ -- cgit v1.2.3