aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-01-16 10:32:28 +0100
committerBad Diode <bd@badd10de.dev>2024-01-16 10:32:28 +0100
commit8c33aeda7cd65a5797930340c2728a9464e98b9f (patch)
treef7e9548d326fac18d1e7f778a6681fa8da9a4981
parent77374dacdee448b9dea733c0e444da07942b3238 (diff)
downloadstepper-8c33aeda7cd65a5797930340c2728a9464e98b9f.tar.gz
stepper-8c33aeda7cd65a5797930340c2728a9464e98b9f.zip
[WIP] Full implementation of attack/decay for ch3 (bugs?)
-rw-r--r--Makefile2
-rw-r--r--src/main.c4
-rw-r--r--src/sequencer.c84
3 files changed, 65 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 7afaf9d..d7c0b05 100644
--- a/Makefile
+++ b/Makefile
@@ -27,7 +27,7 @@ INC_FLAGS := $(addprefix -I,$(INC_DIRS))
27INC_FLAGS += -I$(LIBGBA_SRC) 27INC_FLAGS += -I$(LIBGBA_SRC)
28 28
29# Output library names and executables. 29# Output library names and executables.
30TARGET := STEPPER-v1.8-dev-15 30TARGET := STEPPER-v1.8-dev-16
31ELF := $(BUILD_DIR)/$(TARGET).elf 31ELF := $(BUILD_DIR)/$(TARGET).elf
32BIN := $(BUILD_DIR)/$(TARGET).gba 32BIN := $(BUILD_DIR)/$(TARGET).gba
33 33
diff --git a/src/main.c b/src/main.c
index cea35f6..a068bc8 100644
--- a/src/main.c
+++ b/src/main.c
@@ -28,9 +28,8 @@ WITH REGARD TO THIS SOFTWARE.
28// + Hold L/R retriggers at short intervals? 28// + Hold L/R retriggers at short intervals?
29// to key release to enable trigs. 29// to key release to enable trigs.
30// + Fix bug with not being able to stop the sound when synced 30// + Fix bug with not being able to stop the sound when synced
31// + Add attack and decay envelope for ch3 (synced to tempo)
31// - Fix any bugs we currently have 32// - Fix any bugs we currently have
32// - Add an envelope to ch3, would need to work with a timer in order to make
33// it work I think (Can reuse the 96bpq sequencer timer for this).
34// - Add clipboard sharing between banks. 33// - Add clipboard sharing between banks.
35// - Make sure transposing a sequence past the keyboard limit doesn't affect 34// - Make sure transposing a sequence past the keyboard limit doesn't affect
36// the sequence and can be reversed. 35// the sequence and can be reversed.
@@ -38,6 +37,7 @@ WITH REGARD TO THIS SOFTWARE.
38// - When putting a new trigger, make sure it uses the global parameters 37// - When putting a new trigger, make sure it uses the global parameters
39// - Bad performance when selecting patterns 38// - Bad performance when selecting patterns
40// - Add help for attack/decay on ch3 39// - Add help for attack/decay on ch3
40// - Fix A+B on ch3
41// 41//
42// Low priority: 42// Low priority:
43// 43//
diff --git a/src/sequencer.c b/src/sequencer.c
index 4b5f34f..66f1d24 100644
--- a/src/sequencer.c
+++ b/src/sequencer.c
@@ -227,33 +227,18 @@ play_step(void) {
227 TriggerNote *trig = &pat->ch3.notes[step_counter]; 227 TriggerNote *trig = &pat->ch3.notes[step_counter];
228 ChannelWaveParams *params = &pat->ch3.params[step_counter]; 228 ChannelWaveParams *params = &pat->ch3.params[step_counter];
229 if (trig->active && should_play(params->prob)) { 229 if (trig->active && should_play(params->prob)) {
230 Wave wave_zero = {
231 0x77777777, 0x77777777, 0x77777777, 0x77777777,
232 };
233 switch (params->wave_mode) { 230 switch (params->wave_mode) {
234 case 0: { 231 case 0: {
235 wave_target = &waves[params->shape_a][params->type_a]; 232 wave_target = &waves[params->shape_a][params->type_a];
236 wave_env_attack = params->wave_attack; 233 wave_env_attack = params->wave_attack;
237 wave_env_decay = params->wave_decay; 234 wave_env_decay = params->wave_decay;
238 wave_env = WAV_ENV_START; 235 wave_env = WAV_ENV_START;
239 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0);
240 memcpy32(SOUND_WAVE_RAM, wave_zero, 16);
241 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1);
242 memcpy32(SOUND_WAVE_RAM, wave_zero, 16);
243 SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0)
244 | SOUND_WAVE_BANK_SELECT(0);
245 } break; 236 } break;
246 case 1: { 237 case 1: {
247 wave_target = &waves[params->shape_b][params->type_b]; 238 wave_target = &waves[params->shape_b][params->type_b];
248 wave_env_attack = params->wave_attack; 239 wave_env_attack = params->wave_attack;
249 wave_env_decay = params->wave_decay; 240 wave_env_decay = params->wave_decay;
250 wave_env = WAV_ENV_START; 241 wave_env = WAV_ENV_START;
251 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0);
252 memcpy32(SOUND_WAVE_RAM, wave_zero, 16);
253 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1);
254 memcpy32(SOUND_WAVE_RAM, wave_zero, 16);
255 SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0)
256 | SOUND_WAVE_BANK_SELECT(0);
257 } break; 242 } break;
258 case 2: { 243 case 2: {
259 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0); 244 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0);
@@ -361,21 +346,30 @@ play_step(void) {
361 346
362static int nseq_ticks = 0; 347static int nseq_ticks = 0;
363 348
349UNROLL_LOOPS
364IWRAM_CODE 350IWRAM_CODE
365void 351void
366wave_ad_tick(void) { 352wave_ad_tick(void) {
367 Wave wave_active = {0}; 353 Wave wave_active = {0};
354 Wave wave_zero = {
355 0x77777777, 0x77777777, 0x77777777, 0x77777777,
356 };
368env_start: 357env_start:
369 switch (wave_env) { 358 switch (wave_env) {
370 case WAV_ENV_START: { 359 case WAV_ENV_START: {
371 wave_env_ticks = 0; 360 wave_env_ticks = 0;
372 wave_env_prog = 0; 361 wave_env_prog = 0;
362 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(0);
363 memcpy32(SOUND_WAVE_RAM, wave_zero, 16);
364 SOUND_WAVE_MODE = SOUND_WAVE_BANK_SELECT(1);
365 memcpy32(SOUND_WAVE_RAM, wave_zero, 16);
366 SOUND_WAVE_MODE = SOUND_WAVE_BANK_MODE(0)
367 | SOUND_WAVE_BANK_SELECT(0);
373 SOUND_WAVE_MODE |= SOUND_WAVE_ENABLE; 368 SOUND_WAVE_MODE |= SOUND_WAVE_ENABLE;
374 SOUND_WAVE_FREQ = SOUND_FREQ_RESET | wave_freq; 369 SOUND_WAVE_FREQ = SOUND_FREQ_RESET | wave_freq;
375 370
376 if (wave_env_attack == 0) { 371 if (wave_env_attack == 0) {
377 memcpy32(wave_active, wave_target, 16); 372 memcpy32(SOUND_WAVE_RAM, wave_target, 16);
378 memcpy32(SOUND_WAVE_RAM, wave_active, 16);
379 SOUND_WAVE_MODE ^= SOUND_WAVE_BANK_SELECT(1); 373 SOUND_WAVE_MODE ^= SOUND_WAVE_BANK_SELECT(1);
380 } else { 374 } else {
381 wave_env = WAV_ENV_ATTACK; 375 wave_env = WAV_ENV_ATTACK;
@@ -391,7 +385,57 @@ env_start:
391 return; 385 return;
392 } break; 386 } break;
393 case WAV_ENV_ATTACK: { 387 case WAV_ENV_ATTACK: {
394 // TODO: Attack envelope 388 if (wave_env_ticks++ < wave_env_attack) {
389 return;
390 }
391 wave_env_ticks = 0;
392
393 // Attack.
394 int powers[] = {
395 20, 57, 104, 143, 177, 208, 235, 256,
396 };
397 int power = powers[wave_env_prog];
398 if (++wave_env_prog >= 8) {
399 if (wave_env_decay == 0) {
400 wave_env = WAV_ENV_OFF;
401 } else {
402 wave_env_prog = 0;
403 wave_env = WAV_ENV_DECAY;
404 }
405 }
406 for (size_t j = 0; j < 4; j++) {
407 u32 next = 0;
408 u32 prev = (*wave_target)[j];
409 for (size_t i = 0; i < 8; i++) {
410 u8 val = (prev >> 4 * i) & 0xF;
411 // Operating in 24.8 fixed point:
412 if (val < 0x7) {
413 int tmp = 0x7 - val;
414 tmp *= power;
415 tmp >>= 8;
416 val = (0x7 - tmp) & 0xf;
417 } else if (val > 0x7) {
418 int tmp = (val - 0x7);
419 tmp *= power;
420 tmp >>= 8;
421 val = tmp + 0x7;
422 if (val <= 0x7) {
423 val = 0x7;
424 }
425 }
426 next |= (val << 4 * i);
427 }
428 wave_active[j] = next;
429 }
430
431 // DEBUG:
432 // int x = 50;
433 // int y = 50;
434 // draw_filled_rect(0 + x, 0 + y, 100 + x, 32 + y, COL_BG);
435 // draw_wave_pattern(&wave_active, 0 + x, 0 + y, 1);
436
437 memcpy32(SOUND_WAVE_RAM, wave_active, 16);
438 SOUND_WAVE_MODE ^= SOUND_WAVE_BANK_SELECT(1);
395 } break; 439 } break;
396 case WAV_ENV_DECAY: { 440 case WAV_ENV_DECAY: {
397 if (wave_env_ticks++ < wave_env_decay) { 441 if (wave_env_ticks++ < wave_env_decay) {
@@ -401,11 +445,7 @@ env_start:
401 445
402 // Decay. 446 // Decay.
403 int powers[] = { 447 int powers[] = {
404 // FP_NUM(1,8), 230, 205, 192, 150, 100, 50, 0
405 // 256, 128, 85, 64, 51, 43, 37, 32, 28, 0
406 // Logarithmic volume range. 448 // Logarithmic volume range.
407 // 256, 245, 224, 202, 177, 150, 120, 86, 47, 0,
408 // 0., 57., 104., 143., 177., 208., 235., 259.
409 256, 235, 208, 177, 143, 104, 57, 0 449 256, 235, 208, 177, 143, 104, 57, 0
410 }; 450 };
411 int power = powers[wave_env_prog]; 451 int power = powers[wave_env_prog];