audio: SN76496 fixes
authorkub <derkub@gmail.com>
Fri, 24 Apr 2020 17:05:27 +0000 (19:05 +0200)
committerkub <derkub@gmail.com>
Fri, 24 Apr 2020 17:08:49 +0000 (19:08 +0200)
pico/memory.c
pico/pico_int.h
pico/sms.c
pico/sound/sn76496.c
pico/sound/sound.c

index e1afb4d..c0ba9ff 100644 (file)
@@ -883,7 +883,7 @@ static void m68k_mem_setup(void)
 static int get_scanline(int is_from_z80)\r
 {\r
   if (is_from_z80) {\r
-    int mclk_z80 = z80_cyclesDone() * 15;\r
+    int mclk_z80 = (z80_cyclesLeft<0 ? Pico.t.z80c_aim : z80_cyclesDone()) * 15;\r
     int mclk_line = Pico.t.z80_scanline * 488 * 7;\r
     while (mclk_z80 - mclk_line >= 488 * 7)\r
       Pico.t.z80_scanline++, mclk_line += 488 * 7;\r
index 7539379..088c7aa 100644 (file)
@@ -213,7 +213,7 @@ extern struct DrZ80 drZ80;
 #define z80_cyclesDone() \\r
   (Pico.t.z80c_aim - z80_cyclesLeft)\r
 \r
-#define cycles_68k_to_z80(x) ((x) * 3823 >> 13)\r
+#define cycles_68k_to_z80(x) ((x) * 3822 >> 13)\r
 \r
 // ----------------------- SH2 CPU -----------------------\r
 \r
index 901f2f5..0f4a48a 100644 (file)
@@ -152,7 +152,7 @@ static void z80_sms_out(unsigned short a, unsigned char d)
 
     case 0x40:
     case 0x41:
-      if ((d & 0x90) == 0x90);
+      if ((d & 0x90) == 0x90)
         PsndDoPSG(Pico.m.scanline);
       SN76496Write(d);
       break;
index b212759..4507507 100644 (file)
@@ -173,9 +173,12 @@ void SN76496Update(short *buffer, int length, int stereo)
                        /* If we exit the loop in the middle, Output[i] has to be inverted */\r
                        /* and vol[i] incremented only if the exit status of the square */\r
                        /* wave is 1. */\r
+                       left = 0;\r
                        while (R->Count[i] <= 0)\r
                        {\r
-                               R->Count[i] += R->Period[i];\r
+                               if (R->Count[i] + R->Period[i]*4 < R->Period[i])\r
+                                       left+= 4, R->Count[i] += R->Period[i]*4;\r
+                               else    left++,   R->Count[i] += R->Period[i];\r
                                if (R->Count[i] > 0)\r
                                {\r
                                        R->Output[i] ^= 1;\r
@@ -186,6 +189,9 @@ void SN76496Update(short *buffer, int length, int stereo)
                                vol[i] += R->Period[i];\r
                        }\r
                        if (R->Output[i]) vol[i] -= R->Count[i];\r
+                       /* Cut of anything above the sample freqency. It will only create */\r
+                       /* aliasing and hearable distortions anyway. */\r
+                       if (left > 1) vol[i] = STEP/2;\r
                }\r
 \r
                left = STEP;\r
index 5452160..a6d55df 100644 (file)
@@ -259,6 +259,7 @@ static int PsndRender(int offset, int length)
   int stereo = (PicoIn.opt & 8) >> 3;\r
   int fmlen = ((Pico.snd.fm_pos+0x80000) >> 20);\r
   int daclen = ((Pico.snd.dac_pos+0x80000) >> 20);\r
+  int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);\r
 \r
   buf32 = PsndBuffer+(offset<<stereo);\r
 \r
@@ -282,6 +283,14 @@ static int PsndRender(int offset, int length)
     Pico.snd.dac_val2 = Pico.snd.dac_val;\r
   }\r
 \r
+  // Add in parts of the PSG output not yet done\r
+  if (length-psglen > 0) {\r
+    short *psgbuf = PicoIn.sndOut + (psglen << stereo);\r
+    Pico.snd.psg_pos += (length-psglen) << 16;\r
+    if (PicoIn.opt & POPT_EN_PSG)\r
+      SN76496Update(psgbuf, length-psglen, stereo);\r
+  }\r
+\r
   // Add in parts of the FM buffer not yet done\r
   if (length-fmlen > 0) {\r
     int *fmbuf = buf32 + ((fmlen-offset) << stereo);\r
@@ -323,8 +332,6 @@ PICO_INTERNAL void PsndGetSamples(int y)
 {\r
   static int curr_pos = 0;\r
 \r
-  PsndDoPSG(y - 1);\r
-\r
   curr_pos  = PsndRender(0, Pico.snd.len_use);\r
 \r
   if (PicoIn.writeSound)\r
@@ -333,11 +340,20 @@ PICO_INTERNAL void PsndGetSamples(int y)
   PsndClear();\r
 }\r
 \r
-PICO_INTERNAL void PsndGetSamplesMS(int y)\r
+static int PsndRenderMS(int offset, int length)\r
 {\r
-  int length = Pico.snd.len_use;\r
+  int stereo = (PicoIn.opt & 8) >> 3;\r
+  int psglen = ((Pico.snd.psg_pos+0x8000) >> 16);\r
 \r
-  PsndDoPSG(y - 1);\r
+  pprof_start(sound);\r
+\r
+  // Add in parts of the PSG output not yet done\r
+  if (length-psglen > 0) {\r
+    short *psgbuf = PicoIn.sndOut + (psglen << stereo);\r
+    Pico.snd.psg_pos += (length-psglen) << 16;\r
+    if (PicoIn.opt & POPT_EN_PSG)\r
+      SN76496Update(psgbuf, length-psglen, stereo);\r
+  }\r
 \r
   // upmix to "stereo" if needed\r
   if (PicoIn.opt & POPT_EN_STEREO) {\r
@@ -346,8 +362,19 @@ PICO_INTERNAL void PsndGetSamplesMS(int y)
       *p |= *p << 16;\r
   }\r
 \r
+  pprof_end(sound);\r
+\r
+  return length;\r
+}\r
+\r
+PICO_INTERNAL void PsndGetSamplesMS(int y)\r
+{\r
+  static int curr_pos = 0;\r
+\r
+  curr_pos  = PsndRenderMS(0, Pico.snd.len_use);\r
+\r
   if (PicoIn.writeSound != NULL)\r
-    PicoIn.writeSound(length * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));\r
+    PicoIn.writeSound(curr_pos * ((PicoIn.opt & POPT_EN_STEREO) ? 4 : 2));\r
   PsndClear();\r
 }\r
 \r