aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-05-25 15:01:42 +0200
committerBad Diode <bd@badd10de.dev>2021-05-25 15:01:42 +0200
commitc4041799fc3c6e6cdcce6121ea2c121fd504a3b6 (patch)
tree041641c56544c323a31adbe72dd10bfc711430ef
parentefdfd887caea6450284a0e1e2ceb2b6141f15486 (diff)
downloaduxngba-c4041799fc3c6e6cdcce6121ea2c121fd504a3b6.tar.gz
uxngba-c4041799fc3c6e6cdcce6121ea2c121fd504a3b6.zip
Add sample playing prototype (not on UXN yet)
-rw-r--r--src/common.h10
-rw-r--r--src/main.c108
2 files changed, 110 insertions, 8 deletions
diff --git a/src/common.h b/src/common.h
index 5766565..048708b 100644
--- a/src/common.h
+++ b/src/common.h
@@ -14,6 +14,7 @@ WITH REGARD TO THIS SOFTWARE.
14 14
15#include "shorthand.h" 15#include "shorthand.h"
16 16
17#define CPU_FREQUENCY (2 << 23)
17// 18//
18// Memory sections. 19// Memory sections.
19// 20//
@@ -585,10 +586,11 @@ int bios_div(int num, int denom);
585#define SOUND_ENABLE_NOISE_RIGHT (1 << 0xF) 586#define SOUND_ENABLE_NOISE_RIGHT (1 << 0xF)
586 587
587typedef enum { 588typedef enum {
589 SOUND_DSOUND = (0x0 << 0),
588 SOUND_SQUARE1 = (0x1 << 0), 590 SOUND_SQUARE1 = (0x1 << 0),
589 SOUND_SQUARE2 = (0x1 << 1), 591 SOUND_SQUARE2 = (0x1 << 1),
590 SOUND_WAVE = (0x1 << 2), 592 SOUND_WAVE = (0x1 << 2),
591 SOUND_NOISE = (0x1 << 3), 593 SOUND_NOISE = (0x1 << 3),
592} SoundChannel; 594} SoundChannel;
593 595
594u16 596u16
@@ -613,6 +615,10 @@ sound_volume(SoundChannel channels, u8 volume) {
613#define SOUND_DSOUND_TIMER_B (1 << 0xE) 615#define SOUND_DSOUND_TIMER_B (1 << 0xE)
614#define SOUND_DSOUND_RESET_B (1 << 0xF) 616#define SOUND_DSOUND_RESET_B (1 << 0xF)
615 617
618// Direct sound FIFO queues.
619#define SOUND_FIFO_A ((u16*)(MEM_IO + 0xA0))
620#define SOUND_FIFO_B ((u16*)(MEM_IO + 0xA4))
621
616// Sound status bits. 622// Sound status bits.
617#define SOUND_ENABLE (1 << 0x7) 623#define SOUND_ENABLE (1 << 0x7)
618 624
diff --git a/src/main.c b/src/main.c
index 7764278..0862ca5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -26,6 +26,7 @@ WITH REGARD TO THIS SOFTWARE.
26// 26//
27// Config parameters. 27// Config parameters.
28// 28//
29
29#ifndef TEXT_LAYER 30#ifndef TEXT_LAYER
30#define TEXT_LAYER ppu.fg 31#define TEXT_LAYER ppu.fg
31#endif 32#endif
@@ -298,7 +299,8 @@ handle_input(Uxn *u) {
298 } 299 }
299 if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) { 300 if (key_tap(KEY_UP) && cursor_position >= KEYBOARD_ROW_SIZE) {
300 update_cursor(cursor_position - KEYBOARD_ROW_SIZE); 301 update_cursor(cursor_position - KEYBOARD_ROW_SIZE);
301 } else if (key_tap(KEY_DOWN) && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) { 302 } else if (key_tap(KEY_DOWN)
303 && cursor_position < LEN(keyboard) - KEYBOARD_ROW_SIZE) {
302 update_cursor(cursor_position + KEYBOARD_ROW_SIZE); 304 update_cursor(cursor_position + KEYBOARD_ROW_SIZE);
303 } 305 }
304 if (key_tap(KEY_B)) { 306 if (key_tap(KEY_B)) {
@@ -342,6 +344,75 @@ static Uxn u;
342EWRAM_BSS 344EWRAM_BSS
343static u8 umem[65536]; 345static u8 umem[65536];
344 346
347#include "kick.c"
348
349typedef struct AudioChannel {
350 u32 *samples;
351 u32 n_samples;
352 u16 sampling_freq;
353 bool loop;
354 // TODO: u16 adsr; // attack, decay, sustain, release
355 // TODO: u8 pitch; // Bit 8 is the "loop" bit
356 // TODO: u8 volume; // VOL_LEFT | (VOL_RIGHT << 4)
357} AudioChannel;
358
359typedef struct APU {
360 AudioChannel chan_0;
361 // u32 *samples_1;
362 // u32 *samples_2;
363 // u32 *samples_3;
364} APU;
365
366
367static APU apu = {0};
368
369void
370reset_sound(AudioChannel *chan) {
371 TIMER_CTRL_0 = 0;
372 TIMER_CTRL_1 = 0;
373 DMA_CTRL(1) = 0;
374
375 // Set max volume, left-right sound, fifo reset and use timer 0 for
376 // DirectSound A.
377 SOUND_DSOUND_MASTER = SOUND_DSOUND_RATIO_A
378 | SOUND_DSOUND_LEFT_A
379 | SOUND_DSOUND_RIGHT_A
380 | SOUND_DSOUND_RESET_A;
381
382 // Prepare DMA copy.
383 dma_transfer_copy(SOUND_FIFO_A, chan->samples, 1, 1,
384 DMA_CHUNK_32 | DMA_REFRESH | DMA_REPEAT | DMA_ENABLE);
385
386 // Timer 1 used to stop playing samples.
387 u32 sample_duration = chan->n_samples;
388 TIMER_DATA_1 = 0xFFFF - sample_duration;
389 TIMER_CTRL_1 = TIMER_CTRL_IRQ
390 | TIMER_CTRL_ENABLE
391 | TIMER_CTRL_CASCADE;
392
393 // Timer 0 used to stop sample playing.
394 TIMER_DATA_0 = 0xFFFF - CPU_FREQUENCY / chan->sampling_freq;
395 TIMER_CTRL_0 = TIMER_CTRL_ENABLE;
396}
397
398void
399irs_stop_sample(void) {
400 if (apu.chan_0.loop) {
401 reset_sound(&apu.chan_0);
402 } else {
403 TIMER_CTRL_0 = 0;
404 DMA_CTRL(1) = 0;
405 }
406}
407
408void
409init_sound(AudioChannel *chan) {
410 chan->samples = voiceraw;
411 chan->n_samples = LEN(voiceraw);
412 chan->sampling_freq = 44100;
413 chan->loop = true;
414}
415
345int main(void) { 416int main(void) {
346 // Initialize filesystem. 417 // Initialize filesystem.
347 fs_init(); 418 fs_init();
@@ -349,6 +420,7 @@ int main(void) {
349 // Register interrupts. 420 // Register interrupts.
350 irq_init(); 421 irq_init();
351 irs_set(IRQ_VBLANK, irs_stub); 422 irs_set(IRQ_VBLANK, irs_stub);
423 irs_set(IRQ_TIMER_1, irs_stop_sample);
352 424
353 // Initialize VM. 425 // Initialize VM.
354 memset(&u, 0, sizeof(u)); 426 memset(&u, 0, sizeof(u));
@@ -359,15 +431,39 @@ int main(void) {
359 txt_init(1, TEXT_LAYER); 431 txt_init(1, TEXT_LAYER);
360 txt_position(0,0); 432 txt_position(0,0);
361 433
434 txt_printf("VOICE LOADED: %lu\n", LEN(voiceraw));
435
436 // Enable sound.
437 SOUND_STATUS = SOUND_ENABLE;
438
439 init_sound(&apu.chan_0);
440 reset_sound(&apu.chan_0);
441
362 // Main loop. 442 // Main loop.
363 int frame_counter = 0; 443 // int frame_counter = 0;
364 evaluxn(&u, 0x0100); 444 // evaluxn(&u, 0x0100);
445 // u32 flip_cycles = 0;
365 while(true) { 446 while(true) {
366 bios_vblank_wait(); 447 bios_vblank_wait();
367 handle_input(&u); 448 // profile_start();
368 evaluxn(&u, mempeek16(devscreen->dat, 0)); 449 // handle_input(&u);
450 // u32 input_cycles = profile_stop();
451 // profile_start();
452 // evaluxn(&u, mempeek16(devscreen->dat, 0));
453 // u32 eval_cycles = profile_stop();
454 // txt_position(0, 8);
455 // txt_printf("INPUT: %lu \n", input_cycles);
456 // txt_printf("EVAL: %lu \n", eval_cycles);
457 // txt_printf("FLIP: %lu \n", flip_cycles);
458 // profile_start();
369 flipbuf(&ppu); 459 flipbuf(&ppu);
370 frame_counter++; 460 // flip_cycles = profile_stop();
461 // frame_counter++;
462 poll_keys();
463 if (key_tap(KEY_B)) {
464 txt_printf("TAP B\n");
465 reset_sound(&apu.chan_0);
466 }
371 } 467 }
372 468
373 return 0; 469 return 0;