Skip to content

Instantly share code, notes, and snippets.

@perrygeo
Created April 6, 2020 17:00
Show Gist options
  • Save perrygeo/4388792fd070e7ba50f9ecefd7b2eef8 to your computer and use it in GitHub Desktop.
Save perrygeo/4388792fd070e7ba50f9ecefd7b2eef8 to your computer and use it in GitHub Desktop.
extern crate byteorder;
extern crate itertools;
extern crate rustfft;
use byteorder::{LittleEndian, ReadBytesExt};
use num_complex::Complex;
use rustfft::num_traits::Zero;
use rustfft::FFTplanner;
use std::fs::File;
use std::io::Seek;
use std::io::SeekFrom;
fn main() {
// TODO: read length and start position from capture metadata
// TODO: make a proper function
let path = "/home/mperry/data/rural-sw-testrun-20191219/2019-12-19T16-12-35_318EE00_F2D0791729_Rural-SW/iq_out_RX2_318EE00_0_1576800475.sigmf-data";
let mut reader = File::open(path).unwrap();
let start_pos: u64 = 33554432 * 4; // bytes from start of file
// capture["core:sample_start"] * 4 bytes
let len: usize = 4194302 * 2; // number of i16 integers to read (each 2 bytes)
// capture["scan:num_samples"] * 4 bytes / 2 bytes-per-int
// Note that a "sample" is 4 bytes, a pair of i16s
// interpreted as a complex number
assert!(len % 2 == 0);
let mut buffer: Vec<i16> = vec![0i16; len];
reader.seek(SeekFrom::Start(start_pos)).unwrap();
reader
.read_i16_into::<LittleEndian>(&mut buffer[..])
.unwrap();
// FFT not implemented for i16 yet
// otherwise we could use e.g. https://stackoverflow.com/a/54188098
// Instead we iterate, cast to complex f32 and build up a new vector
// TODO: apply simple gain offset to get voltage
let mut iq: Vec<Complex<f32>> = Vec::new();
for chunk in buffer.chunks(2) {
iq.push(Complex::new(chunk[0] as f32, chunk[1] as f32));
}
let mut output: Vec<Complex<f32>> = vec![Complex::zero(); iq.len()];
let mut planner = FFTplanner::new(false);
let fft = planner.plan_fft(iq.len());
fft.process(&mut iq, &mut output);
// println!("{:?}", &output);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment