allow slightly deviated sound rates (for Wiz)
[picodrive.git] / pico / sound / sound.c
index 39ae291..a73ebd9 100644 (file)
@@ -17,7 +17,7 @@
 void (*PsndMix_32_to_16l)(short *dest, int *src, int count) = mix_32_to_16l_stereo;\r
 \r
 // master int buffer to mix to\r
-static int PsndBuffer[2*44100/50];\r
+static int PsndBuffer[2*(44100+100)/50];\r
 \r
 // dac\r
 static unsigned short dac_info[312+4]; // pppppppp ppppllll, p - pos in buff, l - length to write for this sample\r
@@ -126,19 +126,23 @@ void PsndRerate(int preserve_state)
 \r
   // not all rates are supported in MCD mode due to mp3 decoder limitations\r
   if (PicoAHW & PAHW_MCD) {\r
-    if (PsndRate != 11025 && PsndRate != 22050 && PsndRate != 44100) PsndRate = 22050;\r
+    if (!(11025-100 <= PsndRate && PsndRate <= 11025+100) &&\r
+        !(22050-100 <= PsndRate && PsndRate <= 22050+100) &&\r
+        !(44100-100 <= PsndRate && PsndRate <= 44100+100))\r
+      PsndRate = 22050;\r
     PicoOpt |= POPT_EN_STEREO; // force stereo\r
   }\r
 \r
   if (preserve_state) {\r
-    state = malloc(0x200);\r
+    state = malloc(0x204);\r
     if (state == NULL) return;\r
-    memcpy(state, YM2612GetRegs(), 0x200);\r
+    ym2612_pack_state();\r
+    memcpy(state, YM2612GetRegs(), 0x204);\r
   }\r
   YM2612Init(Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7, PsndRate);\r
   if (preserve_state) {\r
     // feed it back it's own registers, just like after loading state\r
-    memcpy(YM2612GetRegs(), state, 0x200);\r
+    memcpy(YM2612GetRegs(), state, 0x204);\r
     ym2612_unpack_state();\r
     if ((PicoAHW & PAHW_MCD) && !(Pico_mcd->s68k_regs[0x36] & 1) && (Pico_mcd->scd.Status_CDC & 1))\r
       cdda_start_play();\r
@@ -211,12 +215,14 @@ static pm_file *cdda_stream = NULL;
 \r
 static void cdda_raw_update(int *buffer, int length)\r
 {\r
-  int ret, cdda_bytes;\r
-  if (cdda_stream == NULL) return;\r
+  int ret, cdda_bytes, mult = 1;\r
+  if (cdda_stream == NULL)\r
+    return;\r
 \r
   cdda_bytes = length*4;\r
-  if (PsndRate <= 22050) cdda_bytes *= 2;\r
-  if (PsndRate <  22050) cdda_bytes *= 2;\r
+  if (PsndRate <= 22050 + 100) mult = 2;\r
+  if (PsndRate <  22050 - 100) mult = 4;\r
+  cdda_bytes *= mult;\r
 \r
   ret = pm_read(cdda_out_buffer, cdda_bytes, cdda_stream);\r
   if (ret < cdda_bytes) {\r
@@ -226,10 +232,10 @@ static void cdda_raw_update(int *buffer, int length)
   }\r
 \r
   // now mix\r
-  switch (PsndRate) {\r
-    case 44100: mix_16h_to_32(buffer, cdda_out_buffer, length*2); break;\r
-    case 22050: mix_16h_to_32_s1(buffer, cdda_out_buffer, length*2); break;\r
-    case 11025: mix_16h_to_32_s2(buffer, cdda_out_buffer, length*2); break;\r
+  switch (mult) {\r
+    case 1: mix_16h_to_32(buffer, cdda_out_buffer, length*2); break;\r
+    case 2: mix_16h_to_32_s1(buffer, cdda_out_buffer, length*2); break;\r
+    case 4: mix_16h_to_32_s2(buffer, cdda_out_buffer, length*2); break;\r
   }\r
 }\r
 \r
@@ -297,7 +303,7 @@ PICO_INTERNAL void PsndClear(void)
 }\r
 \r
 \r
-PICO_INTERNAL int PsndRender(int offset, int length)\r
+static int PsndRender(int offset, int length)\r
 {\r
   int  buf32_updated = 0;\r
   int *buf32 = PsndBuffer+offset;\r
@@ -361,6 +367,35 @@ PICO_INTERNAL int PsndRender(int offset, int length)
   return length;\r
 }\r
 \r
+// to be called on 224 or line_sample scanlines only\r
+PICO_INTERNAL void PsndGetSamples(int y)\r
+{\r
+#if SIMPLE_WRITE_SOUND\r
+  if (y != 224) return;\r
+  PsndRender(0, PsndLen);\r
+  if (PicoWriteSound) PicoWriteSound(PsndLen);\r
+  PsndClear();\r
+#else\r
+  static int curr_pos = 0;\r
+\r
+  if (y == 224)\r
+  {\r
+    if (emustatus & 2)\r
+         curr_pos += PsndRender(curr_pos, PsndLen-PsndLen/2);\r
+    else curr_pos  = PsndRender(0, PsndLen);\r
+    if (emustatus&1) emustatus|=2; else emustatus&=~2;\r
+    if (PicoWriteSound) PicoWriteSound(curr_pos);\r
+    // clear sound buffer\r
+    PsndClear();\r
+  }\r
+  else if (emustatus & 3) {\r
+    emustatus|= 2;\r
+    emustatus&=~1;\r
+    curr_pos = PsndRender(0, PsndLen/2);\r
+  }\r
+#endif\r
+}\r
+\r
 \r
 // -----------------------------------------------------------------\r
 //                            z80 stuff\r