Merge #434
434: Adding optimized signal generator r=jordens a=ryan-summers This PR fixes #415 by implementing the proposed changes to reduce processing overhead. Unfortunately, even with these changes, it appears to not be possible to stream at full data rate even when using square waves - there are still losses of ~0.5% of frames. These changes were run with a signal frequency/amplitude/symmetry sweep from 500Hz-1KHz, Symmetry 0-1, and amplitude 1V -> 2V and output waveform on a scope looked well-formed. Co-authored-by: Ryan Summers <ryan.summers@vertigo-designs.com>
This commit is contained in:
commit
323ed54989
|
@ -279,7 +279,7 @@ const APP: () = {
|
||||||
|
|
||||||
let signal_config = {
|
let signal_config = {
|
||||||
let frequency_tuning_word =
|
let frequency_tuning_word =
|
||||||
(1u64 << (32 - BATCH_SIZE_SIZE_LOG2)) as u32;
|
(1u64 << (32 - BATCH_SIZE_SIZE_LOG2)) as i32;
|
||||||
|
|
||||||
signal_generator::Config {
|
signal_generator::Config {
|
||||||
// Same frequency as batch size.
|
// Same frequency as batch size.
|
||||||
|
|
|
@ -93,12 +93,12 @@ impl BasicConfig {
|
||||||
ftw / self.symmetry
|
ftw / self.symmetry
|
||||||
} else {
|
} else {
|
||||||
NYQUIST
|
NYQUIST
|
||||||
} as u32,
|
} as i32,
|
||||||
if symmetry_complement * NYQUIST > ftw {
|
if symmetry_complement * NYQUIST > ftw {
|
||||||
ftw / symmetry_complement
|
ftw / symmetry_complement
|
||||||
} else {
|
} else {
|
||||||
NYQUIST
|
NYQUIST
|
||||||
} as u32,
|
} as i32,
|
||||||
];
|
];
|
||||||
|
|
||||||
Ok(Config {
|
Ok(Config {
|
||||||
|
@ -120,7 +120,7 @@ pub struct Config {
|
||||||
pub amplitude: i16,
|
pub amplitude: i16,
|
||||||
|
|
||||||
/// The frequency tuning word of the signal. Phase is incremented by this amount
|
/// The frequency tuning word of the signal. Phase is incremented by this amount
|
||||||
pub frequency_tuning_word: [u32; 2],
|
pub frequency_tuning_word: [i32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
@ -135,7 +135,7 @@ impl Default for Config {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SignalGenerator {
|
pub struct SignalGenerator {
|
||||||
phase_accumulator: u32,
|
phase_accumulator: i32,
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,32 +174,26 @@ impl core::iter::Iterator for SignalGenerator {
|
||||||
|
|
||||||
/// Get the next value in the generator sequence.
|
/// Get the next value in the generator sequence.
|
||||||
fn next(&mut self) -> Option<i16> {
|
fn next(&mut self) -> Option<i16> {
|
||||||
self.phase_accumulator = self.phase_accumulator.wrapping_add(
|
let sign = self.phase_accumulator.is_negative();
|
||||||
if (self.phase_accumulator as i32).is_negative() {
|
self.phase_accumulator = self
|
||||||
self.config.frequency_tuning_word[0]
|
.phase_accumulator
|
||||||
} else {
|
.wrapping_add(self.config.frequency_tuning_word[sign as usize]);
|
||||||
self.config.frequency_tuning_word[1]
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
let phase = self.phase_accumulator as i32;
|
let scale = match self.config.signal {
|
||||||
|
Signal::Cosine => (dsp::cossin(self.phase_accumulator).0 >> 16),
|
||||||
let amplitude: i16 = match self.config.signal {
|
|
||||||
Signal::Cosine => (dsp::cossin(phase).0 >> 16) as i16,
|
|
||||||
Signal::Square => {
|
Signal::Square => {
|
||||||
if phase.is_negative() {
|
if sign {
|
||||||
i16::MAX
|
-1 << 15
|
||||||
} else {
|
} else {
|
||||||
-i16::MAX
|
1 << 15
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Signal::Triangle => i16::MAX - (phase.abs() >> 15) as i16,
|
Signal::Triangle => {
|
||||||
|
(self.phase_accumulator >> 15).abs() - (1 << 15)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Calculate the final output result as an i16.
|
// Calculate the final output result as an i16.
|
||||||
let result = amplitude as i32 * self.config.amplitude as i32;
|
Some(((self.config.amplitude as i32 * scale) >> 15) as _)
|
||||||
|
|
||||||
// Note: We downshift by 15-bits to preserve only one of the sign bits.
|
|
||||||
Some(((result + (1 << 14)) >> 15) as i16)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue