91 lines
2.3 KiB
Rust
91 lines
2.3 KiB
Rust
use num_complex::Complex;
|
|
use std::error::Error;
|
|
use std::fs::File;
|
|
use std::io::{BufReader, ErrorKind, Read};
|
|
|
|
pub type IqSample = Complex<f32>;
|
|
|
|
// Data chunk
|
|
// #[derive(Debug)]
|
|
// pub struct IqChunk {
|
|
// pub samples: Vec<IqSample>,
|
|
// }
|
|
//
|
|
// impl IqChunk {
|
|
// pub fn new() -> Self {
|
|
// IqChunk {
|
|
// samples: Vec::<IqSample>::new(),
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
pub struct FileSource {
|
|
// Buffer
|
|
pub reader: BufReader<File>,
|
|
// Hackrf I & Q 8 bits
|
|
pub raw_buffer: Vec<u8>,
|
|
// Size of a sample chunk
|
|
pub chunk_samples_size: usize,
|
|
// raw_buffer position (in samples)
|
|
pub cursor: usize,
|
|
// The length of the file in samples
|
|
pub len: u64,
|
|
}
|
|
|
|
impl FileSource {
|
|
pub fn new(file_path: &str, chunk_samples_size: usize) -> Result<Self, Box<dyn Error>> {
|
|
let file = File::open(file_path)?;
|
|
let len = file.metadata().unwrap().len() / 2;
|
|
// Init buffer with size 16 Mo
|
|
let reader = BufReader::with_capacity(16 * 1024 * 1024, file);
|
|
|
|
// 1 sample = 2 bytes (1 byte : I, 1 byte : Q)
|
|
let raw_reader = vec![0; chunk_samples_size * 2];
|
|
|
|
Ok(Self {
|
|
reader,
|
|
raw_buffer: raw_reader,
|
|
chunk_samples_size,
|
|
cursor: chunk_samples_size,
|
|
len,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl ExactSizeIterator for FileSource {}
|
|
|
|
impl Iterator for FileSource {
|
|
type Item = Result<IqSample, Box<dyn Error>>;
|
|
|
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
(self.len as usize, Some(self.len as usize))
|
|
}
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
if self.cursor >= self.chunk_samples_size {
|
|
// Buffer read chunk
|
|
match self.reader.read_exact(&mut self.raw_buffer) {
|
|
Ok(_) => {}
|
|
|
|
// EOF
|
|
Err(e) if e.kind() == ErrorKind::UnexpectedEof => {
|
|
return None;
|
|
}
|
|
|
|
Err(e) => {
|
|
return Some(Err(e.into()));
|
|
}
|
|
}
|
|
self.cursor = 0;
|
|
}
|
|
|
|
// Buffer read sample
|
|
let i = (self.raw_buffer[self.cursor * 2] as i8) as f32 / 128.0;
|
|
let q = (self.raw_buffer[self.cursor * 2 + 1] as i8) as f32 / 128.0;
|
|
|
|
self.cursor += 1;
|
|
|
|
Some(Ok(IqSample::new(i, q)))
|
|
}
|
|
}
|