Browse code

Add sample duration handling

Bad Diode authored on 10/10/2023 13:39:47 • neauoire committed on 03/11/2023 00:30:14
Showing 4 changed files
... ...
@@ -2608,23 +2608,20 @@ audio_handler(void *ctx, Uint8 *out_stream, int len) {
2608 2608
 
2609 2609
     for (int n = 0; n < N_CHANNELS; n++) {
2610 2610
         Uint8 device = (3 + n) << 4;
2611
-        // TODO: Make sure this works properly and evals to the audio stack
2612
-        // instead of the regular stack.
2613
-        // Uxn *u = (Uxn *)ctx;
2614
-        // Uint8 *addr = &u->dev[device];
2615
-        // if (channel[n].duration <= 0 && PEEK2(addr)) {
2616
-			// uxn_eval(u, PEEK2(addr));
2617
-        // }
2618
-        // printf("DEVICE: %x\n", device);
2619
-        // printf("ADDR: %x\n", PEEK2(addr));
2620
-        if (channel[n].sample.data != 0) {
2621
-            channel[n].duration -= SOUND_TIMER;
2611
+        Uxn *u = (Uxn *)ctx;
2612
+        Uint8 *addr = &u->dev[device];
2613
+        if (channel[n].duration <= 0 && PEEK2(addr)) {
2614
+			uxn_eval(u, PEEK2(addr));
2615
+            // printf("EVAL: %x\n", device);
2616
+            // printf("ADDR: %x\n", PEEK2(addr));
2617
+            // printf("----\n");
2622 2618
         }
2619
+        channel[n].duration -= SOUND_TIMER;
2623 2620
 
2624 2621
         int x = 0;
2625 2622
         if (channel[n].xfade) {
2626 2623
             float delta = 1.0f / (XFADE_SAMPLES);
2627
-            while (x < XFADE_SAMPLES * 2) {
2624
+            while (x < XFADE_SAMPLES * 2 && x < len / 2) {
2628 2625
                 float alpha = x * delta;
2629 2626
                 float beta = 1.0f - alpha;
2630 2627
                 Sint16 next_a = next_a = next_sample(&channel[n].next_sample);
... ...
@@ -15,8 +15,8 @@ typedef signed int Sint32;
15 15
 #define AUDIO_DEIMASK 0x0014
16 16
 #define AUDIO_DEOMASK 0x8000
17 17
 
18
-#define AUDIO_BUFSIZE 256
19
-#define SAMPLE_FREQUENCY 44100
18
+#define AUDIO_BUFSIZE 256.0f
19
+#define SAMPLE_FREQUENCY 44100.0f
20 20
 #define POLYPHONY 4
21 21
 
22 22
 Uint8 audio_get_vu(int instance);
... ...
@@ -29,7 +29,7 @@ typedef struct {
29 29
 } Stack;
30 30
 
31 31
 typedef struct Uxn {
32
-	Uint8 *ram, dev[0x100];
32
+	Uint8 *ram, *dev;
33 33
 	Stack wst, rst;
34 34
 } Uxn;
35 35
 
... ...
@@ -103,7 +103,6 @@ audio_deo(int instance, Uint8 *d, Uint8 port, Uxn *u)
103 103
 		SDL_LockAudioDevice(audio_id);
104 104
 		audio_start(instance, d, u);
105 105
 		SDL_UnlockAudioDevice(audio_id);
106
-		SDL_PauseAudioDevice(audio_id, 0);
107 106
 	}
108 107
 }
109 108
 
... ...
@@ -251,7 +250,7 @@ emu_redraw(Uxn *u)
251 250
 }
252 251
 
253 252
 static int
254
-emu_init(void)
253
+emu_init(Uxn *u)
255 254
 {
256 255
 	SDL_AudioSpec as;
257 256
 	SDL_zero(as);
... ...
@@ -260,7 +259,7 @@ emu_init(void)
260 259
 	as.channels = 2;
261 260
 	as.callback = audio_handler;
262 261
 	as.samples = AUDIO_BUFSIZE;
263
-	as.userdata = NULL;
262
+	as.userdata = u;
264 263
 	if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0)
265 264
 		return system_error("sdl", SDL_GetError());
266 265
 
... ...
@@ -280,6 +279,7 @@ emu_init(void)
280 279
 	deadline_interval = ms_interval * TIMEOUT_MS;
281 280
 	exec_deadline = SDL_GetPerformanceCounter() + deadline_interval;
282 281
 	screen_resize(WIDTH, HEIGHT);
282
+    SDL_PauseAudioDevice(audio_id, 0);
283 283
 	return 1;
284 284
 }
285 285
 
... ...
@@ -541,7 +541,11 @@ emu_end(Uxn *u)
541 541
 int
542 542
 main(int argc, char **argv)
543 543
 {
544
+    Uint8 dev[0x100] = {0};
544 545
 	Uxn u = {0};
546
+	u.dev = &dev;
547
+	Uxn u_audio = {0};
548
+	u_audio.dev = &dev;
545 549
 	int i = 1;
546 550
 	if(i == argc)
547 551
 		return system_error("usage", "uxnemu [-v] | uxnemu [-f | -2x | -3x | --] file.rom [args...]");
... ...
@@ -559,10 +563,16 @@ main(int argc, char **argv)
559 563
 		}
560 564
 	}
561 565
 	/* Start system. */
562
-	if(!emu_init())
563
-		return system_error("Init", "Failed to initialize varvara.");
564
-	if(!system_init(&u, (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8)), argv[i++]))
566
+	Uint8 *ram = (Uint8 *)calloc(0x10000 * RAM_PAGES, sizeof(Uint8));
567
+	char *rom = argv[i++];
568
+	if(!system_init(&u, ram, rom)) {
569
+		return system_error("Init", "Failed to initialize uxn.");
570
+    }
571
+	if(!system_init(&u_audio, ram, rom)) {
565 572
 		return system_error("Init", "Failed to initialize uxn.");
573
+    }
574
+	if(!emu_init(&u_audio))
575
+		return system_error("Init", "Failed to initialize varvara.");
566 576
 	/* Game Loop */
567 577
 	u.dev[0x17] = argc - i;
568 578
 	if(uxn_eval(&u, PAGE_PROGRAM)) {