uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit 9437c4e52024d7248b64114ec42e779a5d7473d8
parent 49eda85851edbd65cf545468c23bfa4dd035a962
Author: Bad Diode <bd@badd10de.dev>
Date:   Tue, 10 Oct 2023 15:39:47 +0200

Add sample duration handling

Diffstat:
Msrc/devices/audio.c | 21+++++++++------------
Msrc/devices/audio.h | 4++--
Msrc/uxn.h | 2+-
Msrc/uxnemu.c | 22++++++++++++++++------
4 files changed, 28 insertions(+), 21 deletions(-)

diff --git a/src/devices/audio.c b/src/devices/audio.c @@ -2608,23 +2608,20 @@ audio_handler(void *ctx, Uint8 *out_stream, int len) { for (int n = 0; n < N_CHANNELS; n++) { Uint8 device = (3 + n) << 4; - // TODO: Make sure this works properly and evals to the audio stack - // instead of the regular stack. - // Uxn *u = (Uxn *)ctx; - // Uint8 *addr = &u->dev[device]; - // if (channel[n].duration <= 0 && PEEK2(addr)) { - // uxn_eval(u, PEEK2(addr)); - // } - // printf("DEVICE: %x\n", device); - // printf("ADDR: %x\n", PEEK2(addr)); - if (channel[n].sample.data != 0) { - channel[n].duration -= SOUND_TIMER; + Uxn *u = (Uxn *)ctx; + Uint8 *addr = &u->dev[device]; + if (channel[n].duration <= 0 && PEEK2(addr)) { + uxn_eval(u, PEEK2(addr)); + // printf("EVAL: %x\n", device); + // printf("ADDR: %x\n", PEEK2(addr)); + // printf("----\n"); } + channel[n].duration -= SOUND_TIMER; int x = 0; if (channel[n].xfade) { float delta = 1.0f / (XFADE_SAMPLES); - while (x < XFADE_SAMPLES * 2) { + while (x < XFADE_SAMPLES * 2 && x < len / 2) { float alpha = x * delta; float beta = 1.0f - alpha; Sint16 next_a = next_a = next_sample(&channel[n].next_sample); diff --git a/src/devices/audio.h b/src/devices/audio.h @@ -15,8 +15,8 @@ typedef signed int Sint32; #define AUDIO_DEIMASK 0x0014 #define AUDIO_DEOMASK 0x8000 -#define AUDIO_BUFSIZE 256 -#define SAMPLE_FREQUENCY 44100 +#define AUDIO_BUFSIZE 256.0f +#define SAMPLE_FREQUENCY 44100.0f #define POLYPHONY 4 Uint8 audio_get_vu(int instance); diff --git a/src/uxn.h b/src/uxn.h @@ -29,7 +29,7 @@ typedef struct { } Stack; typedef struct Uxn { - Uint8 *ram, dev[0x100]; + Uint8 *ram, *dev; Stack wst, rst; } Uxn; diff --git a/src/uxnemu.c b/src/uxnemu.c @@ -103,7 +103,6 @@ audio_deo(int instance, Uint8 *d, Uint8 port, Uxn *u) SDL_LockAudioDevice(audio_id); audio_start(instance, d, u); SDL_UnlockAudioDevice(audio_id); - SDL_PauseAudioDevice(audio_id, 0); } } @@ -251,7 +250,7 @@ emu_redraw(Uxn *u) } static int -emu_init(void) +emu_init(Uxn *u) { SDL_AudioSpec as; SDL_zero(as); @@ -260,7 +259,7 @@ emu_init(void) as.channels = 2; as.callback = audio_handler; as.samples = AUDIO_BUFSIZE; - as.userdata = NULL; + as.userdata = u; if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) return system_error("sdl", SDL_GetError()); @@ -280,6 +279,7 @@ emu_init(void) deadline_interval = ms_interval * TIMEOUT_MS; exec_deadline = SDL_GetPerformanceCounter() + deadline_interval; screen_resize(WIDTH, HEIGHT); + SDL_PauseAudioDevice(audio_id, 0); return 1; } @@ -541,7 +541,11 @@ emu_end(Uxn *u) int main(int argc, char **argv) { + Uint8 dev[0x100] = {0}; Uxn u = {0}; + u.dev = &dev; + Uxn u_audio = {0}; + u_audio.dev = &dev; int i = 1; if(i == argc) return system_error("usage", "uxnemu [-v] | uxnemu [-f | -2x | -3x | --] file.rom [args...]"); @@ -559,10 +563,16 @@ main(int argc, char **argv) } } /* Start system. */ - if(!emu_init()) - return system_error("Init", "Failed to initialize varvara."); - if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++])) + Uint8 *ram = (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)); + char *rom = argv[i++]; + if(!system_init(&u, ram, rom)) { + return system_error("Init", "Failed to initialize uxn."); + } + if(!system_init(&u_audio, ram, rom)) { return system_error("Init", "Failed to initialize uxn."); + } + if(!emu_init(&u_audio)) + return system_error("Init", "Failed to initialize varvara."); /* Game Loop */ u.dev[0x17] = argc - i; if(uxn_eval(&u, PAGE_PROGRAM)) {