host sample rate support for Pico
authornotaz <notasas@gmail.com>
Mon, 12 May 2008 20:17:32 +0000 (20:17 +0000)
committernotaz <notasas@gmail.com>
Mon, 12 May 2008 20:17:32 +0000 (20:17 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@445 be3aeb3a-fb24-0410-a615-afba39da0efa

Pico/Pico.h
Pico/Pico/Pico.c
Pico/Pico/xpcm.c
Pico/PicoInt.h
Pico/sound/sound.c

index 0178590..0ae2544 100644 (file)
@@ -71,7 +71,7 @@ extern int  (*PicoMCDcloseTray)(void);
 extern int PicoCDBuffers;\r
 \r
 // Pico/Pico.c\r
-#define XPCM_BUFFER_SIZE (320+32)\r
+#define XPCM_BUFFER_SIZE (320+160)\r
 typedef struct\r
 {\r
        int pen_pos[2];\r
index ece6d64..00fe576 100644 (file)
@@ -8,6 +8,14 @@ picohw_state PicoPicohw;
 static int prev_line_cnt_irq3 = 0, prev_line_cnt_irq5 = 0;
 static int fifo_bytes_line = (16000<<16)/60/262/2; // fifo bytes/line. FIXME: other rates, modes
 
+PICO_INTERNAL void PicoReratePico(void)
+{
+  if (Pico.m.pal)
+       fifo_bytes_line = (16000<<16)/50/312/2;
+  else fifo_bytes_line = (16000<<16)/60/262/2;
+  PicoPicoPCMRerate();
+}
+
 static void PicoLinePico(int count)
 {
   PicoPicohw.line_counter += count;
index a92f4d6..4e2de8b 100644 (file)
@@ -15,7 +15,7 @@
        else if ( val < min ) val = min; \
 }
 
-const int TableQuant[8] =
+static const int TableQuant[8] =
 {
   ADFIX(0.8984375),
   ADFIX(0.8984375),
@@ -29,17 +29,24 @@ const int TableQuant[8] =
 
 // changed using trial and error..
 //const int quant_mul[16] = { 1, 3, 5, 7, 9, 11, 13, 15, -1, -3, -5, -7, -9, -11, -13, -15 };
-const int quant_mul[16]   = { 1, 3, 5, 7, 9, 11, 13, -1, -1, -3, -5, -7, -9, -11, -13, -15 };
+static const int quant_mul[16]   = { 1, 3, 5, 7, 9, 11, 13, -1, -1, -3, -5, -7, -9, -11, -13, -15 };
+
+static int sample = 0, quant = 0, sgn = 0;
+static int stepsamples = (44100<<10)/16000;
 
-static int sample = 0, quant = 0;
 
 PICO_INTERNAL void PicoPicoPCMReset(void)
 {
-  sample = 0;
+  sample = sgn = 0;
   quant = 0x7f;
   memset(PicoPicohw.xpcm_buffer, 0, sizeof(PicoPicohw.xpcm_buffer));
 }
 
+PICO_INTERNAL void PicoPicoPCMRerate(void)
+{
+  stepsamples = (PsndRate<<10)/16000;
+}
+
 #define XSHIFT 7
 
 #define do_sample() \
@@ -47,24 +54,16 @@ PICO_INTERNAL void PicoPicoPCMReset(void)
   sample += quant * quant_mul[srcval] >> XSHIFT; \
   quant = (quant * TableQuant[srcval&7]) >> ADPCMSHIFT; \
   Limit(quant, 0x6000, 0x7f); \
-  Limit(sample, 32767, -32768); \
+  Limit(sample, 32767/2, -32768/2); \
 }
 
 PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
 {
   unsigned char *src = PicoPicohw.xpcm_buffer;
   unsigned char *lim = PicoPicohw.xpcm_ptr;
-  int srcval, stepsamples = (44100<<10)/16000, needsamples = 0; // TODO: stepsamples
+  int srcval, needsamples = 0;
 
-  if (src == lim)
-  {
-    if (stereo)
-      // still must expand SN76496 to stereo
-      for (; length > 0; buffer+=2, length--)
-        buffer[1] = buffer[0];
-    sample = quant = 0;
-    return;
-  }
+  if (src == lim) goto end;
 
   for (; length > 0 && src < lim; src++)
   {
@@ -72,7 +71,7 @@ PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
     do_sample();
 
     for (needsamples += stepsamples; needsamples > (1<<10) && length > 0; needsamples -= (1<<10), length--) {
-      *buffer++ = sample;
+      *buffer++ += sample;
       if (stereo) { buffer[0] = buffer[-1]; buffer++; }
     }
 
@@ -80,9 +79,13 @@ PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
     do_sample();
 
     for (needsamples += stepsamples; needsamples > (1<<10) && length > 0; needsamples -= (1<<10), length--) {
-      *buffer++ = sample;
+      *buffer++ += sample;
       if (stereo) { buffer[0] = buffer[-1]; buffer++; }
     }
+
+    // lame normalization stuff, needed due to wrong adpcm algo
+    sgn += (sample < 0) ? -1 : 1;
+    if (sgn < -16 || sgn > 16) sample -= sample >> 5;
   }
 
   if (src < lim) {
@@ -90,11 +93,21 @@ PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo)
     memmove(PicoPicohw.xpcm_buffer, src, di);
     PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer + di;
     elprintf(EL_STATUS, "xpcm update: over %i", di);
+    // adjust fifo
+    PicoPicohw.fifo_bytes = di;
+    return;
   }
-  else
-  {
-    elprintf(EL_STATUS, "xpcm update: under %i", length);
-    PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
-  }
+
+  elprintf(EL_STATUS, "xpcm update: under %i", length);
+  PicoPicohw.xpcm_ptr = PicoPicohw.xpcm_buffer;
+
+end:
+  if (stereo)
+    // still must expand SN76496 to stereo
+    for (; length > 0; buffer+=2, length--)
+      buffer[1] = buffer[0];
+
+  sample = sgn = 0;
+  quant = 0x7f;
 }
 
index eb78f8c..dcbb57a 100644 (file)
@@ -443,10 +443,12 @@ PICO_INTERNAL int PicoFrameMCD(void);
 \r
 // Pico/Pico.c\r
 PICO_INTERNAL int PicoInitPico(void);\r
+PICO_INTERNAL void PicoReratePico(void);\r
 \r
 // Pico/xpcm.c\r
 PICO_INTERNAL void PicoPicoPCMUpdate(short *buffer, int length, int stereo);\r
 PICO_INTERNAL void PicoPicoPCMReset(void);\r
+PICO_INTERNAL void PicoPicoPCMRerate(void);\r
 \r
 // Sek.c\r
 PICO_INTERNAL int SekInit(void);\r
index f0348db..1d6c168 100644 (file)
@@ -158,6 +158,9 @@ void PsndRerate(int preserve_state)
 \r
   // set mixer\r
   PsndMix_32_to_16l = (PicoOpt & POPT_EN_STEREO) ? mix_32_to_16l_stereo : mix_32_to_16_mono;\r
+\r
+  if (PicoAHW & PAHW_PICO)\r
+    PicoReratePico();\r
 }\r
 \r
 \r