shithub: psxe

Download patch

ref: c48f128074614094e15b019389c8efb7cbc14ad1
parent: bf43cbd3c958fff8abc63c1a12afe878c2b06299
author: allkern <lisandroaalarcon@gmail.com>
date: Sun Oct 1 07:03:40 EDT 2023

Fix stereo audio

--- a/frontend/main.c
+++ b/frontend/main.c
@@ -14,10 +14,13 @@
     psx_cdrom_get_cdda_samples(cdrom, buf, size);
 
     for (int i = 0; i < (size >> 2); i++) {
-        int32_t sample = psx_spu_get_sample(spu) / 2;
+        uint32_t sample = psx_spu_get_sample(spu);
 
-        *(uint16_t*)(&buf[(i << 2) + 0]) += sample;
-        *(uint16_t*)(&buf[(i << 2) + 2]) += sample;
+        int16_t left = (int16_t)(sample & 0xffff);
+        int16_t right = (int16_t)(sample >> 16);
+
+        *(int16_t*)(&buf[(i << 2) + 0]) += left;
+        *(int16_t*)(&buf[(i << 2) + 2]) += right;
     }
 }
 
@@ -106,7 +109,6 @@
 
     psx_pad_detach_joy(psx->pad, 0);
     psx_destroy(psx);
-    //psxi_sda_destroy(controller);
     psxe_screen_destroy(screen);
 
     return 0;
--- a/psx/dev/spu.c
+++ b/psx/dev/spu.c
@@ -5,6 +5,8 @@
 #include "spu.h"
 #include "../log.h"
 
+#define CLAMP(v, l, h) ((v <= l) ? l : ((v >= h) ? h : v))
+
 static const int g_spu_pos_adpcm_table[] = {
     0, +60, +115, +98, +122
 };
@@ -284,12 +286,13 @@
   6-7   Unused (should be 0)
 */
 
-int32_t psx_spu_get_sample(psx_spu_t* spu) {
+uint32_t psx_spu_get_sample(psx_spu_t* spu) {
     if (spu->endx == 0x00ffffff)
         return 0x0000;
 
     int voice_count = 0;
-    int output = 0x0000;
+    int left = 0x0000;
+    int right = 0x0000;
 
     for (int v = 0; v < 24; v++) {
         if (!spu->data[v].playing)
@@ -348,7 +351,8 @@
         out += (g2 * spu->data[v].s[1]) >> 15;
         out += (g3 * spu->data[v].s[0]) >> 15;
 
-        output += out * ((spu->data[v].lvol + spu->data[v].rvol) / 2);
+        left += out * spu->data[v].lvol;
+        right += out * spu->data[v].rvol;
 
         uint16_t step = spu->voice[v].adsampr;
 
@@ -360,7 +364,8 @@
     if (!voice_count)
         return 0x00000000;
 
-    output = (output < INT16_MIN) ? INT16_MIN : ((output > INT16_MAX) ? INT16_MAX : output);
+    uint16_t clampl = CLAMP(left, INT16_MIN, INT16_MAX);
+    uint16_t clampr = CLAMP(right, INT16_MIN, INT16_MAX);
 
-    return output;
+    return clampl | (((uint32_t)clampr) << 16);
 }
\ No newline at end of file
--- a/psx/dev/spu.h
+++ b/psx/dev/spu.h
@@ -127,6 +127,6 @@
 void psx_spu_write16(psx_spu_t*, uint32_t, uint16_t);
 void psx_spu_write8(psx_spu_t*, uint32_t, uint8_t);
 void psx_spu_destroy(psx_spu_t*);
-int32_t psx_spu_get_sample(psx_spu_t*);
+uint32_t psx_spu_get_sample(psx_spu_t*);
 
 #endif
\ No newline at end of file
--