rusty-dsp/src/sources.rs

101 lines
2.4 KiB
Rust
Raw Normal View History

2020-05-22 17:33:30 +02:00
use std::f32::consts::PI;
2020-06-03 21:54:48 +02:00
use super::error::DspError;
2020-05-22 17:33:30 +02:00
pub struct SinSource {
sampling_rate: f32,
frequency: f32,
phase_acc: f32,
}
impl SinSource {
pub fn new(frequency: f32, sampling_rate: f32) -> SinSource {
SinSource {
sampling_rate: sampling_rate,
frequency: frequency,
phase_acc: 0.0,
}
}
}
impl Iterator for SinSource {
2020-06-03 21:54:48 +02:00
type Item = Result<f32, DspError>;
2020-05-22 17:33:30 +02:00
fn next(&mut self) -> Option<Self::Item> {
self.phase_acc += (1.0 / self.sampling_rate) * self.frequency * 2.0 * PI;
if self.phase_acc > 2.0 * PI {
self.phase_acc -= 2.0 * PI;
}
2020-06-03 21:54:48 +02:00
Some(Ok(self.phase_acc.sin()))
2020-05-22 17:33:30 +02:00
}
}
pub struct CosSource {
sampling_rate: f32,
frequency: f32,
phase_acc: f32,
}
impl CosSource {
pub fn new(frequency: f32, sampling_rate: f32) -> CosSource {
CosSource {
sampling_rate: sampling_rate,
frequency: frequency,
phase_acc: 0.0,
}
}
}
impl Iterator for CosSource {
2020-06-03 21:54:48 +02:00
type Item = Result<f32, DspError>;
2020-05-22 17:33:30 +02:00
fn next(&mut self) -> Option<Self::Item> {
self.phase_acc += (1.0 / self.sampling_rate) * self.frequency * 2.0 * PI;
if self.phase_acc > 2.0 * PI {
self.phase_acc -= 2.0 * PI;
}
2020-06-03 21:54:48 +02:00
Some(Ok(self.phase_acc.cos()))
2020-05-22 17:33:30 +02:00
}
}
pub struct VFOSource<'a> {
sampling_rate: f32,
phase_acc: f32,
2020-06-03 21:54:48 +02:00
frequency_iterator: Box<dyn Iterator<Item = Result<f32, DspError>> + 'a>,
2020-05-22 17:33:30 +02:00
}
impl<'a> VFOSource<'a> {
pub fn new<I>(frequency_iterator: I, sampling_rate: f32) -> VFOSource<'a>
where
2020-06-03 21:54:48 +02:00
I: Iterator<Item = Result<f32, DspError>> + 'a,
2020-05-22 17:33:30 +02:00
{
VFOSource {
sampling_rate: sampling_rate,
phase_acc: 0.0,
frequency_iterator: Box::new(frequency_iterator),
}
}
}
impl<'a> Iterator for VFOSource<'a> {
2020-06-03 21:54:48 +02:00
type Item = Result<f32, DspError>;
2020-05-22 17:33:30 +02:00
fn next(&mut self) -> Option<Self::Item> {
let current_frequency = match self.frequency_iterator.next() {
2020-06-03 21:54:48 +02:00
Some(Ok(x)) => x,
// Propagate any upstream errors
Some(Err(e)) => return Some(Err(e)),
2020-05-22 17:33:30 +02:00
None => return None,
};
self.phase_acc += (1.0 / self.sampling_rate) * current_frequency * 2.0 * PI;
if self.phase_acc > 2.0 * PI {
self.phase_acc -= 2.0 * PI;
}
2020-06-03 21:54:48 +02:00
Some(Ok(self.phase_acc.sin()))
2020-05-22 17:33:30 +02:00
}
}