From 4c9b172b50a240efc37aec8bdd4a59972fbf10c4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Tue, 3 May 2022 02:52:38 -0500 Subject: [PATCH] YM2610: optimize oscilloscope fetch CPU usage --- src/engine/platform/sound/ymfm/ymfm_adpcm.cpp | 24 ++++++++++++------- src/engine/platform/sound/ymfm/ymfm_adpcm.h | 15 ++++++++++-- src/engine/platform/ym2610.cpp | 21 +++++++++------- src/engine/platform/ym2610b.cpp | 19 ++++++++------- 4 files changed, 52 insertions(+), 27 deletions(-) diff --git a/src/engine/platform/sound/ymfm/ymfm_adpcm.cpp b/src/engine/platform/sound/ymfm/ymfm_adpcm.cpp index 01f35367..76839e78 100644 --- a/src/engine/platform/sound/ymfm/ymfm_adpcm.cpp +++ b/src/engine/platform/sound/ymfm/ymfm_adpcm.cpp @@ -220,7 +220,7 @@ bool adpcm_a_channel::clock() //------------------------------------------------- template -void adpcm_a_channel::output(ymfm_output &output) const +void adpcm_a_channel::output(ymfm_output &output) { // volume combines instrument and total levels int vol = (m_regs.ch_instrument_level(m_choffs) ^ 0x1f) + (m_regs.total_level() ^ 0x3f); @@ -239,14 +239,18 @@ void adpcm_a_channel::output(ymfm_output &output) const int16_t value = ((int16_t(m_accumulator << 4) * mul) >> shift) & ~3; // apply to left/right as appropriate - if (NumOutputs == 1 || m_regs.ch_pan_left(m_choffs)) + if (NumOutputs == 1 || m_regs.ch_pan_left(m_choffs)) { output.data[0] += value; - if (NumOutputs > 1 && m_regs.ch_pan_right(m_choffs)) + m_lastOut[0] = value; + } + if (NumOutputs > 1 && m_regs.ch_pan_right(m_choffs)) { output.data[1] += value; + m_lastOut[1] = value; + } } -template void adpcm_a_channel::output<1>(ymfm_output<1> &output) const; -template void adpcm_a_channel::output<2>(ymfm_output<2> &output) const; +template void adpcm_a_channel::output<1>(ymfm_output<1> &output); +template void adpcm_a_channel::output<2>(ymfm_output<2> &output); //********************************************************* @@ -528,7 +532,7 @@ void adpcm_b_channel::clock() //------------------------------------------------- template -void adpcm_b_channel::output(ymfm_output &output, uint32_t rshift) const +void adpcm_b_channel::output(ymfm_output &output, uint32_t rshift) { // mask out some channels for debug purposes if ((debug::GLOBAL_ADPCM_B_CHANNEL_MASK & 1) == 0) @@ -541,10 +545,14 @@ void adpcm_b_channel::output(ymfm_output &output, uint32_t rshift) c result = (result * int32_t(m_regs.level())) >> (8 + rshift); // apply to left/right - if (NumOutputs == 1 || m_regs.pan_left()) + if (NumOutputs == 1 || m_regs.pan_left()) { + m_lastOut[0] = result; output.data[0] += result; - if (NumOutputs > 1 && m_regs.pan_right()) + } + if (NumOutputs > 1 && m_regs.pan_right()) { + m_lastOut[1] = result; output.data[1] += result; + } } diff --git a/src/engine/platform/sound/ymfm/ymfm_adpcm.h b/src/engine/platform/sound/ymfm/ymfm_adpcm.h index c08eeae5..58bee8a2 100644 --- a/src/engine/platform/sound/ymfm/ymfm_adpcm.h +++ b/src/engine/platform/sound/ymfm/ymfm_adpcm.h @@ -146,7 +146,10 @@ public: // return the computed output value, with panning applied template - void output(ymfm_output &output) const; + void output(ymfm_output &output); + + // return the last output + int32_t get_last_out(int ch) { return m_lastOut[ch]; } private: // internal state @@ -158,6 +161,7 @@ private: uint32_t m_curaddress; // current address int32_t m_accumulator; // accumulator int32_t m_step_index; // index in the stepping table + int32_t m_lastOut[2]; // last output adpcm_a_registers &m_regs; // reference to registers adpcm_a_engine &m_owner; // reference to our owner }; @@ -326,7 +330,7 @@ public: // return the computed output value, with panning applied template - void output(ymfm_output &output, uint32_t rshift) const; + void output(ymfm_output &output, uint32_t rshift); // return the status register uint8_t status() const { return m_status; } @@ -337,6 +341,9 @@ public: // handle special register writes void write(uint32_t regnum, uint8_t value); + // return the last output + int32_t get_last_out(int ch) { return m_lastOut[ch]; } + private: // helper - return the current address shift uint32_t address_shift() const; @@ -361,6 +368,7 @@ private: int32_t m_accumulator; // accumulator int32_t m_prev_accum; // previous accumulator (for linear interp) int32_t m_adpcm_step; // next forecast + int32_t m_lastOut[2]; // last output adpcm_b_registers &m_regs; // reference to registers adpcm_b_engine &m_owner; // reference to our owner }; @@ -387,6 +395,9 @@ public: template void output(ymfm_output &output, uint32_t rshift); + // get last output + int32_t get_last_out(int ch) { return m_channel->get_last_out(ch); } + // read from the ADPCM-B registers uint32_t read(uint32_t regnum) { return m_channel->read(regnum); } diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 3711515a..a4526608 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -428,7 +428,15 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l ymfm::adpcm_b_engine* abe=fm->debug_adpcm_b_engine(); ymfm::ssg_engine::output_data ssgOut; - ymfm::ymfm_output<2> adpcmOut; + + ymfm::fm_channel>* fmChan[6]; + ymfm::adpcm_a_channel* adpcmAChan[6]; + for (int i=0; i<4; i++) { + fmChan[i]=fme->debug_channel(bchOffs[i]); + } + for (int i=0; i<6; i++) { + adpcmAChan[i]=aae->debug_channel(i); + } for (size_t h=start; hdata[oscBuf[i]->needle++]=(fme->debug_channel(ch)->debug_output(0)+fme->debug_channel(ch)->debug_output(1)); + oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1)); } ssge->get_last_out(ssgOut); @@ -467,14 +474,10 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l } for (int i=7; i<13; i++) { - adpcmOut.clear(); - aae->debug_channel(i-7)->output<2>(adpcmOut); - oscBuf[i]->data[oscBuf[i]->needle++]=adpcmOut.data[0]+adpcmOut.data[1]; + oscBuf[i]->data[oscBuf[i]->needle++]=adpcmAChan[i-7]->get_last_out(0)+adpcmAChan[i-7]->get_last_out(1); } - adpcmOut.clear(); - abe->output(adpcmOut,1); - oscBuf[13]->data[oscBuf[13]->needle++]=adpcmOut.data[0]+adpcmOut.data[1]; + oscBuf[13]->data[oscBuf[13]->needle++]=abe->get_last_out(0)+abe->get_last_out(1); } } diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 9c126c2b..a66f0b57 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -408,7 +408,13 @@ void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t ymfm::adpcm_b_engine* abe=fm->debug_adpcm_b_engine(); ymfm::ssg_engine::output_data ssgOut; - ymfm::ymfm_output<2> adpcmOut; + + ymfm::fm_channel>* fmChan[6]; + ymfm::adpcm_a_channel* adpcmAChan[6]; + for (int i=0; i<6; i++) { + fmChan[i]=fme->debug_channel(i); + adpcmAChan[i]=aae->debug_channel(i); + } for (size_t h=start; hdata[oscBuf[i]->needle++]=(fme->debug_channel(i)->debug_output(0)+fme->debug_channel(i)->debug_output(1)); + oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1)); } ssge->get_last_out(ssgOut); @@ -446,14 +453,10 @@ void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t } for (int i=9; i<15; i++) { - adpcmOut.clear(); - aae->debug_channel(i-9)->output<2>(adpcmOut); - oscBuf[i]->data[oscBuf[i]->needle++]=adpcmOut.data[0]+adpcmOut.data[1]; + oscBuf[i]->data[oscBuf[i]->needle++]=adpcmAChan[i-9]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1); } - adpcmOut.clear(); - abe->output(adpcmOut,1); - oscBuf[15]->data[oscBuf[15]->needle++]=adpcmOut.data[0]+adpcmOut.data[1]; + oscBuf[15]->data[oscBuf[15]->needle++]=abe->get_last_out(0)+abe->get_last_out(1); } }