Skip to content

Commit 25b3c2d

Browse files
authored
Add clippy github action (#8)
Add clippy github action Use cargo clippy to lint rust projects and fix the current outstanding lint issues. Signed-off-by: Fredrik Lönnegren <[email protected]>
1 parent e5a9179 commit 25b3c2d

File tree

2 files changed

+72
-35
lines changed

2 files changed

+72
-35
lines changed

.github/workflows/build.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ on:
88
permissions:
99
contents: read
1010

11+
env:
12+
RUSTFLAGS: "-Dwarnings"
13+
1114
jobs:
1215
lint:
1316
name: lint
@@ -22,6 +25,13 @@ jobs:
2225
with:
2326
version: v2.5.0
2427

28+
clippy_check:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@v5
32+
- name: Run Clippy
33+
run: cargo clippy --all-targets --all-features
34+
2535
build-bin:
2636
name: build binaries
2737
runs-on: ubuntu-latest

fm-streamer/src/main.rs

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
// Based on the simple_fm example from https://github.com/ccostes/rtl-sdr-rs/
22

33
use clap::Parser;
4-
use core::alloc::Layout;
5-
use ctrlc;
64
use log::info;
75
use num_complex::Complex;
86
use rtl_sdr_rs::{error::Result, DeviceId, RtlSdr, DEFAULT_BUF_LENGTH};
97
use std::f64::consts::PI;
10-
use std::fs::File;
11-
use std::os::fd::AsRawFd;
128
use std::io::Write;
139
use std::sync::atomic::{AtomicBool, Ordering};
1410
use std::sync::mpsc::{self, Receiver, Sender};
@@ -26,16 +22,14 @@ struct Args {
2622
}
2723

2824
// Radio and demodulation config
29-
const FREQUENCY: u32 = 101_900_000; // Frequency in Hz
3025
const SAMPLE_RATE: u32 = 170_000; // Demodulation sample rate, 170kHz
3126
const RATE_RESAMPLE: u32 = 32_000; // Output sample rate, 32kHz
3227

33-
// RTL Device Index
34-
const RTL_INDEX: usize = 0;
35-
3628
fn main() {
3729
let args = Args::parse();
3830

31+
let frequency = parse_frequency(args.frequency);
32+
3933
// Printing to stdout will break audio output, so use this to log to stderr instead
4034
stderrlog::new().verbosity(log::Level::Info).init().unwrap();
4135

@@ -47,7 +41,7 @@ fn main() {
4741
.unwrap();
4842

4943
// Get radio and demodulation settings for given frequency and sample rate
50-
let (radio_config, demod_config) = optimal_settings(FREQUENCY, SAMPLE_RATE);
44+
let (radio_config, demod_config) = optimal_settings(frequency, SAMPLE_RATE);
5145

5246
// Channel to pass receive data from receiver thread to processor thread
5347
let (tx, rx) = mpsc::channel();
@@ -62,6 +56,24 @@ fn main() {
6256
receive_thread.join().unwrap();
6357
}
6458

59+
fn parse_frequency(frequency: String) -> u32 {
60+
let suffix = frequency.chars().last().unwrap();
61+
let stripped = frequency.strip_suffix(['G', 'g', 'M', 'm', 'K', 'k']);
62+
63+
match suffix {
64+
'G' | 'g' => {
65+
(stripped.unwrap().parse::<f32>().unwrap() * 1_000_000_000.0) as u32
66+
},
67+
'M' | 'm' => {
68+
(stripped.unwrap().parse::<f32>().unwrap() * 1_000_000.0) as u32
69+
},
70+
'K' | 'k' => {
71+
(stripped.unwrap().parse::<f32>().unwrap() * 1_000.0) as u32
72+
},
73+
_ => frequency.parse().unwrap(),
74+
}
75+
}
76+
6577
/// Thread to open SDR device and send received data to the demod thread until
6678
/// SHUTDOWN flag is set to true.
6779
fn receive(shutdown: &AtomicBool, radio_config: RadioConfig, tx: Sender<Vec<u8>>) {
@@ -103,7 +115,7 @@ fn receive(shutdown: &AtomicBool, radio_config: RadioConfig, tx: Sender<Vec<u8>>
103115
break;
104116
}
105117
// Send received data through the channel to the processor thread
106-
tx.send(buf.to_vec());
118+
let _ = tx.send(buf.to_vec());
107119
}
108120
// Shut down the device and exit
109121
info!("Close");
@@ -179,15 +191,15 @@ fn optimal_settings(freq: u32, rate: u32) -> (RadioConfig, DemodConfig) {
179191
}
180192
(
181193
RadioConfig {
182-
capture_freq: capture_freq,
183-
capture_rate: capture_rate,
194+
capture_freq,
195+
capture_rate,
184196
},
185197
DemodConfig {
186198
rate_in: SAMPLE_RATE,
187199
rate_out: SAMPLE_RATE,
188200
rate_resample: RATE_RESAMPLE,
189-
downsample: downsample,
190-
output_scale: output_scale,
201+
downsample,
202+
output_scale,
191203
},
192204
)
193205
}
@@ -221,7 +233,7 @@ struct Demod {
221233
impl Demod {
222234
fn new(config: DemodConfig) -> Self {
223235
Demod {
224-
config: config,
236+
config,
225237
prev_index: 0,
226238
now_lpr: 0,
227239
prev_lpr_index: 0,
@@ -243,8 +255,7 @@ impl Demod {
243255
let demodulated = self.fm_demod(lowpassed);
244256

245257
// Resample and return result
246-
let output = self.low_pass_real(demodulated);
247-
output
258+
self.low_pass_real(demodulated)
248259
}
249260

250261
/// Performs a 90-degree rotation in the complex plane on a vector of bytes
@@ -273,8 +284,8 @@ impl Demod {
273284
/// Applies a low-pass filter on a vector of complex values
274285
fn low_pass_complex(&mut self, buf: Vec<Complex<i32>>) -> Vec<Complex<i32>> {
275286
let mut res = vec![];
276-
for orig in 0..buf.len() {
277-
self.lp_now += buf[orig];
287+
for i in &buf {
288+
self.lp_now += i;
278289

279290
self.prev_index += 1;
280291
if self.prev_index < self.config.downsample as usize {
@@ -325,20 +336,19 @@ impl Demod {
325336
if x == 0 && y == 0 {
326337
return 0;
327338
}
328-
let mut yabs = y;
329-
if yabs < 0 {
330-
yabs = -yabs;
331-
}
332-
let angle;
333-
if x >= 0 {
334-
angle = pi4 - (pi4 as i64 * (x - yabs) as i64) as i32 / (x + yabs);
339+
let yabs = y.abs();
340+
341+
let angle = if x >= 0 {
342+
pi4 - (pi4 as i64 * (x - yabs) as i64) as i32 / (x + yabs)
335343
} else {
336-
angle = pi34 - (pi4 as i64 * (x + yabs) as i64) as i32 / (yabs - x);
337-
}
344+
pi34 - (pi4 as i64 * (x + yabs) as i64) as i32 / (yabs - x)
345+
};
346+
338347
if y < 0 {
339348
return -angle;
340349
}
341-
return angle;
350+
351+
angle
342352
}
343353

344354
/// Applies a low-pass filter to a vector of real-valued data
@@ -370,8 +380,8 @@ fn output(buf: Vec<i16>) {
370380
let slice_u8: &[u8] = unsafe {
371381
slice::from_raw_parts(buf.as_ptr() as *const u8, buf.len() * mem::size_of::<i16>())
372382
};
373-
out.write_all(slice_u8);
374-
out.flush();
383+
let _ = out.write_all(slice_u8);
384+
let _ = out.flush();
375385
}
376386

377387
/// Convert a vector of i16 complex components (real and imaginary) to a vector of i32 Complex values
@@ -388,6 +398,24 @@ fn buf_to_complex(buf: Vec<i16>) -> Vec<Complex<i32>> {
388398
#[cfg(test)]
389399
mod tests {
390400
use super::*;
401+
#[test]
402+
fn test_parse_frequency() {
403+
let freq = parse_frequency("10".to_string());
404+
assert_eq!(freq, 10);
405+
406+
let freq = parse_frequency("20K".to_string());
407+
assert_eq!(freq, 20_000);
408+
409+
let freq = parse_frequency("90M".to_string());
410+
assert_eq!(freq, 90_000_000);
411+
412+
let freq = parse_frequency("1.9M".to_string());
413+
assert_eq!(freq, 1_900_000);
414+
415+
let freq = parse_frequency("2.4G".to_string());
416+
assert_eq!(freq, 2_400_000_000);
417+
}
418+
391419
#[test]
392420
fn test_lowpass() {
393421
// Based on data from rtl_fm
@@ -401,7 +429,7 @@ mod tests {
401429
];
402430
let lp_complex = buf_to_complex(lowpass);
403431

404-
let (_, demod_config) = optimal_settings(FREQUENCY, SAMPLE_RATE);
432+
let (_, demod_config) = optimal_settings(100_000_000, SAMPLE_RATE);
405433
let mut demod = Demod::new(demod_config);
406434

407435
let buf_signed = vec![
@@ -454,9 +482,8 @@ mod tests {
454482
76, 1228, 2517, 3241, 3490, -6608, -11786, -1057, 3088, 805, -14996, -783, -12842,
455483
9551, 11213,
456484
];
457-
let result = vec![2588, 4030, -1212, -3430, 2585, 2110, -6110];
458485

459-
let (_, demod_config) = optimal_settings(FREQUENCY, SAMPLE_RATE);
486+
let (_, demod_config) = optimal_settings(100_000_000, SAMPLE_RATE);
460487
let mut demod = Demod::new(demod_config);
461488

462489
let demodulated = demod.fm_demod(lp_complex);
@@ -473,7 +500,7 @@ mod tests {
473500
];
474501
let result = vec![2588, 4030, -1212, -3430, 2585, 2110, -6110];
475502

476-
let (_, demod_config) = optimal_settings(FREQUENCY, SAMPLE_RATE);
503+
let (_, demod_config) = optimal_settings(100_000_000, SAMPLE_RATE);
477504
let mut demod = Demod::new(demod_config);
478505

479506
let output = demod.low_pass_real(demodulated);

0 commit comments

Comments
 (0)