rusty-dsp/src/sources.rs

101 lines
2.4 KiB
Rust

use std::f32::consts::PI;
use super::error::DspError;
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 {
type Item = Result<f32, DspError>;
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;
}
Some(Ok(self.phase_acc.sin()))
}
}
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 {
type Item = Result<f32, DspError>;
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;
}
Some(Ok(self.phase_acc.cos()))
}
}
pub struct VFOSource<'a> {
sampling_rate: f32,
phase_acc: f32,
frequency_iterator: Box<dyn Iterator<Item = Result<f32, DspError>> + 'a>,
}
impl<'a> VFOSource<'a> {
pub fn new<I>(frequency_iterator: I, sampling_rate: f32) -> VFOSource<'a>
where
I: Iterator<Item = Result<f32, DspError>> + 'a,
{
VFOSource {
sampling_rate: sampling_rate,
phase_acc: 0.0,
frequency_iterator: Box::new(frequency_iterator),
}
}
}
impl<'a> Iterator for VFOSource<'a> {
type Item = Result<f32, DspError>;
fn next(&mut self) -> Option<Self::Item> {
let current_frequency = match self.frequency_iterator.next() {
Some(Ok(x)) => x,
// Propagate any upstream errors
Some(Err(e)) => return Some(Err(e)),
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;
}
Some(Ok(self.phase_acc.sin()))
}
}