Add sample duration handling

This commit is contained in:
Bad Diode 2023-10-10 15:39:47 +02:00 committed by neauoire
parent 49eda85851
commit 9437c4e520
4 changed files with 28 additions and 21 deletions

View File

@ -2608,23 +2608,20 @@ audio_handler(void *ctx, Uint8 *out_stream, int len) {
for (int n = 0; n < N_CHANNELS; n++) { for (int n = 0; n < N_CHANNELS; n++) {
Uint8 device = (3 + n) << 4; Uint8 device = (3 + n) << 4;
// TODO: Make sure this works properly and evals to the audio stack Uxn *u = (Uxn *)ctx;
// instead of the regular stack. Uint8 *addr = &u->dev[device];
// Uxn *u = (Uxn *)ctx; if (channel[n].duration <= 0 && PEEK2(addr)) {
// Uint8 *addr = &u->dev[device]; uxn_eval(u, PEEK2(addr));
// if (channel[n].duration <= 0 && PEEK2(addr)) { // printf("EVAL: %x\n", device);
// uxn_eval(u, PEEK2(addr)); // printf("ADDR: %x\n", PEEK2(addr));
// } // printf("----\n");
// printf("DEVICE: %x\n", device);
// printf("ADDR: %x\n", PEEK2(addr));
if (channel[n].sample.data != 0) {
channel[n].duration -= SOUND_TIMER;
} }
channel[n].duration -= SOUND_TIMER;
int x = 0; int x = 0;
if (channel[n].xfade) { if (channel[n].xfade) {
float delta = 1.0f / (XFADE_SAMPLES); float delta = 1.0f / (XFADE_SAMPLES);
while (x < XFADE_SAMPLES * 2) { while (x < XFADE_SAMPLES * 2 && x < len / 2) {
float alpha = x * delta; float alpha = x * delta;
float beta = 1.0f - alpha; float beta = 1.0f - alpha;
Sint16 next_a = next_a = next_sample(&channel[n].next_sample); Sint16 next_a = next_a = next_sample(&channel[n].next_sample);

View File

@ -15,8 +15,8 @@ typedef signed int Sint32;
#define AUDIO_DEIMASK 0x0014 #define AUDIO_DEIMASK 0x0014
#define AUDIO_DEOMASK 0x8000 #define AUDIO_DEOMASK 0x8000
#define AUDIO_BUFSIZE 256 #define AUDIO_BUFSIZE 256.0f
#define SAMPLE_FREQUENCY 44100 #define SAMPLE_FREQUENCY 44100.0f
#define POLYPHONY 4 #define POLYPHONY 4
Uint8 audio_get_vu(int instance); Uint8 audio_get_vu(int instance);

View File

@ -29,7 +29,7 @@ typedef struct {
} Stack; } Stack;
typedef struct Uxn { typedef struct Uxn {
Uint8 *ram, dev[0x100]; Uint8 *ram, *dev;
Stack wst, rst; Stack wst, rst;
} Uxn; } Uxn;

View File

@ -103,7 +103,6 @@ audio_deo(int instance, Uint8 *d, Uint8 port, Uxn *u)
SDL_LockAudioDevice(audio_id); SDL_LockAudioDevice(audio_id);
audio_start(instance, d, u); audio_start(instance, d, u);
SDL_UnlockAudioDevice(audio_id); SDL_UnlockAudioDevice(audio_id);
SDL_PauseAudioDevice(audio_id, 0);
} }
} }
@ -251,7 +250,7 @@ emu_redraw(Uxn *u)
} }
static int static int
emu_init(void) emu_init(Uxn *u)
{ {
SDL_AudioSpec as; SDL_AudioSpec as;
SDL_zero(as); SDL_zero(as);
@ -260,7 +259,7 @@ emu_init(void)
as.channels = 2; as.channels = 2;
as.callback = audio_handler; as.callback = audio_handler;
as.samples = AUDIO_BUFSIZE; as.samples = AUDIO_BUFSIZE;
as.userdata = NULL; as.userdata = u;
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0) if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0)
return system_error("sdl", SDL_GetError()); return system_error("sdl", SDL_GetError());
@ -280,6 +279,7 @@ emu_init(void)
deadline_interval = ms_interval * TIMEOUT_MS; deadline_interval = ms_interval * TIMEOUT_MS;
exec_deadline = SDL_GetPerformanceCounter() + deadline_interval; exec_deadline = SDL_GetPerformanceCounter() + deadline_interval;
screen_resize(WIDTH, HEIGHT); screen_resize(WIDTH, HEIGHT);
SDL_PauseAudioDevice(audio_id, 0);
return 1; return 1;
} }
@ -541,7 +541,11 @@ emu_end(Uxn *u)
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
Uint8 dev[0x100] = {0};
Uxn u = {0}; Uxn u = {0};
u.dev = &dev;
Uxn u_audio = {0};
u_audio.dev = &dev;
int i = 1; int i = 1;
if(i == argc) if(i == argc)
return system_error("usage", "uxnemu [-v] | uxnemu [-f | -2x | -3x | --] file.rom [args...]"); return system_error("usage", "uxnemu [-v] | uxnemu [-f | -2x | -3x | --] file.rom [args...]");
@ -559,10 +563,16 @@ main(int argc, char **argv)
} }
} }
/* Start system. */ /* Start system. */
if(!emu_init()) Uint8 *ram = (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8));
return system_error("Init", "Failed to initialize varvara."); char *rom = argv[i++];
if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++])) if(!system_init(&u, ram, rom)) {
return system_error("Init", "Failed to initialize uxn."); 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 */ /* Game Loop */
u.dev[0x17] = argc - i; u.dev[0x17] = argc - i;
if(uxn_eval(&u, PAGE_PROGRAM)) { if(uxn_eval(&u, PAGE_PROGRAM)) {