From 8d17be50ef4e6dbe1dd776b377502f1f37e20e5e Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Tue, 23 Apr 2024 21:09:10 +0300 Subject: [PATCH] Audio event priority change, intreq2 handling changes, small period hack modified. --- audio.cpp | 76 +++++++++++++++++++++++++++++++++--------------- include/events.h | 3 +- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/audio.cpp b/audio.cpp index 6c7fbf15..20340148 100644 --- a/audio.cpp +++ b/audio.cpp @@ -57,6 +57,7 @@ #define PERIOD_MIN 1 #define PERIOD_MIN_NONCE 60 #define PERIOD_MIN_LOOP 16 +#define PERIOD_MIN_LOOP_COUNT 64 #define PERIOD_LOW 124 @@ -154,6 +155,7 @@ struct audio_channel_data int dmaofftime_active; int dmaofftime_cpu_cnt; uaecptr dmaofftime_pc; + int minperloop; int volcntbufcnt; float volcntbuf[VOLCNT_BUFFER_SIZE]; }; @@ -1395,7 +1397,7 @@ static void sample16si_rh_handler (void) static int audio_work_to_do; -static void zerostate (int nr) +static void zerostate(int nr, bool reset) { struct audio_channel_data *cdp = audio_channel + nr; #if DEBUG_AUDIO > 0 @@ -1405,11 +1407,14 @@ static void zerostate (int nr) cdp->state = 0; cdp->irqcheck = 0; cdp->evtime = MAX_EV; - cdp->intreq2 = false; + if (!currprefs.cpu_memory_cycle_exact || reset) { + cdp->intreq2 = false; + } cdp->dmaenstore = false; cdp->dmaofftime_active = 0; cdp->volcnt = 0; cdp->volcntbufcnt = 0; + cdp->minperloop = 0; memset(cdp->volcntbuf, 0, sizeof(cdp->volcntbuf)); #if TEST_AUDIO > 0 cdp->have_dat = false; @@ -1451,10 +1456,12 @@ static void audio_event_reset (void) last_cycles = get_cycles (); next_sample_evtime = scaled_sample_evtime; - for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) - zerostate (i); - for (i = 0; i < audio_total_extra_streams; i++) + for (i = 0; i < AUDIO_CHANNELS_PAULA; i++) { + zerostate(i, true); + } + for (i = 0; i < audio_total_extra_streams; i++) { audio_stream[i].evtime = MAX_EV; + } schedule_audio (); events_schedule (); samplecnt = 0; @@ -1715,7 +1722,7 @@ static bool audio_state_channel2 (int nr, bool perfin) cdp->dmaenstore = chan_ena; if (currprefs.produce_sound == 0) { - zerostate (nr); + zerostate (nr, true); return true; } audio_activate (); @@ -1745,7 +1752,7 @@ static bool audio_state_channel2 (int nr, bool perfin) write_log(_T("%d: INSTADMAOFF\n"), nr, M68K_GETPC); #endif newsample(nr, (cdp->dat2 >> 0) & 0xff); - zerostate(nr); + zerostate(nr, true); } else { if (warned >= 0) { warned--; @@ -1793,7 +1800,7 @@ static bool audio_state_channel2 (int nr, bool perfin) static int warned = 100; // make sure audio.device AUDxDAT startup returns to idle state before DMA is enabled newsample(nr, (cdp->dat2 >> 0) & 0xff); - zerostate(nr); + zerostate(nr, true); if (warned > 0) { write_log(_T("AUD%d: forced idle state PER=%d PC=%08x\n"), nr, cdp->per, M68K_GETPC); warned--; @@ -1803,13 +1810,13 @@ static bool audio_state_channel2 (int nr, bool perfin) audio_state_channel2(nr, false); } } else { - zerostate(nr); + zerostate(nr, false); } break; case 1: cdp->evtime = MAX_EV; if (!chan_ena) { - zerostate(nr); + zerostate(nr, false); return true; } if (!cdp->dat_written) @@ -1831,7 +1838,7 @@ static bool audio_state_channel2 (int nr, bool perfin) case 5: cdp->evtime = MAX_EV; if (!chan_ena) { - zerostate(nr); + zerostate(nr, false); return true; } if (!cdp->dat_written) @@ -1850,7 +1857,9 @@ static bool audio_state_channel2 (int nr, bool perfin) cdp->state = 2; loadper(nr); cdp->pbufldl = true; - cdp->intreq2 = false; + if (!currprefs.cpu_memory_cycle_exact) { + cdp->intreq2 = false; + } cdp->volcnt = 0; audio_state_channel2(nr, false); break; @@ -1883,13 +1892,17 @@ static bool audio_state_channel2 (int nr, bool perfin) if (audap) loaddat(nr, true); if (chan_ena) { - if (audap) + if (audap) { setdr(nr, false); - if (cdp->intreq2 && audap) + } + if (cdp->intreq2 && audap) { setirq(nr, 21); + cdp->intreq2 = false; + } } else { - if (audap) + if (audap) { setirq(nr, 22); + } } cdp->pbufldl = true; cdp->irqcheck = 0; @@ -1942,13 +1955,17 @@ static bool audio_state_channel2 (int nr, bool perfin) if (chan_ena) { loaddat (nr); - if (napnav) + if (napnav) { setdr(nr, false); - if (cdp->intreq2 && napnav) + } + if (cdp->intreq2 && napnav) { setirq(nr, 31); + cdp->intreq2 = false; + } } else { - if (napnav) + if (napnav) { setirq(nr, 32); + } // cycle-accurate period check was not needed, do delayed check if (!cdp->irqcheck) { cdp->irqcheck = isirq(nr); @@ -1958,12 +1975,11 @@ static bool audio_state_channel2 (int nr, bool perfin) if (debugchannel (nr)) write_log(_T("%d: IDLE\n"), nr); #endif - zerostate(nr); + zerostate(nr, false); return true; } loaddat(nr); } - cdp->intreq2 = false; cdp->pbufldl = true; cdp->state = 2; audio_state_channel2(nr, false); @@ -2482,9 +2498,14 @@ void event_audxdat_func(uae_u32 v) cdp->wlen = cdp->len; // if very low period sample repeats, set higher period value to not cause huge performance drop if (cdp->per < PERIOD_MIN_LOOP * CYCLE_UNIT) { - cdp->per = PERIOD_MIN_LOOP * CYCLE_UNIT; + cdp->minperloop++; + if (cdp->minperloop >= PERIOD_MIN_LOOP_COUNT) { + cdp->per = PERIOD_MIN_LOOP * CYCLE_UNIT; + } + } + if (!(v & 0x80000000)) { + cdp->intreq2 = true; } - cdp->intreq2 = true; if (sampleripper_enabled) do_samplerip(cdp); #if DEBUG_AUDIO > 0 @@ -2551,7 +2572,14 @@ void AUDxDAT(int nr, uae_u16 v, uaecptr addr) int cyc = 0; if (chan_ena) { // AUDxLEN is processed after 1 CCK delay - cyc = 1 * CYCLE_UNIT; + if ((cdp->state & 15) == 2 || (cdp->state & 15) == 3) { + cyc = 1 * CYCLE_UNIT; + // But INTREQ2 is set immediately + if (cdp->wlen == 1) { + cdp->intreq2 = true; + } + vv |= 0x80000000; + } } if (cyc > 0) { event2_newevent_xx(-1, cyc, vv, event_audxdat_func); @@ -2777,7 +2805,7 @@ uae_u8 *restore_audio (int nr, uae_u8 *src) { struct audio_channel_data *acd = audio_channel + nr; - zerostate (nr); + zerostate(nr, true); acd->state = restore_u8 (); acd->data.audvol = restore_u8 (); acd->intreq2 = restore_u8 () ? true : false; diff --git a/include/events.h b/include/events.h index cc04dfb6..ea61af09 100644 --- a/include/events.h +++ b/include/events.h @@ -64,7 +64,8 @@ struct ev2 // hsync handlers must have priority over misc enum { - ev_cia, ev_audio, ev_hsync, ev_hsynch, ev_misc, + ev_cia, ev_hsync, ev_hsynch, ev_misc, + ev_audio, ev_max }; -- 2.47.3