summaryrefslogtreecommitdiffstats
path: root/src/pa_effects.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/pa_effects.rs')
-rw-r--r--src/pa_effects.rs125
1 files changed, 125 insertions, 0 deletions
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 @@
1use cli::pa_effects::*;
2use utils::*;
3use Filter;
4
5use failure::Error;
6
7use serde_json;
8
9const DEFAULT_PRESET: &'static str = include_str!("../res/default-pa-effects-preset.json");
10
11pub fn main(cmd: Command) -> Result<(), Error> {
12 use cli::pa_effects::Command::*;
13
14 match cmd {
15 ExportPreset(args) => export_preset(args),
16 }
17}
18
19fn export_preset(args: ExportPresetCli) -> Result<(), Error> {
20 debug!("Parsing base preset");
21 let mut preset: serde_json::Value = match args.base_preset {
22 Some(file) => serde_json::from_str(&read_filearg_to_str(&file)?),
23 None => serde_json::from_str(&DEFAULT_PRESET),
24 }?;
25
26 let filter = read_filter_from_arg(&args.file)?;
27
28 preset["output"]["equalizer"] = filter_to_eq_preset(filter);
29
30 println!("{}", preset);
31 Ok(())
32}
33
34fn filter_to_eq_preset(mut filter: Filter) -> serde_json::Value {
35 if filter.frequencies.len() > 30 {
36 info!("More than 30 frequencies specified, taking the approximative approach");
37 filter = simplify_filter(filter);
38 }
39
40 let mut equalizer: serde_json::Value = json!({
41 "state": "true",
42 "num-bands": filter.frequencies.len(),
43 "input-gain": 0,
44 "output-gain": 0,
45 });
46
47 for (i, (frequency, coeff)) in filter
48 .frequencies
49 .into_iter()
50 .zip(filter.coefficients)
51 .enumerate()
52 {
53 equalizer[format!("band{}", i)] = json!({
54 "gain": coeff,
55 "frequency": frequency,
56 "type": "peak",
57 });
58 }
59
60 equalizer
61}
62
63fn simplify_filter(filter: Filter) -> Filter {
64 //let partition_size = (filter.frequencies.len() as f64 / 30f64).floor() as usize;
65 let mut partition_size = filter.frequencies.len() / 30;
66 let step_error = filter.frequencies.len() as f64 % 30f64;
67 if step_error != 0f64 {
68 info!("The approximation will be imperfect");
69 partition_size += 1;
70 }
71
72 //let mut cumulative_error = 0f64;
73
74 let frequencies = filter.frequencies.chunks(partition_size).map(|vec| {
75 let sum: u32 = vec.iter().sum();
76 sum / vec.len() as u32
77 }).collect();
78
79 let coefficients = filter.coefficients.chunks(partition_size).map(|vec| {
80 let sum: f64 = vec.iter().sum();
81 sum / vec.len() as f64
82 }).collect();
83
84 Filter {
85 preamp: filter.preamp,
86 frequencies, coefficients
87 }
88}
89
90/*
91trait MultiPartitionnable {
92 type Item;
93
94 fn multi_partition(self, size: usize, wanted_parts: usize) -> MultiPartition<Self>
95 where
96 Self: Iterator + Sized,
97 {
98 MultiPartition {
99 iter: self,
100 size,
101 wanted_parts,
102 cumulative_error: 0f64,
103 }
104 }
105}
106
107impl<I> MultiPartitionnable for Iterator<Item = I> {
108 type Item = I;
109}
110
111struct MultiPartition<I: Iterator> {
112 iter: I,
113 size: usize,
114 wanted_parts: usize,
115 cumulative_error: f64,
116}
117
118impl<I: Iterator> Iterator for MultiPartition<I> {
119 type Item = Vec<I::Item>;
120
121 fn next(&mut self) -> Option<Self::Item> {
122
123 }
124}
125*/