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 frequency_tuning_word =
|
||||
(1u64 << (32 - BATCH_SIZE_SIZE_LOG2)) as u32;
|
||||
(1u64 << (32 - BATCH_SIZE_SIZE_LOG2)) as i32;
|
||||
|
||||
signal_generator::Config {
|
||||
// Same frequency as batch size.
|
||||
|
|
|
@ -93,12 +93,12 @@ impl BasicConfig {
|
|||
ftw / self.symmetry
|
||||
} else {
|
||||
NYQUIST
|
||||
} as u32,
|
||||
} as i32,
|
||||
if symmetry_complement * NYQUIST > ftw {
|
||||
ftw / symmetry_complement
|
||||
} else {
|
||||
NYQUIST
|
||||
} as u32,
|
||||
} as i32,
|
||||
];
|
||||
|
||||
Ok(Config {
|
||||
|
@ -120,7 +120,7 @@ pub struct Config {
|
|||
pub amplitude: i16,
|
||||
|
||||
/// 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 {
|
||||
|
@ -135,7 +135,7 @@ impl Default for Config {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct SignalGenerator {
|
||||
phase_accumulator: u32,
|
||||
phase_accumulator: i32,
|
||||
config: Config,
|
||||
}
|
||||
|
||||
|
@ -174,32 +174,26 @@ impl core::iter::Iterator for SignalGenerator {
|
|||
|
||||
/// Get the next value in the generator sequence.
|
||||
fn next(&mut self) -> Option<i16> {
|
||||
self.phase_accumulator = self.phase_accumulator.wrapping_add(
|
||||
if (self.phase_accumulator as i32).is_negative() {
|
||||
self.config.frequency_tuning_word[0]
|
||||
} else {
|
||||
self.config.frequency_tuning_word[1]
|
||||
},
|
||||
);
|
||||
let sign = self.phase_accumulator.is_negative();
|
||||
self.phase_accumulator = self
|
||||
.phase_accumulator
|
||||
.wrapping_add(self.config.frequency_tuning_word[sign as usize]);
|
||||
|
||||
let phase = self.phase_accumulator as i32;
|
||||
|
||||
let amplitude: i16 = match self.config.signal {
|
||||
Signal::Cosine => (dsp::cossin(phase).0 >> 16) as i16,
|
||||
let scale = match self.config.signal {
|
||||
Signal::Cosine => (dsp::cossin(self.phase_accumulator).0 >> 16),
|
||||
Signal::Square => {
|
||||
if phase.is_negative() {
|
||||
i16::MAX
|
||||
if sign {
|
||||
-1 << 15
|
||||
} 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.
|
||||
let result = amplitude as i32 * self.config.amplitude as i32;
|
||||
|
||||
// Note: We downshift by 15-bits to preserve only one of the sign bits.
|
||||
Some(((result + (1 << 14)) >> 15) as i16)
|
||||
Some(((self.config.amplitude as i32 * scale) >> 15) as _)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue