sound, don't reinitialize after menu if not needed
authorkub <derkub@gmail.com>
Sat, 18 May 2024 09:35:22 +0000 (11:35 +0200)
committerkub <derkub@gmail.com>
Sat, 18 May 2024 19:21:54 +0000 (21:21 +0200)
pico/sound/sn76496.c
pico/sound/sn76496.h
pico/sound/sound.c
pico/sound/ym2612.c

index 0837839..1624d13 100644 (file)
@@ -279,6 +279,15 @@ static void SN76496_set_gain(struct SN76496 *R,int gain)
 }\r
 \r
 \r
+//static\r
+void SN76496_set_clockrate(int clock,int sample_rate)\r
+{\r
+       struct SN76496 *R = &ono_sn;\r
+\r
+       R->SampleRate = sample_rate;\r
+       SN76496_set_clock(R,clock);\r
+}\r
+\r
 //static\r
 int SN76496_init(int clock,int sample_rate)\r
 {\r
@@ -287,8 +296,7 @@ int SN76496_init(int clock,int sample_rate)
 \r
        //R->Channel = stream_create(0,1, sample_rate,R,SN76496Update);\r
 \r
-       R->SampleRate = sample_rate;\r
-       SN76496_set_clock(R,clock);\r
+       SN76496_set_clockrate(clock,sample_rate);\r
 \r
        for (i = 0;i < 4;i++) R->Volume[i] = 0;\r
 \r
index 707bb5d..8677ea9 100644 (file)
@@ -4,6 +4,7 @@
 void SN76496Write(int data);\r
 void SN76496Update(short *buffer,int length,int stereo);\r
 void SN76496Config(int panning);\r
+void SN76496_set_clockrate(int clock,int sample_rate);\r
 int  SN76496_init(int clock,int sample_rate);\r
 \r
 #endif\r
index edf9c89..2150f68 100644 (file)
@@ -33,7 +33,6 @@ static int (*PsndFMUpdate)(s32 *buffer, int length, int stereo, int is_buf_empty
 \r
 // ym2413\r
 static OPLL *opll = NULL;\r
-static OPLL old_opll;\r
 static struct {\r
   uint32_t adr;\r
   uint8_t reg[sizeof(opll->reg)];\r
@@ -152,6 +151,10 @@ static int YM2612UpdateONE(s32 *buffer, int length, int stereo, int is_buf_empty
   return YM2612UpdateOne(buffer, length, stereo, is_buf_empty);\r
 }\r
 \r
+static int ymclock;\r
+static int ymrate;\r
+static int ymopts;\r
+\r
 // to be called after changing sound rate or chips\r
 void PsndRerate(int preserve_state)\r
 {\r
@@ -159,54 +162,58 @@ void PsndRerate(int preserve_state)
   int target_fps = Pico.m.pal ? 50 : 60;\r
   int target_lines = Pico.m.pal ? 313 : 262;\r
   int sms_clock = Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15;\r
+  int ym2413_rate = (sms_clock + 36) / 72;\r
   int ym2612_clock = Pico.m.pal ? OSC_PAL/7 : OSC_NTSC/7;\r
   int ym2612_rate = YM2612_NATIVE_RATE();\r
-  int ym2413_rate = (sms_clock + 36) / 72;\r
+  int ym2612_init = !preserve_state;\r
 \r
-  if (preserve_state) {\r
+  // don't init YM2612 if preserve_state and no parameter changes\r
+  ym2612_init |= ymclock != ym2612_clock || ymopts != (PicoIn.opt & (POPT_DIS_FM_SSGEG|POPT_EN_FM_DAC));\r
+  ym2612_init |= ymrate != (PicoIn.opt & POPT_EN_FM_FILTER ? ym2612_rate : PicoIn.sndRate);\r
+  ymclock = ym2612_clock;\r
+  ymrate = (PicoIn.opt & POPT_EN_FM_FILTER ? ym2612_rate : PicoIn.sndRate);\r
+  ymopts = PicoIn.opt & (POPT_DIS_FM_SSGEG|POPT_EN_FM_DAC);\r
+\r
+  if (preserve_state && ym2612_init) {\r
     state = malloc(0x204);\r
     if (state == NULL) return;\r
     ym2612_pack_state();\r
     memcpy(state, YM2612GetRegs(), 0x204);\r
-\r
-    if (opll != NULL)\r
-       memcpy(&old_opll, opll, sizeof(OPLL)); // remember old state\r
   }\r
+\r
   if (PicoIn.AHW & PAHW_SMS) {\r
     OPLL_setRate(opll, ym2413_rate);\r
-    OPLL_reset(opll);\r
+    if (!preserve_state)\r
+      OPLL_reset(opll);\r
     YMFM_setup_FIR(ym2413_rate, PicoIn.sndRate, 0);\r
     PsndFMUpdate = YM2413UpdateFIR;\r
   } else if ((PicoIn.opt & POPT_EN_FM_FILTER) && ym2612_rate != PicoIn.sndRate) {\r
     // polyphase FIR resampler, resampling directly from native to output rate\r
-    YM2612Init(ym2612_clock, ym2612_rate,\r
+    if (ym2612_init)\r
+      YM2612Init(ym2612_clock, ym2612_rate,\r
         ((PicoIn.opt&POPT_DIS_FM_SSGEG) ? 0 : ST_SSG) |\r
         ((PicoIn.opt&POPT_EN_FM_DAC)    ? ST_DAC : 0));\r
     YMFM_setup_FIR(ym2612_rate, PicoIn.sndRate, PicoIn.opt & POPT_EN_STEREO);\r
     PsndFMUpdate = YM2612UpdateFIR;\r
   } else {\r
-    YM2612Init(ym2612_clock, PicoIn.sndRate,\r
+    if (ym2612_init)\r
+      YM2612Init(ym2612_clock, PicoIn.sndRate,\r
         ((PicoIn.opt&POPT_DIS_FM_SSGEG) ? 0 : ST_SSG) |\r
         ((PicoIn.opt&POPT_EN_FM_DAC)    ? ST_DAC : 0));\r
     PsndFMUpdate = YM2612UpdateONE;\r
   }\r
-  if (preserve_state) {\r
+\r
+  if (preserve_state && ym2612_init) {\r
     // feed it back it's own registers, just like after loading state\r
     memcpy(YM2612GetRegs(), state, 0x204);\r
     ym2612_unpack_state();\r
-\r
-    if (opll != NULL) {\r
-      memcpy(&opll->adr, &old_opll.adr, sizeof(OPLL)-20); // restore old state\r
-      OPLL_forceRefresh(opll);\r
-    }\r
+    free(state);\r
   }\r
 \r
-  if (preserve_state) memcpy(state, sn76496_regs, 28*4); // remember old state\r
-  SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PicoIn.sndRate);\r
-  if (preserve_state) memcpy(sn76496_regs, state, 28*4); // restore old state\r
-\r
-  if (state)\r
-    free(state);\r
+  if (preserve_state)\r
+    SN76496_set_clockrate(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PicoIn.sndRate);\r
+  else\r
+    SN76496_init(Pico.m.pal ? OSC_PAL/15 : OSC_NTSC/15, PicoIn.sndRate);\r
 \r
   // calculate Pico.snd.len\r
   Pico.snd.len = PicoIn.sndRate / target_fps;\r
index f8a1862..f0e60b4 100644 (file)
@@ -193,6 +193,8 @@ UINT16 ym_tl_tab2[13*TL_RES_LEN];
 /* sin waveform table in 'decibel' scale (use only period/4 values) */\r
 static UINT16 ym_sin_tab[256];\r
 \r
+static int ym_init_tab;\r
+\r
 /* sustain level table (3dB per step) */\r
 /* bit0, bit1, bit2, bit3, bit4, bit5, bit6 */\r
 /* 1,    2,    4,    8,    16,   32,   64   (value)*/\r
@@ -1467,6 +1469,9 @@ static void init_tables(void)
        signed int n;\r
        double o,m;\r
 \r
+       if (ym_init_tab) return;\r
+       ym_init_tab = 1;\r
+\r
        for (i=0; i < 256; i++)\r
        {\r
                /* non-standard sinus */\r