Skip to content

Commit

Permalink
Merge pull request #43 from phip1611/fix-scaling-function-type
Browse files Browse the repository at this point in the history
better spectrum scaling function type
  • Loading branch information
phip1611 authored Jul 20, 2022
2 parents fccf00c + 4b2a37a commit 843c0de
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 12 deletions.
4 changes: 2 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ pub fn samples_fft_to_spectrum(
samples: &[f32],
sampling_rate: u32,
frequency_limit: FrequencyLimit,
scaling_fn: Option<SpectrumScalingFunction>,
scaling_fn: Option<&SpectrumScalingFunction>,
) -> Result<FrequencySpectrum, SpectrumAnalyzerError> {
// everything below two samples is unreasonable
if samples.len() < 2 {
Expand Down Expand Up @@ -247,7 +247,7 @@ fn fft_result_to_spectrum(
fft_result: &[Complex32],
sampling_rate: u32,
frequency_limit: FrequencyLimit,
scaling_fn: Option<SpectrumScalingFunction>,
scaling_fn: Option<&SpectrumScalingFunction>,
) -> Result<FrequencySpectrum, SpectrumAnalyzerError> {
let maybe_min = frequency_limit.maybe_min();
let maybe_max = frequency_limit.maybe_max();
Expand Down
36 changes: 27 additions & 9 deletions src/scaling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ pub struct SpectrumDataStats {

/// Describes the type for a function that scales/normalizes the data inside [`crate::FrequencySpectrum`].
/// The scaling only affects the value/amplitude of the frequency, but not the frequency itself.
/// It gets applied to every single element.
/// ///
/// It is applied to every single element.
///
/// A scaling function can be used for example to subtract the minimum (`min`) from each value.
/// It is optional to use the second parameter [`SpectrumDataStats`].
/// and the type works with static functions as well as dynamically created closures.
Expand All @@ -64,7 +64,7 @@ pub struct SpectrumDataStats {
///
/// This uses `f32` in favor of [`crate::FrequencyValue`] because the latter led to
/// some implementation problems.
pub type SpectrumScalingFunction<'a> = &'a dyn Fn(f32, &SpectrumDataStats) -> f32;
pub type SpectrumScalingFunction = dyn Fn(f32, &SpectrumDataStats) -> f32;

/// Calculates the base 10 logarithm of each frequency magnitude and
/// multiplies it with 20. This scaling is quite common, you can
Expand Down Expand Up @@ -136,14 +136,14 @@ pub fn divide_by_N_sqrt(val: f32, stats: &SpectrumDataStats) -> f32 {

/// Combines several scaling functions into a new single one.
///
/// Currently there is the limitation that the functions need to have
/// a `'static` lifetime. This will be fixed if someone needs this.
///
/// # Example
/// ```ignored
/// Some(&combined(&[&divide_by_N, &scale_20_times_log10]))
/// let fncs = combined(&[&divide_by_N, &scale_20_times_log10]);
/// ```
#[allow(clippy::type_complexity)]
pub fn combined<'a>(
fncs: &'a [SpectrumScalingFunction<'a>],
) -> Box<dyn Fn(f32, &SpectrumDataStats) -> f32 + 'a> {
pub fn combined(fncs: &'static [&SpectrumScalingFunction]) -> Box<SpectrumScalingFunction> {
Box::new(move |val, stats| {
let mut val = val;
for fnc in fncs {
Expand All @@ -169,7 +169,7 @@ mod tests {
n: data.len() as f32,
};
// check that type matches
let scaling_fn: SpectrumScalingFunction = &scale_to_zero_to_one;
let scaling_fn: &SpectrumScalingFunction = &scale_to_zero_to_one;
let scaled_data = data
.into_iter()
.map(|x| scaling_fn(x, &stats))
Expand All @@ -179,4 +179,22 @@ mod tests {
float_cmp::approx_eq!(f32, *expected_val, *actual_val, ulps = 3);
}
}

// make sure this compiles
#[test]
fn test_combined_compiles() {
let _combined_static = combined(&[&scale_20_times_log10, &divide_by_N, &divide_by_N_sqrt]);

// doesn't compile yet.. fix this once someone requests it
/*let closure_scaling_fnc = |frequency_magnitude: f32, _stats: &SpectrumDataStats| {
0.0
};
let _combined_dynamic = combined(&[
&scale_20_times_log10,
&divide_by_N,
&divide_by_N_sqrt,
&closure_scaling_fnc,
]);*/
}
}
2 changes: 1 addition & 1 deletion src/spectrum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ impl FrequencySpectrum {
#[inline(always)]
pub fn apply_scaling_fn(
&self,
scaling_fn: SpectrumScalingFunction,
scaling_fn: &SpectrumScalingFunction,
) -> Result<(), SpectrumAnalyzerError> {
{
// drop RefMut<> from borrow_mut() before calc_statistics
Expand Down

0 comments on commit 843c0de

Please sign in to comment.