core/dsp: document module
authorKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 19 Feb 2020 14:20:36 +0000 (15:20 +0100)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Wed, 19 Feb 2020 14:20:36 +0000 (15:20 +0100)
nihav-core/src/dsp/dct.rs
nihav-core/src/dsp/fft.rs
nihav-core/src/dsp/mdct.rs
nihav-core/src/dsp/mod.rs
nihav-core/src/dsp/window.rs

index e58ccc706d87ae5ab54f08dcde36eb0bad996bb2..2a744492f53a13c2a2f85e04689013b0c24a5ccf 100644 (file)
@@ -1,5 +1,7 @@
+//! Discrete 1-D cosine and sine transforms.
 use std::f32::consts;
 
+/// A list of DCT and DST modes.
 #[allow(non_camel_case_types)]
 #[derive(Clone,Copy,Debug,PartialEq)]
 pub enum DCTMode {
@@ -13,6 +15,7 @@ pub enum DCTMode {
     DST_IV,
 }
 
+/// DCT/DST working context.
 #[allow(dead_code)]
 pub struct DCT {
     tmp:        Vec<f32>,
@@ -26,6 +29,7 @@ pub struct DCT {
 }
 
 impl DCT {
+    /// Constructs a new context for the selected DCT or DST operation.
     pub fn new(mode: DCTMode, size: usize) -> Self {
         let bits = 31 - (size as u32).leading_zeros();
         let is_pow2 = (size & (size - 1)) == 0;
@@ -111,6 +115,7 @@ impl DCT {
             _ => unreachable!(),
         };
     }
+    /// Performs DCT/DST.
     pub fn do_dct(&mut self, src: &[f32], dst: &mut [f32]) {
         if self.can_do_fast() {
             for (i, ni) in self.perms.iter().enumerate() { dst[i] = src[*ni]; }
@@ -119,6 +124,7 @@ impl DCT {
             do_ref_dct(self.mode, src, dst, self.size);
         }
     }
+    /// Performs inplace DCT/DST.
     pub fn do_dct_inplace(&mut self, buf: &mut [f32]) {
         if self.can_do_fast() {
             swap_buf(buf, &self.swaps);
@@ -128,6 +134,7 @@ impl DCT {
             do_ref_dct(self.mode, &self.tmp, buf, self.size);
         }
     }
+    /// Returns the scale for output normalisation.
     pub fn get_scale(&self) -> f32 {
         let fsize = self.size as f32;
         match self.mode {
index 936a8aa02a62b1eb4db4749579cce5d066e4c6c1..4629f75df5a72dcbdffcc7c07b8d9aa6ada29719 100644 (file)
@@ -1,21 +1,28 @@
+//! FFT and RDFT implementation.
 use std::f32::{self, consts};
 use std::ops::{Not, Neg, Add, AddAssign, Sub, SubAssign, Mul, MulAssign};
 use std::fmt;
 
+/// Complex number.
 #[repr(C)]
 #[derive(Debug,Clone,Copy,PartialEq)]
 pub struct FFTComplex {
+    /// Real part of the numner.
     pub re: f32,
+    /// Complex part of the number.
     pub im: f32,
 }
 
 impl FFTComplex {
+    /// Calculates `exp(i * val)`.
     pub fn exp(val: f32) -> Self {
         FFTComplex { re: val.cos(), im: val.sin() }
     }
+    /// Returns `-Im + i * Re`.
     pub fn rotate(self) -> Self {
         FFTComplex { re: -self.im, im: self.re }
     }
+    /// Multiplies complex number by scalar.
     pub fn scale(self, scale: f32) -> Self {
         FFTComplex { re: self.re * scale, im: self.im * scale }
     }
@@ -86,8 +93,10 @@ impl fmt::Display for FFTComplex {
     }
 }
 
+/// Complex number with zero value.
 pub const FFTC_ZERO: FFTComplex = FFTComplex { re: 0.0, im: 0.0 };
 
+/// Calculates forward or inverse FFT in the straightforward way.
 pub fn generic_fft(data: &mut [FFTComplex], forward: bool) {
     let mut tmp = Vec::with_capacity(data.len());
     tmp.resize(data.len(), FFTC_ZERO);
@@ -523,6 +532,7 @@ impl FFTMode {
     }
 }
 
+/// FFT working context.
 pub struct FFT {
     perms:  Vec<usize>,
     swaps:  Vec<usize>,
@@ -530,14 +540,17 @@ pub struct FFT {
 }
 
 impl FFT {
+    /// Calculates Fourier transform.
     pub fn do_fft(&mut self, src: &[FFTComplex], dst: &mut [FFTComplex]) {
         for k in 0..src.len() { dst[k] = src[self.perms[k]]; }
         self.do_fft_core(dst);
     }
+    /// Calculates inverse Fourier transform.
     pub fn do_ifft(&mut self, src: &[FFTComplex], dst: &mut [FFTComplex]) {
         for k in 0..src.len() { dst[k] = src[self.perms[k]]; }
         self.do_ifft_core(dst);
     }
+    /// Performs inplace FFT.
     pub fn do_fft_inplace(&mut self, data: &mut [FFTComplex]) {
         for idx in 0..self.swaps.len() {
             let nidx = self.swaps[idx];
@@ -547,6 +560,7 @@ impl FFT {
         }
         self.do_fft_core(data);
     }
+    /// Performs inplace inverse FFT.
     pub fn do_ifft_inplace(&mut self, data: &mut [FFTComplex]) {
         for idx in 0..self.swaps.len() {
             let nidx = self.swaps[idx];
@@ -606,6 +620,9 @@ impl FFT {
     }
 }
 
+/// [`FFT`] context creator.
+///
+/// [`FFT`]: ./struct.FFT.html
 pub struct FFTBuilder {
 }
 
@@ -683,6 +700,7 @@ impl FFTBuilder {
             }
         }
     }
+    /// Constructs a new `FFT` context.
     pub fn new_fft(size: usize, forward: bool) -> FFT {
         let mut ffts: Vec<(FFTMode, FFTData)> = Vec::with_capacity(1);
         let mut perms: Vec<usize> = Vec::with_capacity(size);
@@ -725,6 +743,7 @@ impl FFTBuilder {
     }
 }
 
+/// RDFT working context.
 pub struct RDFT {
     table:  Vec<FFTComplex>,
     fft:    FFT,
@@ -738,10 +757,12 @@ fn crossadd(a: FFTComplex, b: FFTComplex) -> FFTComplex {
 }
 
 impl RDFT {
+    /// Calculates RDFT.
     pub fn do_rdft(&mut self, src: &[FFTComplex], dst: &mut [FFTComplex]) {
         dst.copy_from_slice(src);
         self.do_rdft_inplace(dst);
     }
+    /// Calculates inplace RDFT.
     pub fn do_rdft_inplace(&mut self, buf: &mut [FFTComplex]) {
         if !self.fwd {
             for n in 0..self.size/2 {
@@ -790,10 +811,14 @@ impl RDFT {
     }
 }
 
+/// [`RDFT`] context creator.
+///
+/// [`RDFT`]: ./struct.FFT.html
 pub struct RDFTBuilder {
 }
 
 impl RDFTBuilder {
+    /// Constructs a new `RDFT` context.
     pub fn new_rdft(size: usize, forward: bool, forward_fft: bool) -> RDFT {
         let mut table: Vec<FFTComplex> = Vec::with_capacity(size / 4);
         let (base, scale) = if forward { (consts::PI / (size as f32), 0.5) } else { (-consts::PI / (size as f32), 1.0) };
index f883c7f42e148e536b863c23b89acbd62b189cf7..e6ed3dc9bdfd5994aad24ff48dca12e536e27362 100644 (file)
@@ -1,6 +1,8 @@
+//! Modified Discrete Cosine transform functionality.
 use std::f32::consts;
 use super::fft::*;
 
+/// IMDCT working context.
 pub struct IMDCT {
     twiddle:    Vec<FFTComplex>,
     fft:        FFT,
@@ -19,6 +21,7 @@ fn imdct(src: &[f32], dst: &mut [f32], length: usize) {
 }*/
 
 impl IMDCT {
+    /// Constructs a new instance of `IMDCT` context.
     pub fn new(size: usize, scaledown: bool) -> Self {
         let mut twiddle: Vec<FFTComplex> = Vec::with_capacity(size / 4);
         let factor = 2.0 * consts::PI / ((8 * size) as f32);
@@ -31,6 +34,7 @@ impl IMDCT {
         z.resize(size / 2, FFTC_ZERO);
         IMDCT { twiddle, fft, size, z }
     }
+    /// Calculates IMDCT.
     pub fn imdct(&mut self, src: &[f32], dst: &mut [f32]) {
         let size2 = self.size / 2;
         let size4 = self.size / 4;
@@ -54,6 +58,7 @@ impl IMDCT {
             dst[3 * size4 + 2 * n + 1] = -self.z[size4 - n - 1].re;
         }
     }
+    /// Calculates only non-mirrored part of IMDCT.
     pub fn imdct_half(&mut self, src: &[f32], dst: &mut [f32]) {
         let size2 = self.size / 2;
         let size4 = self.size / 4;
index 8e8e6af39ba3e7a35e4d21c9a0a5af5f2a7945b6..2ff322d8361ab201e1ce6dde9a2b4378d4c823bd 100644 (file)
@@ -1,3 +1,4 @@
+//! DSP routines.
 #[cfg(feature="dct")]
 #[allow(clippy::erasing_op)]
 pub mod dct;
index 92a26556587dff8528570bd580f795f413f64457..eb350e3ecbd319208e8b9312a90cecaad6f31358 100644 (file)
@@ -1,12 +1,20 @@
+//! Window generating functions.
 use std::f32::consts;
 
+/// Known window types.
 #[derive(Debug,Clone,Copy,PartialEq)]
 pub enum WindowType {
+    /// Simple square window.
     Square,
+    /// Simple sine window.
     Sine,
+    /// Kaiser-Bessel derived window.
     KaiserBessel(f32),
 }
 
+/// Calculates window coefficients for the requested window type and size.
+///
+/// Set `half` flag to calculate only the first half of the window.
 pub fn generate_window(mode: WindowType, scale: f32, size: usize, half: bool, dst: &mut [f32]) {
     match mode {
         WindowType::Square => {