sound: fix ym2612 forgetting lfo state when dac is on
authornotaz <notasas@gmail.com>
Thu, 15 Jun 2023 23:06:04 +0000 (02:06 +0300)
committeririxxxx <31696370+irixxxx@users.noreply.github.com>
Fri, 16 Jun 2023 09:39:17 +0000 (11:39 +0200)
for less bad audio in OD2

pico/sound/ym2612.c

index 39958f5..6d47850 100644 (file)
@@ -892,7 +892,8 @@ typedef struct
        UINT16 vol_out2;\r
        UINT16 vol_out3;\r
        UINT16 vol_out4;\r
-       UINT32 pad[2];\r
+       UINT32 lfo_init_sft16;\r
+       UINT32 pad;\r
        UINT32 phase1;   /* 10 */\r
        UINT32 phase2;\r
        UINT32 phase3;\r
@@ -1225,18 +1226,18 @@ static chan_rend_context crct;
 static void chan_render_prep(void)\r
 {\r
        crct.eg_timer_add = ym2612.OPN.eg_timer_add;\r
+       crct.lfo_init_sft16 = g_lfo_ampm << 16;\r
        crct.lfo_inc = ym2612.OPN.lfo_inc;\r
 }\r
 \r
-static void chan_render_finish(s32 *buffer, unsigned short length, int active_chans)\r
+static void chan_render_finish(s32 *buffer, int length, int active_chans)\r
 {\r
        ym2612.OPN.eg_cnt = crct.eg_cnt;\r
        ym2612.OPN.eg_timer = crct.eg_timer;\r
-       g_lfo_ampm = crct.pack >> 16; // need_save\r
-       ym2612.OPN.lfo_cnt = crct.lfo_cnt;\r
+       ym2612.OPN.lfo_cnt += ym2612.OPN.lfo_inc * length;\r
 }\r
 \r
-static UINT32 update_lfo_phase(FM_SLOT *SLOT, UINT32 block_fnum)\r
+static UINT32 update_lfo_phase(const FM_SLOT *SLOT, UINT32 block_fnum)\r
 {\r
        UINT32 fnum_lfo;\r
        INT32  lfo_fn_table_index_offset;\r
@@ -1273,7 +1274,7 @@ static int chan_render(s32 *buffer, int length, int c, UINT32 flags) // flags: s
 \r
        if (crct.lfo_inc) {\r
                flags |= 8;\r
-               flags |= g_lfo_ampm << 16;\r
+               flags |= crct.lfo_init_sft16;\r
                flags |= crct.CH->AMmasks << 8;\r
                if (crct.CH->ams == 8) // no ams\r
                     flags &= ~0xf00;\r
@@ -1809,6 +1810,7 @@ int YM2612UpdateOne_(s32 *buffer, int length, int stereo, int is_buf_empty)
        if (ym2612.slot_mask & 0x00f000) active_chs |= chan_render(buffer, length, 3, flags|((pan&0x0c0)>>2)) << 3;\r
        BIT_IF(flags, 1, (ym2612.ssg_mask & 0x0f0000) && (ym2612.OPN.ST.flags & 1));\r
        if (ym2612.slot_mask & 0x0f0000) active_chs |= chan_render(buffer, length, 4, flags|((pan&0x300)>>4)) << 4;\r
+       g_lfo_ampm = crct.pack >> 16; // need_save; now because ch5 might skip updating it\r
        BIT_IF(flags, 1, (ym2612.ssg_mask & 0xf00000) && (ym2612.OPN.ST.flags & 1));\r
        if (ym2612.slot_mask & 0xf00000) active_chs |= chan_render(buffer, length, 5, flags|((pan&0xc00)>>6)|(!!ym2612.dacen<<2)) << 5;\r
 #undef BIT_IF\r