first wavetable synth demo

This commit is contained in:
sigil-03 2025-10-27 21:10:36 -06:00
parent 3ea7aac1f4
commit 58579ae6c2
6 changed files with 84 additions and 20 deletions

3
.gitmodules vendored
View file

@ -7,3 +7,6 @@
[submodule "ch32v-insert-coin/ext/adpcm-pwm-dac"]
path = ch32v-insert-coin/ext/adpcm-pwm-dac
url = ssh://git@git.glyphs.tech:222/sigil-03/adpcm-pwm-dac.git
[submodule "ch32v-insert-coin/ext/wavetable-synth"]
path = ch32v-insert-coin/ext/wavetable-synth
url = https://git.glyphs.tech/sigil-03/wavetable-synth.git

View file

@ -78,6 +78,7 @@ dependencies = [
"panic-halt",
"qingke 0.5.0",
"qingke-rt",
"wavetable-synth",
]
[[package]]
@ -626,3 +627,7 @@ name = "void"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "wavetable-synth"
version = "0.1.0"

View file

@ -31,6 +31,8 @@ qingke = {path = "ext/qingke"}
adpcm-pwm-dac = { path = "ext/adpcm-pwm-dac/" }
wavetable-synth = { path = "ext/wavetable-synth" }
critical-section = { version = "1.2.0" }
[profile.release]

@ -0,0 +1 @@
Subproject commit 9417e6edbf590f3fe777e39ad76efc21a024e01d

View file

@ -9,6 +9,10 @@ mod insert_coin;
// system stuff
mod system;
// synthesizer :3
mod synthesizer;
use synthesizer::AppSynthesizers;
use ch32_hal::{adc::AdcChannel, interrupt::typelevel::Handler, timer::low_level::OutputPolarity};
use insert_coin::{CoreConfig, InsertCoin, SimplePwmCore};
@ -204,30 +208,40 @@ fn debug_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
use hal::gpio::{Level, Output};
let mut led0_pin = Output::new(p.PC3, Level::High, Default::default());
// button pin setup
let button_pin = p.PD6;
unsafe { system::init_gpio_irq(button_pin.pin(), button_pin.port(), false, true) };
let mut button_input = Input::new(button_pin, Pull::Up);
delay.delay_ms(1000);
unsafe { system::enter_standby() };
delay.delay_ms(1000);
riscv::asm::wfi();
let tick_rate_hz = 100000; // 100khz
let tick_interval_us = 1000000 / tick_rate_hz;
// get the clocks re-initialized
let mut config = hal::Config::default();
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
unsafe {
hal::rcc::init(config.rcc);
}
// DAC output setup
let dac_pin = PwmPin::new_ch4::<0>(p.PC4);
// let dac_ch = hal::timer::Channel::Ch4;
// PWM timer setup
let mut pwm = SimplePwm::new(
p.TIM1,
None,
None,
None,
Some(dac_pin),
Hertz::khz(200),
CountingMode::default(),
);
let pwm_core = SimplePwmCore::new(pwm);
// === synthesizer setup ===
let mut synthesizer = AppSynthesizers::new(tick_rate_hz, pwm_core);
synthesizer.square.set_freq(440);
#[cfg(feature = "enable_print")]
println!("begin loop");
led0_pin.toggle();
loop {
led0_pin.toggle();
delay.delay_ms(100);
synthesizer.service();
delay.delay_us(tick_interval_us as u32);
}
}
@ -275,6 +289,11 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
let core_config = CoreConfig::new(tick_rate_hz);
let pwm_core = SimplePwmCore::new(pwm);
// === synthesizer setup ===
// let synthesizer = AppSynthesizers::new(core_config.tick_rate_hz, pwm_core);
// === input setup ===
// adc
@ -327,8 +346,6 @@ fn app_main(mut p: hal::Peripherals, mut delay: Delay) -> ! {
let mut light_ctrl_btn_input =
DebouncedGPIO::new(light_ctrl_btn_pin.degrade(), core_config.tick_rate_hz, 100);
let pwm_core = SimplePwmCore::new(pwm);
let mut interfaces = InsertCoin::new(core_config, pwm_core);
interfaces.set_active(true);
// insert_coin.init();
@ -631,8 +648,8 @@ fn main() -> ! {
let mut delay = Delay;
delay.delay_ms(1000);
// debug_main(p, delay);
app_main(p, delay);
debug_main(p, delay);
// app_main(p, delay);
}
#[panic_handler]

View file

@ -0,0 +1,36 @@
use crate::insert_coin::SimplePwmCore;
use ch32_hal::println;
use ch32_hal::timer::GeneralInstance16bit;
use wavetable_synth::{synthesizer::SimpleWavetableSynthesizer, wavetable::SimpleWavetable};
const SQUARE_WAVETABLE: [u8; 32] = [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 100, 100, 100, 100, 100, 100, 100, 100,
100, 100, 100, 100, 100, 100, 100,
];
pub struct AppSynthesizers<'a, T: GeneralInstance16bit> {
pub square: SimpleWavetableSynthesizer<SimpleWavetable<'static, u8>>,
output: SimplePwmCore<'a, T>,
}
impl<'a, T: GeneralInstance16bit> AppSynthesizers<'a, T> {
pub fn new(clock_freq_hz: usize, output: SimplePwmCore<'a, T>) -> Self {
let square_wt = SimpleWavetable::new(&SQUARE_WAVETABLE);
let square = SimpleWavetableSynthesizer::new(square_wt, clock_freq_hz);
Self { square, output }
}
pub fn service(&mut self) {
self.square.tick();
if self.square.has_new_output() {
let out = self.square.get_output();
// println!("OUTPUT: {out}");
self.output.write_amplitude(
ch32_hal::timer::Channel::Ch4,
out / 2,
// (out as f32 * (u8::MAX as f32 / u32::MAX as f32)) as u8,
);
}
}
}