101 lines
2.4 KiB
Rust
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()))
|
|
}
|
|
}
|