fm demod
This commit is contained in:
@ -1,4 +1,6 @@
|
||||
use crate::iq_reader::{IqChunk, IqSample};
|
||||
use crate::iq_reader::IqSample;
|
||||
|
||||
pub type Phase = f32;
|
||||
|
||||
pub struct FmDemod<I> {
|
||||
pub inner: I,
|
||||
@ -13,9 +15,10 @@ impl<I> FmDemod<I> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_sample(&mut self, sample: IqSample) -> IqSample {
|
||||
// TODO: FM Demodulation
|
||||
todo!();
|
||||
pub fn process_sample(&mut self, sample: IqSample) -> Phase {
|
||||
let phase_diff = sample * self.prev_sample.conj();
|
||||
self.prev_sample = sample;
|
||||
phase_diff.arg()
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,7 +26,7 @@ impl<I, E> Iterator for FmDemod<I>
|
||||
where
|
||||
I: Iterator<Item = Result<IqSample, E>>,
|
||||
{
|
||||
type Item = Result<IqSample, E>;
|
||||
type Item = Result<Phase, E>;
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self.inner.next()? {
|
||||
|
||||
@ -6,18 +6,18 @@ 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
// #[derive(Debug)]
|
||||
// pub struct IqChunk {
|
||||
// pub samples: Vec<IqSample>,
|
||||
// }
|
||||
//
|
||||
// impl IqChunk {
|
||||
// pub fn new() -> Self {
|
||||
// IqChunk {
|
||||
// samples: Vec::<IqSample>::new(),
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
pub struct FileSource {
|
||||
// Buffer
|
||||
|
||||
@ -17,11 +17,12 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
let pipeline = source
|
||||
.agc(20_000_000.0, 1.0, 0.001, 100.0)
|
||||
.fir::<64>(taps, 4);
|
||||
.fir::<64>(taps, 4)
|
||||
.demodulate();
|
||||
|
||||
for sample_r in pipeline {
|
||||
let sample = sample_r?;
|
||||
println!("sample : {} + i{}", sample.re, sample.im);
|
||||
for phase_r in pipeline {
|
||||
let phase = phase_r?;
|
||||
println!("phase : {}", phase);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::agc::Agc;
|
||||
use crate::fir::Fir;
|
||||
use crate::fm_demod::FmDemod;
|
||||
use crate::iq_reader::IqSample;
|
||||
|
||||
pub trait DspPipelineExt<E>: Iterator<Item = Result<IqSample, E>> + Sized {
|
||||
@ -10,6 +11,10 @@ pub trait DspPipelineExt<E>: Iterator<Item = Result<IqSample, E>> + Sized {
|
||||
fn fir<const N: usize>(self, taps: [f32; N], decimation_factor: usize) -> Fir<Self, N> {
|
||||
Fir::new(self, taps, decimation_factor)
|
||||
}
|
||||
|
||||
fn demodulate(self) -> FmDemod<Self> {
|
||||
FmDemod::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, E> DspPipelineExt<E> for I where I: Iterator<Item = Result<IqSample, E>> {}
|
||||
|
||||
Reference in New Issue
Block a user