Buffer management in line with other peripherals. Constructor and config redesign
This commit is contained in:
@ -6,33 +6,29 @@ use core::f32::consts::PI;
|
||||
|
||||
use defmt::{error, info};
|
||||
use embassy_executor::Spawner;
|
||||
use embassy_nrf::i2s::{self, Sample as _};
|
||||
use embassy_nrf::i2s::{self, Channels, Config, MasterClock, Sample as _, SampleWidth, I2S};
|
||||
use embassy_nrf::interrupt;
|
||||
use {defmt_rtt as _, panic_probe as _};
|
||||
|
||||
type Sample = i16;
|
||||
|
||||
const NUM_SAMPLES: usize = 6000;
|
||||
|
||||
#[embassy_executor::main]
|
||||
async fn main(_spawner: Spawner) {
|
||||
let p = embassy_nrf::init(Default::default());
|
||||
|
||||
let mut config = i2s::Config::default();
|
||||
config.mode = i2s::ExactSampleRate::_50000.into();
|
||||
config.channels = i2s::Channels::Left;
|
||||
config.swidth = i2s::SampleWidth::_16bit;
|
||||
let sample_rate = config.mode.sample_rate().expect("I2S Master");
|
||||
let inv_sample_rate = 1.0 / sample_rate as f32;
|
||||
let master_clock: MasterClock = i2s::ExactSampleRate::_50000.into();
|
||||
|
||||
let sample_rate = master_clock.sample_rate();
|
||||
info!("Sample rate: {}", sample_rate);
|
||||
|
||||
// Wait for a button press
|
||||
// use embassy_nrf::gpio::{Input, Pin, Pull};
|
||||
// let mut btn1 = Input::new(p.P1_00.degrade(), Pull::Up);
|
||||
// btn1.wait_for_low().await;
|
||||
let config = Config::default()
|
||||
.sample_width(SampleWidth::_16bit)
|
||||
.channels(Channels::MonoLeft);
|
||||
|
||||
let irq = interrupt::take!(I2S);
|
||||
let mut i2s = i2s::I2S::new(p.I2S, irq, p.P0_28, p.P0_29, p.P0_31, p.P0_27, p.P0_30, config).output();
|
||||
|
||||
type Sample = i16;
|
||||
const NUM_SAMPLES: usize = 6000;
|
||||
let mut output_stream = I2S::master(p.I2S, irq, p.P0_25, p.P0_26, p.P0_27, master_clock, config).output(p.P0_28);
|
||||
|
||||
let mut buffers: [i2s::AlignedBuffer<Sample, NUM_SAMPLES>; 3] = [
|
||||
i2s::AlignedBuffer::default(),
|
||||
@ -40,36 +36,16 @@ async fn main(_spawner: Spawner) {
|
||||
i2s::AlignedBuffer::default(),
|
||||
];
|
||||
|
||||
let mut carrier = SineOsc::new();
|
||||
let mut waveform = Waveform::new(1.0 / sample_rate as f32);
|
||||
|
||||
let mut freq_mod = SineOsc::new();
|
||||
freq_mod.set_frequency(8.0, inv_sample_rate);
|
||||
freq_mod.set_amplitude(1.0);
|
||||
waveform.process(&mut buffers[0]);
|
||||
waveform.process(&mut buffers[1]);
|
||||
|
||||
let mut amp_mod = SineOsc::new();
|
||||
amp_mod.set_frequency(16.0, inv_sample_rate);
|
||||
amp_mod.set_amplitude(0.5);
|
||||
|
||||
let mut generate = |buf: &mut [Sample]| {
|
||||
for sample in &mut buf.chunks_mut(1) {
|
||||
let freq_modulation = bipolar_to_unipolar(freq_mod.generate());
|
||||
carrier.set_frequency(220.0 + 440.0 * freq_modulation, inv_sample_rate);
|
||||
let amp_modulation = bipolar_to_unipolar(amp_mod.generate());
|
||||
carrier.set_amplitude(amp_modulation);
|
||||
let signal = carrier.generate();
|
||||
let value = (Sample::SCALE as f32 * signal) as Sample;
|
||||
sample[0] = value;
|
||||
}
|
||||
};
|
||||
|
||||
generate(buffers[0].as_mut());
|
||||
generate(buffers[1].as_mut());
|
||||
|
||||
i2s.start(buffers[0].as_ref()).await.expect("I2S Start");
|
||||
output_stream.start(&buffers[0]).await.expect("I2S Start");
|
||||
|
||||
let mut index = 1;
|
||||
loop {
|
||||
if let Err(err) = i2s.send(buffers[index].as_ref()).await {
|
||||
if let Err(err) = output_stream.send_from_ram(&buffers[index]).await {
|
||||
error!("{}", err);
|
||||
}
|
||||
|
||||
@ -77,11 +53,54 @@ async fn main(_spawner: Spawner) {
|
||||
if index >= 3 {
|
||||
index = 0;
|
||||
}
|
||||
generate(buffers[index].as_mut());
|
||||
|
||||
waveform.process(&mut buffers[index]);
|
||||
}
|
||||
}
|
||||
|
||||
struct Waveform {
|
||||
inv_sample_rate: f32,
|
||||
carrier: SineOsc,
|
||||
freq_mod: SineOsc,
|
||||
amp_mod: SineOsc,
|
||||
}
|
||||
|
||||
impl Waveform {
|
||||
fn new(inv_sample_rate: f32) -> Self {
|
||||
let carrier = SineOsc::new();
|
||||
|
||||
let mut freq_mod = SineOsc::new();
|
||||
freq_mod.set_frequency(8.0, inv_sample_rate);
|
||||
freq_mod.set_amplitude(1.0);
|
||||
|
||||
let mut amp_mod = SineOsc::new();
|
||||
amp_mod.set_frequency(16.0, inv_sample_rate);
|
||||
amp_mod.set_amplitude(0.5);
|
||||
|
||||
Self {
|
||||
inv_sample_rate,
|
||||
carrier,
|
||||
freq_mod,
|
||||
amp_mod,
|
||||
}
|
||||
}
|
||||
|
||||
fn process(&mut self, buf: &mut [Sample]) {
|
||||
for sample in buf.chunks_mut(1) {
|
||||
let freq_modulation = bipolar_to_unipolar(self.freq_mod.generate());
|
||||
self.carrier
|
||||
.set_frequency(110.0 + 440.0 * freq_modulation, self.inv_sample_rate);
|
||||
|
||||
let amp_modulation = bipolar_to_unipolar(self.amp_mod.generate());
|
||||
self.carrier.set_amplitude(amp_modulation);
|
||||
|
||||
let signal = self.carrier.generate();
|
||||
|
||||
sample[0] = (Sample::SCALE as f32 * signal) as Sample;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SineOsc {
|
||||
amplitude: f32,
|
||||
modulo: f32,
|
Reference in New Issue
Block a user