dynamic sequencer support
This commit is contained in:
parent
7d93cd8977
commit
9e67026345
3 changed files with 144 additions and 22 deletions
|
|
@ -93,6 +93,84 @@ pub mod sequencer {
|
|||
self.sequence[self.index]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SequenceEntry {
|
||||
pub frequency_hz: u16,
|
||||
pub duration_ms: u16,
|
||||
}
|
||||
|
||||
pub struct DynamicSequence<'a> {
|
||||
sequence: &'a [SequenceEntry],
|
||||
index: usize,
|
||||
|
||||
// timer stuff
|
||||
system_tick_rate_hz: usize,
|
||||
ticks_remaining: usize,
|
||||
|
||||
// playback stuff
|
||||
num_loops: usize,
|
||||
loop_count: usize,
|
||||
|
||||
// misc
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
impl<'a> DynamicSequence<'a> {
|
||||
pub fn new(sequence: &'a [SequenceEntry], system_tick_rate_hz: usize) -> Self {
|
||||
Self {
|
||||
sequence,
|
||||
index: 0,
|
||||
system_tick_rate_hz,
|
||||
ticks_remaining: 0,
|
||||
num_loops: 1,
|
||||
loop_count: 0,
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn play_sequence(&mut self, sequence: &'a [SequenceEntry], num_loops: usize) {
|
||||
self.sequence = sequence;
|
||||
self.num_loops = num_loops;
|
||||
self.loop_count = 0;
|
||||
}
|
||||
|
||||
pub fn enable(&mut self) {
|
||||
self.enabled = true;
|
||||
}
|
||||
|
||||
pub fn disable(&mut self) {
|
||||
self.enabled = false;
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
if self.enabled {
|
||||
self.ticks_remaining = self.ticks_remaining.saturating_sub(1);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn need_service(&self) -> bool {
|
||||
self.ticks_remaining == 0
|
||||
}
|
||||
|
||||
pub fn service(&mut self) -> Option<u16> {
|
||||
let entry = &self.sequence[self.index];
|
||||
self.ticks_remaining = self.system_tick_rate_hz * (entry.duration_ms as usize) / 1000;
|
||||
self.index = self.index.saturating_add(1);
|
||||
|
||||
let out = if self.loop_count > self.num_loops {
|
||||
None
|
||||
} else {
|
||||
Some(entry.frequency_hz)
|
||||
};
|
||||
|
||||
if self.index > self.sequence.len() - 1 {
|
||||
self.index = 0;
|
||||
self.loop_count = self.loop_count.saturating_add(1);
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use crate::insert_coin::{
|
||||
|
|
@ -194,12 +272,14 @@ pub struct Services {
|
|||
pub led2: LedService,
|
||||
pub synth0: SynthesizerService,
|
||||
pub sample_player: DacService<'static>,
|
||||
pub sequencer: sequencer::DynamicSequence<'static>,
|
||||
}
|
||||
|
||||
impl Services {
|
||||
pub fn tick(&mut self) {
|
||||
self.synth0.tick();
|
||||
self.sample_player.tick();
|
||||
self.sequencer.tick();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -354,19 +434,31 @@ impl App {
|
|||
self.services.led2.service();
|
||||
}
|
||||
|
||||
if self.services.sequencer.need_service() {
|
||||
if let Some(out) = self.services.sequencer.service() {
|
||||
self.services.synth0.set_freq(out.into());
|
||||
} else {
|
||||
self.services.sequencer.disable();
|
||||
self.services.synth0.disable();
|
||||
}
|
||||
}
|
||||
|
||||
if self.services.synth0.need_service() {
|
||||
let out = self.services.synth0.service() / self.settings.volume.as_volume_divisor();
|
||||
// self.interfaces
|
||||
// .pwm_core
|
||||
// .write_amplitude(ch32_hal::timer::Channel::Ch4, out);
|
||||
let out = match self.services.synth0.service() {
|
||||
Some(value) => value / self.settings.volume.as_volume_divisor(),
|
||||
None => 0,
|
||||
};
|
||||
self.interfaces
|
||||
.pwm_core
|
||||
.write_amplitude(ch32_hal::timer::Channel::Ch4, out);
|
||||
}
|
||||
|
||||
if self.services.sample_player.need_service() {
|
||||
self.services.sample_player.service();
|
||||
let out = self.services.sample_player.get_amplitude();
|
||||
self.interfaces
|
||||
.pwm_core
|
||||
.write_amplitude(ch32_hal::timer::Channel::Ch4, out as u8);
|
||||
// let out = self.services.sample_player.get_amplitude();
|
||||
// self.interfaces
|
||||
// .pwm_core
|
||||
// .write_amplitude(ch32_hal::timer::Channel::Ch4, out as u8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue