diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9e1e6d0 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +name: Continuous Integration + +on: + push: + branches: [main] + pull_request: + branches: [main] +env: + CARGO_TERM_COLOR: always + +jobs: + style: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: cargo fmt --check + uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + - uses: actions-rs/clippy-check@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + - name: cargo check + uses: actions-rs/cargo@v1 + with: + command: check + args: --verbose + + compile: + runs-on: ubuntu-latest + strategy: + matrix: + toolchain: [stable] + steps: + - uses: actions/checkout@v2 + + - uses: actions-rs/cargo@v1 + with: + command: build + args: --release diff --git a/build.rs b/build.rs index edd56b0..bd51ff7 100644 --- a/build.rs +++ b/build.rs @@ -11,8 +11,7 @@ fn write_cossin_table() { let dest_path = Path::new(&out_dir).join("cossin_table.rs"); let mut file = File::create(dest_path).unwrap(); - writeln!(file, "pub(crate) const COSSIN_DEPTH: usize = {};", DEPTH) - .unwrap(); + writeln!(file, "pub(crate) const COSSIN_DEPTH: usize = {};", DEPTH).unwrap(); write!( file, "pub(crate) const COSSIN: [u32; 1 << COSSIN_DEPTH] = [" @@ -30,8 +29,7 @@ fn write_cossin_table() { write!(file, "\n ").unwrap(); } // Use midpoint samples to save one entry in the LUT - let (sin, cos) = - (PI / 4. * ((i as f64 + 0.5) / (1 << DEPTH) as f64)).sin_cos(); + let (sin, cos) = (PI / 4. * ((i as f64 + 0.5) / (1 << DEPTH) as f64)).sin_cos(); // Add one bit accuracy to cos due to 0.5 < cos(z) <= 1 for |z| < pi/4 // The -1 LSB is cancelled when unscaling with the biased half amplitude let cos = ((cos * 2. - 1.) * AMPLITUDE - 1.).round() as u32; diff --git a/src/atan2.rs b/src/atan2.rs index bfe33db..f8f1944 100644 --- a/src/atan2.rs +++ b/src/atan2.rs @@ -63,9 +63,7 @@ pub fn atan2(y: i32, x: i32) -> i32 { // `angle` is signed Q1.31 with 1 << 31 == +- pi // Since K < 0.5 and r*(1 - r) <= 0.25 the correction product can use // 4 bits for K, and 15 bits for r and 1-r to remain within the u32 range. - let mut angle = ((r << 13) - + ((K * (r >> 1) * ((1 << 15) - (r >> 1))) >> (FP_K + 1))) - as i32; + let mut angle = ((r << 13) + ((K * (r >> 1) * ((1 << 15) - (r >> 1))) >> (FP_K + 1))) as i32; if y_greater { angle = (1 << 30) - angle; diff --git a/src/complex.rs b/src/complex.rs index 52ed263..0533939 100644 --- a/src/complex.rs +++ b/src/complex.rs @@ -42,9 +42,7 @@ impl ComplexExt for Complex { /// assert_eq!(Complex::new(i32::MAX, i32::MAX).abs_sqr(), u32::MAX - 3); /// ``` fn abs_sqr(&self) -> u32 { - (((self.re as i64) * (self.re as i64) - + (self.im as i64) * (self.im as i64)) - >> 31) as u32 + (((self.re as i64) * (self.re as i64) + (self.im as i64) * (self.im as i64)) >> 31) as u32 } /// log2(power) re full scale approximation @@ -64,8 +62,7 @@ impl ComplexExt for Complex { /// assert_eq!(Complex::new(0, 0).log2(), -64); /// ``` fn log2(&self) -> i32 { - let a = (self.re as i64) * (self.re as i64) - + (self.im as i64) * (self.im as i64); + let a = (self.re as i64) * (self.re as i64) + (self.im as i64) * (self.im as i64); -(a.leading_zeros() as i32) } diff --git a/src/pll.rs b/src/pll.rs index 1c6a782..3697102 100644 --- a/src/pll.rs +++ b/src/pll.rs @@ -53,12 +53,7 @@ impl PLL { /// /// Returns: /// A tuple of instantaneous phase and frequency (the current phase increment). - pub fn update( - &mut self, - x: Option, - shift_frequency: u8, - shift_phase: u8, - ) -> (i32, i32) { + pub fn update(&mut self, x: Option, shift_frequency: u8, shift_phase: u8) -> (i32, i32) { debug_assert!((1..=30).contains(&shift_frequency)); debug_assert!((1..=30).contains(&shift_phase)); let f = if let Some(x) = x { diff --git a/src/rpll.rs b/src/rpll.rs index e312393..5671e30 100644 --- a/src/rpll.rs +++ b/src/rpll.rs @@ -61,8 +61,8 @@ impl RPLL { // Phase using the current frequency estimate let p_sig_64 = self.ff as u64 * dx as u64; // Add half-up rounding bias and apply gain/attenuation - let p_sig = ((p_sig_64 + (1u32 << (shift_frequency - 1)) as u64) - >> shift_frequency) as u32; + let p_sig = + ((p_sig_64 + (1u32 << (shift_frequency - 1)) as u64) >> shift_frequency) as u32; // Reference phase (1 << dt2 full turns) with gain/attenuation applied let p_ref = 1u32 << (32 + self.dt2 - shift_frequency); // Update frequency lock @@ -137,14 +137,11 @@ mod test { } else { None }; - let (yi, fi) = self.rpll.update( - timestamp, - self.shift_frequency, - self.shift_phase, - ); + let (yi, fi) = self + .rpll + .update(timestamp, self.shift_frequency, self.shift_phase); - let y_ref = (self.time.wrapping_sub(self.next) as i64 - * (1i64 << 32) + let y_ref = (self.time.wrapping_sub(self.next) as i64 * (1i64 << 32) / self.period as i64) as i32; // phase error y.push(yi.wrapping_sub(y_ref) as f32 / 2f32.powi(32)); @@ -153,8 +150,7 @@ mod test { let p_sig = fi as u64 * self.period as u64; // relative frequency error f.push( - p_sig.wrapping_sub(p_ref) as i64 as f32 - / 2f32.powi(32 + self.rpll.dt2 as i32), + p_sig.wrapping_sub(p_ref) as i64 as f32 / 2f32.powi(32 + self.rpll.dt2 as i32), ); // advance time diff --git a/src/testing.rs b/src/testing.rs index 1654b62..7660896 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -25,21 +25,11 @@ pub fn isclosef(a: f32, b: f32, rtol: f32, atol: f32) -> bool { (a - b).abs() <= a.abs().max(b.abs()) * rtol + atol } -pub fn complex_isclose( - a: Complex, - b: Complex, - rtol: f32, - atol: f32, -) -> bool { +pub fn complex_isclose(a: Complex, b: Complex, rtol: f32, atol: f32) -> bool { isclosef(a.re, b.re, rtol, atol) && isclosef(a.im, b.im, rtol, atol) } -pub fn complex_allclose( - a: &[Complex], - b: &[Complex], - rtol: f32, - atol: f32, -) -> bool { +pub fn complex_allclose(a: &[Complex], b: &[Complex], rtol: f32, atol: f32) -> bool { a.iter() .zip(b) .all(|(&i, &j)| complex_isclose(i, j, rtol, atol)) diff --git a/src/tools.rs b/src/tools.rs index 9fba214..cf314b3 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -20,9 +20,7 @@ pub fn copysign(x: T, y: T) -> T where T: PartialOrd + Default + Neg, { - if (x >= T::default() && y >= T::default()) - || (x <= T::default() && y <= T::default()) - { + if (x >= T::default() && y >= T::default()) || (x <= T::default() && y <= T::default()) { x } else { -x