Skip to content

Commit

Permalink
cargo fmt ja clippy
Browse files Browse the repository at this point in the history
  • Loading branch information
ollpu committed May 16, 2021
1 parent 86b6dae commit 98f3564
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 72 deletions.
121 changes: 83 additions & 38 deletions examples/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ fn main() -> Result<(), Box<dyn Error>> {
let sample_rate = match setup_audio(publish_handle) {
Ok(s) => s,
Err(e) => {
eprintln!("Mikrofonin avaaminen ei onnistunut: {:?}\nVoit silti käyttää testisignaalia!", e);
eprintln!(
"Mikrofonin avaaminen ei onnistunut: {:?}\nVoit silti käyttää testisignaalia!",
e
);
44100.
}
};
Expand All @@ -40,7 +43,9 @@ fn err_fn(err: cpal::StreamError) {
}
fn setup_audio(publish_handle: ring_buffer::Producer<f32>) -> Result<f32, Box<dyn Error>> {
let host = cpal::default_host();
let device = host.default_input_device().ok_or("Äänilaitetta ei löydetty")?;
let device = host
.default_input_device()
.ok_or("Äänilaitetta ei löydetty")?;
eprintln!("Käytetään äänilaitetta: \"{}\"", device.name()?);
let config = device.default_input_config()?;
let sample_format = config.sample_format();
Expand Down Expand Up @@ -191,20 +196,42 @@ impl Widget for Plot {

match self.audio_source {
AudioSource::Microphone => {
while self.consume_handle.pop_full(self.display.get_buffer_mut()).is_ok() {
self.display.update_match(self.stabilize_enabled, self.memory_decay, self.display_decay);
while self
.consume_handle
.pop_full(self.display.get_buffer_mut())
.is_ok()
{
self.display.update_match(
self.stabilize_enabled,
self.memory_decay,
self.display_decay,
);
}
}
AudioSource::TestSine => {
self.consume_handle.discard_all();
if self.test_signal_generator.get(self.display.get_buffer_mut(), false) {
self.display.update_match(self.stabilize_enabled, self.memory_decay, self.display_decay);
if self
.test_signal_generator
.get(self.display.get_buffer_mut(), false)
{
self.display.update_match(
self.stabilize_enabled,
self.memory_decay,
self.display_decay,
);
}
}
AudioSource::TestModulating => {
self.consume_handle.discard_all();
if self.test_signal_generator.get(self.display.get_buffer_mut(), true) {
self.display.update_match(self.stabilize_enabled, self.memory_decay, self.display_decay);
if self
.test_signal_generator
.get(self.display.get_buffer_mut(), true)
{
self.display.update_match(
self.stabilize_enabled,
self.memory_decay,
self.display_decay,
);
}
}
}
Expand All @@ -214,17 +241,31 @@ impl Widget for Plot {
let frequency = self.sample_rate / interval;

// Draw offset indicator
canvas.clear_rect((x + 0.4 * w) as u32, (y + h - 40.) as u32, (0.2 * w) as u32, 15, Color::rgb(70, 70, 70));
canvas.clear_rect(
(x + 0.4 * w) as u32,
(y + h - 40.) as u32,
(0.2 * w) as u32,
15,
Color::rgb(70, 70, 70),
);
let pos = offset as f32 / N as f32;
let span = M as f32 / N as f32;
canvas.clear_rect((x + (0.4 + 0.2 * pos) * w) as u32, (y + h - 40.) as u32, (0.2 * span * w) as u32, 15, Color::rgb(90, 90, 90));
canvas.clear_rect(
(x + (0.4 + 0.2 * pos) * w) as u32,
(y + h - 40.) as u32,
(0.2 * span * w) as u32,
15,
Color::rgb(90, 90, 90),
);
// Draw frequency
if self.stabilize_enabled {
let mut paint = femtovg::Paint::default();
paint.set_font(&[state.fonts.regular.unwrap()]);
paint.set_font_size(24.);
paint.set_color(Color::white());
canvas.fill_text(x + 20., y + h - 21., format!("{:.2} Hz", frequency), paint).unwrap();
canvas
.fill_text(x + 20., y + h - 21., format!("{:.2} Hz", frequency), paint)
.unwrap();
}
if self.show_memory {
let mut path = Path::new();
Expand All @@ -242,12 +283,12 @@ impl Widget for Plot {
canvas.stroke_path(&mut path, Paint::color(Color::rgb(12, 170, 255)));
}
let mut path = Path::new();
let mut points = self
.display
.get_display()
.iter()
.enumerate()
.map(|(i, v)| (x + w / M as f32 * (i as f32 - residual), y + h / 2. - v * h / 2.));
let mut points = self.display.get_display().iter().enumerate().map(|(i, v)| {
(
x + w / M as f32 * (i as f32 - residual),
y + h / 2. - v * h / 2.,
)
});
let (x, y) = points.next().unwrap();
path.move_to(x, y);
for (x, y) in points {
Expand Down Expand Up @@ -310,35 +351,39 @@ impl Widget for Control {
entity.set_element(state, "control");
entity.set_layout_type(state, LayoutType::Column);
let (_, _, dropdown) = Dropdown::new("Äänilähde").build(state, entity, |b| {
b
.set_height(Pixels(30.0))
.set_width(Stretch(1.0))
b.set_height(Pixels(30.0)).set_width(Stretch(1.0))
});
let options = List::new().build(state, dropdown, |b| b);
CheckButton::new(true)
.on_checked(Event::new(PlotControlEvent::Source(AudioSource::Microphone)).propagate(Propagation::All))
.on_checked(
Event::new(PlotControlEvent::Source(AudioSource::Microphone))
.propagate(Propagation::All),
)
.build(state, options, |b| {
b
.set_text("Mikrofoni")
.set_height(Pixels(30.0))
.set_child_left(Pixels(5.0))
});
b.set_text("Mikrofoni")
.set_height(Pixels(30.0))
.set_child_left(Pixels(5.0))
});
CheckButton::new(false)
.on_checked(Event::new(PlotControlEvent::Source(AudioSource::TestSine)).propagate(Propagation::All))
.on_checked(
Event::new(PlotControlEvent::Source(AudioSource::TestSine))
.propagate(Propagation::All),
)
.build(state, options, |b| {
b
.set_text("Testi: Siniaalto")
.set_height(Pixels(30.0))
.set_child_left(Pixels(5.0))
});
b.set_text("Testi: Siniaalto")
.set_height(Pixels(30.0))
.set_child_left(Pixels(5.0))
});
CheckButton::new(false)
.on_checked(Event::new(PlotControlEvent::Source(AudioSource::TestModulating)).propagate(Propagation::All))
.on_checked(
Event::new(PlotControlEvent::Source(AudioSource::TestModulating))
.propagate(Propagation::All),
)
.build(state, options, |b| {
b
.set_text("Testi: Vaihtuva")
.set_height(Pixels(30.0))
.set_child_left(Pixels(5.0))
});
b.set_text("Testi: Vaihtuva")
.set_height(Pixels(30.0))
.set_child_left(Pixels(5.0))
});
let checkbox = Row::new().build(state, entity, |builder| builder.class("check"));
Checkbox::new(true)
.on_checked(Event::new(PlotControlEvent::Stabilize(true)).propagate(Propagation::All))
Expand Down
6 changes: 5 additions & 1 deletion examples/test_signal/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ impl TestSignal {
} else {
modulator = 0.;
}
*sample = 0.8 * osc(&mut self.oscillator_phase, BASE_FREQUENCY * (1. + 0.109 * modulator));
*sample = 0.8
* osc(
&mut self.oscillator_phase,
BASE_FREQUENCY * (1. + 0.109 * modulator),
);
}
self.counter = 1;
true
Expand Down
4 changes: 2 additions & 2 deletions src/correlation_match.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

pub mod parabolic_interpolation;
use parabolic_interpolation::parabolic_interpolation_minimum;

Expand Down Expand Up @@ -139,7 +138,8 @@ impl CorrelationMatch {
min_position = end as Num;
min_value = self.result_buffer[end];
}
for (index, [a, b, c]) in IterWindows::from(self.result_buffer.iter().copied()).enumerate() {
for (index, [a, b, c]) in IterWindows::from(self.result_buffer.iter().copied()).enumerate()
{
if let Some((x, y)) = parabolic_interpolation_minimum(a, b, c) {
let position = index as Num + x;
self.minima.push((position, y));
Expand Down
1 change: 0 additions & 1 deletion src/correlation_match/parabolic_interpolation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use crate::math::*;

const EPS: Num = 1e-8;
Expand Down
2 changes: 0 additions & 2 deletions src/cross_correlation.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

use crate::fft;
use crate::math::*;
use std::array::IntoIter;
Expand Down Expand Up @@ -30,7 +29,6 @@ impl CrossCorrelation {
/// Compute cross correlation including partially overlapping positions.
/// Length of `a` and `b` must not exceed the maximum size given in `new`.
/// Returns an interator of the results. The length of the result is `a.len() + b.len() - 1`.
#[allow(dead_code)]
pub fn compute(&mut self, a: &[Num], b: &[Num]) -> impl Iterator<Item = Num> + '_ {
self.compute_raw(a, b);
// The beginning of the result is read from the end of the buffer, rest normally
Expand Down
38 changes: 23 additions & 15 deletions src/display.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Wrapper for [`CorrelationMatch`], providing functionality for displaying a waveform.
use crate::math::*;
use crate::util::{shift_right, shift_left, shift_right_fill, shift_left_fill};
use crate::correlation_match::CorrelationMatch;
use crate::math::*;
use crate::util::{shift_left, shift_left_fill, shift_right, shift_right_fill};

/// Stores a prepared [`CorrelationMatch`] and buffers for display and memory.
pub struct DisplayBuffer {
Expand Down Expand Up @@ -49,16 +49,22 @@ impl DisplayBuffer {
///
/// Missing data is retrieved from the input buffer, or replaced with zeros if not available.
pub fn scroll(&mut self, amount: i32) {
if amount > 0 {
let amount = amount as usize;
shift_right_fill(&mut self.buffer, amount, 0.);
shift_right(&mut self.display, &self.buffer[self.offset..][..amount]);
shift_right(&mut self.memory, &self.buffer[self.offset..][..amount]);
} else if amount < 0 {
let amount = -amount as usize;
shift_left_fill(&mut self.buffer, amount, 0.);
shift_left(&mut self.display, &self.buffer[self.offset + self.size - amount..][..amount]);
shift_left(&mut self.memory, &self.buffer[self.offset + self.size - amount..][..amount]);
match amount {
amount if amount > 0 => {
let amount = amount as usize;
shift_right_fill(&mut self.buffer, amount, 0.);
let replace_range = &self.buffer[self.offset..][..amount];
shift_right(&mut self.display, replace_range);
shift_right(&mut self.memory, replace_range);
}
amount if amount < 0 => {
let amount = -amount as usize;
shift_left_fill(&mut self.buffer, amount, 0.);
let replace_range = &self.buffer[self.offset + self.size - amount..][..amount];
shift_left(&mut self.display, replace_range);
shift_left(&mut self.memory, replace_range);
}
_ => {}
}
}

Expand All @@ -85,14 +91,16 @@ impl DisplayBuffer {
if stabilize {
let (offset, interval) =
self.correlation_matcher
.compute(&self.buffer, &self.memory, &self.weight);
.compute(&self.buffer, &self.memory, &self.weight);
let rounded = offset.round();
self.offset = rounded as usize;
self.residual += offset - rounded;
self.offset = (self.offset as i64 + self.residual as i64).clamp(0, self.buffer.len() as i64 - 1) as usize;
self.offset = (self.offset as i64 + self.residual as i64)
.clamp(0, self.buffer.len() as i64 - 1) as usize;
self.residual = self.residual.fract();
if let Some(interval) = interval {
self.average_period = period_decay * interval + (1. - period_decay) * self.average_period;
self.average_period =
period_decay * interval + (1. - period_decay) * self.average_period;
}
}
for (index, item) in self.memory.iter_mut().enumerate() {
Expand Down
2 changes: 1 addition & 1 deletion src/fft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::math::*;
/// Implements the FFT, i.e. Fast Fourier Transform, and its inverse.
///
/// This structure is initialized beforehand, and contains twiddle-factors for
/// a specific transform size.
/// a specific transform size.
pub struct Fft {
size: usize,
twiddle_factors: Vec<Complex>,
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
mod display;
pub use display::DisplayBuffer;
mod correlation_match;
pub use correlation_match::CorrelationMatch;
pub use correlation_match::parabolic_interpolation::parabolic_interpolation_minimum;
pub use correlation_match::CorrelationMatch;
mod cross_correlation;
pub use cross_correlation::CrossCorrelation;
mod fft;
Expand Down
14 changes: 9 additions & 5 deletions src/test/test_correlation_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ mod test_parabolic_interpolation;

use crate::correlation_match::CorrelationMatch;

use crate::math::*;
use super::util::*;
use crate::math::*;

use rand::prelude::*;
use rand::rngs::SmallRng;
Expand Down Expand Up @@ -40,12 +40,14 @@ fn correlation_match_subsample_accuracy() {
const N: usize = 32;
let mut matcher = CorrelationMatch::new(N);
let pos = 5.315237;
let a: Vec<_> = (0..N).map(|i| ((i as f32 / N as f32) * 2. * PI).sin()).collect();
let b: Vec<_> = (0..N/2)
let a: Vec<_> = (0..N)
.map(|i| ((i as f32 / N as f32) * 2. * PI).sin())
.collect();
let b: Vec<_> = (0..N / 2)
.map(|i| i as f32 + pos)
.map(|i| ((i / N as f32) * 2. * PI).sin())
.collect();
let w = vec![1.; N/2];
let w = vec![1.; N / 2];
let (offset, _) = matcher.compute(&a, &b, &w);
assert!(float_eq(offset, pos, 2));
}
Expand All @@ -56,7 +58,9 @@ fn correlation_match_period() {
const M: usize = 16;
let mut matcher = CorrelationMatch::new(N);
let period = 6.137241;
let a: Vec<_> = (0..N).map(|i| ((i as f32 / period) * 2. * PI).sin()).collect();
let a: Vec<_> = (0..N)
.map(|i| ((i as f32 / period) * 2. * PI).sin())
.collect();
let pos = 13;
let w = vec![1.; M];
let (_, measured_period) = matcher.compute(&a, &a[pos..][..M], &w);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::test::util::*;
use crate::correlation_match::parabolic_interpolation::parabolic_interpolation_minimum;
use crate::test::util::*;

#[test]
fn simple_parabola_minimum() {
Expand All @@ -19,4 +19,3 @@ fn random_parabola_minimum() {
fn parabola_minimum_degenerate() {
assert!(parabolic_interpolation_minimum(1., 2., 3.).is_none());
}

2 changes: 1 addition & 1 deletion src/test/test_util.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::util::{shift_left, shift_right, shift_left_fill, shift_right_fill, IterWindows};
use crate::util::{shift_left, shift_left_fill, shift_right, shift_right_fill, IterWindows};

#[test]
fn shift_left_example() {
Expand Down
5 changes: 2 additions & 3 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ pub struct IterWindows<T, I, const N: usize> {
array: [T; N],
}

impl<T: Copy + Default, I: Iterator<Item=T>, const N: usize> IterWindows<T, I, N>
{
impl<T: Copy + Default, I: Iterator<Item = T>, const N: usize> IterWindows<T, I, N> {
/// Construct an `IterWindows` from another iterator.
pub fn from(mut source: I) -> Self {
let mut array = [Default::default(); N];
Expand All @@ -69,7 +68,7 @@ impl<T: Copy + Default, I: Iterator<Item=T>, const N: usize> IterWindows<T, I, N
}
}

impl<T: Copy + Default, I: Iterator<Item=T>, const N: usize> Iterator for IterWindows<T, I, N> {
impl<T: Copy + Default, I: Iterator<Item = T>, const N: usize> Iterator for IterWindows<T, I, N> {
type Item = [T; N];
fn next(&mut self) -> Option<Self::Item> {
if let Some(item) = self.source.next() {
Expand Down

0 comments on commit 98f3564

Please sign in to comment.