From 65089bc6ca9e31878afd583e133cb376ef03f268 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Mon, 15 Jan 2024 14:50:21 +0100 Subject: [WIP] Initial implementation of CH3 envelope --- src/sequencer.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 9 deletions(-) (limited to 'src/sequencer.c') diff --git a/src/sequencer.c b/src/sequencer.c index 981bbc6..01b8e95 100644 --- a/src/sequencer.c +++ b/src/sequencer.c @@ -229,14 +229,16 @@ play_step(void) { if (trig->active && should_play(params->prob)) { switch (params->wave_mode) { case 0: { + memcpy32(wave_active, waves[params->shape_a][params->type_a], 16); SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1); - memcpy32(SOUND_WAVE_RAM, waves[params->shape_a][params->type_a], 16); + memcpy32(SOUND_WAVE_RAM, wave_active, 16); SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0) | SOUND_WAVE_BANK_SELECT(0); } break; case 1: { + memcpy32(wave_active, waves[params->shape_b][params->type_b], 16); SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0); - memcpy32(SOUND_WAVE_RAM, waves[params->shape_b][params->type_b], 16); + memcpy32(SOUND_WAVE_RAM, wave_active, 16); SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0) | SOUND_WAVE_BANK_SELECT(1); } break; @@ -249,6 +251,7 @@ play_step(void) { | SOUND_WAVE_BANK_SELECT(0); } break; } + wave_env_ticks = 0; SOUND_WAVE_MODE |= SOUND_WAVE_ENABLE; SOUND_WAVE_FREQ = SOUND_FREQ_RESET @@ -261,12 +264,6 @@ play_step(void) { case 4: { SOUND_WAVE_CTRL = SOUND_WAVE_VOL_100; } break; } pan[2] = params->pan; - } else { - // NOTE: Maybe in the future we want an AD, but for now this is - // probably better than holding the notes. Or perhaps add a hold - // mode? - SOUND_WAVE_FREQ = SOUND_FREQ_RESET; - SOUND_WAVE_CTRL = SOUND_WAVE_MUTE; } } else { SOUND_WAVE_FREQ = SOUND_FREQ_RESET; @@ -352,11 +349,65 @@ play_step(void) { static int nseq_ticks = 0; +IWRAM_CODE +void +wave_ad_tick(void) { + // Play a single step for A+B or no envelope. + if ((SOUND_WAVE_MODE & SOUND_WAVE_BANK_MODE(1)) || !wave_env_decay) { + if (wave_env_ticks++ == 24) { + SOUND_WAVE_FREQ = SOUND_FREQ_RESET; + SOUND_WAVE_CTRL = SOUND_WAVE_MUTE; + } + return; + } + + if (wave_env_ticks++ < wave_env_decay) { + return; + } + wave_env_ticks = 0; + + // Decay. + for (size_t j = 0; j < 4; j++) { + u32 next = 0; + for (size_t i = 0; i < 8; i++) { + u8 val = (wave_active[j] >> 4 * i) & 0xF; + // Operating in 24.8 fixed point: + // 0.9 = 230; 0.8 = 205; 0.75 = 192 + int power = 205; + if (val < 0x7) { + int tmp = 0x7 - val; + tmp *= power; + tmp >>= 8; + val = (0x7 - tmp) & 0xf; + } else if (val > 0x7) { + int tmp = (val - 0x7); + tmp *= power; + tmp >>= 8; + val = tmp + 0x7; + if (val <= 0x7) { + val = 0x7; + } + } + next |= (val << 4 * i); + } + wave_active[j] = next; + } + + // DEBUG: + // int x = 50; + // int y = 50; + // draw_filled_rect(0 + x, 0 + y, 100 + x, 32 + y, COL_BG); + // draw_wave_pattern(&wave_active, 0 + x, 0 + y, 1); + + memcpy32(SOUND_WAVE_RAM, wave_active, 16); + SOUND_WAVE_MODE ^= SOUND_WAVE_BANK_SELECT(1); +} + void sequencer_tick(void) { + wave_ad_tick(); if (nseq_ticks++ == 0) { play_step(); - return; } else if (nseq_ticks == 24) { nseq_ticks = 0; } -- cgit v1.2.1