mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-16 17:45:10 +00:00
YM2610: optimize oscilloscope fetch CPU usage
This commit is contained in:
parent
b8a2c90b61
commit
4c9b172b50
4 changed files with 52 additions and 27 deletions
|
@ -220,7 +220,7 @@ bool adpcm_a_channel::clock()
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
template<int NumOutputs>
|
template<int NumOutputs>
|
||||||
void adpcm_a_channel::output(ymfm_output<NumOutputs> &output) const
|
void adpcm_a_channel::output(ymfm_output<NumOutputs> &output)
|
||||||
{
|
{
|
||||||
// volume combines instrument and total levels
|
// volume combines instrument and total levels
|
||||||
int vol = (m_regs.ch_instrument_level(m_choffs) ^ 0x1f) + (m_regs.total_level() ^ 0x3f);
|
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<NumOutputs> &output) const
|
||||||
int16_t value = ((int16_t(m_accumulator << 4) * mul) >> shift) & ~3;
|
int16_t value = ((int16_t(m_accumulator << 4) * mul) >> shift) & ~3;
|
||||||
|
|
||||||
// apply to left/right as appropriate
|
// 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;
|
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;
|
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<1>(ymfm_output<1> &output);
|
||||||
template void adpcm_a_channel::output<2>(ymfm_output<2> &output) const;
|
template void adpcm_a_channel::output<2>(ymfm_output<2> &output);
|
||||||
|
|
||||||
|
|
||||||
//*********************************************************
|
//*********************************************************
|
||||||
|
@ -528,7 +532,7 @@ void adpcm_b_channel::clock()
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
template<int NumOutputs>
|
template<int NumOutputs>
|
||||||
void adpcm_b_channel::output(ymfm_output<NumOutputs> &output, uint32_t rshift) const
|
void adpcm_b_channel::output(ymfm_output<NumOutputs> &output, uint32_t rshift)
|
||||||
{
|
{
|
||||||
// mask out some channels for debug purposes
|
// mask out some channels for debug purposes
|
||||||
if ((debug::GLOBAL_ADPCM_B_CHANNEL_MASK & 1) == 0)
|
if ((debug::GLOBAL_ADPCM_B_CHANNEL_MASK & 1) == 0)
|
||||||
|
@ -541,10 +545,14 @@ void adpcm_b_channel::output(ymfm_output<NumOutputs> &output, uint32_t rshift) c
|
||||||
result = (result * int32_t(m_regs.level())) >> (8 + rshift);
|
result = (result * int32_t(m_regs.level())) >> (8 + rshift);
|
||||||
|
|
||||||
// apply to left/right
|
// 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;
|
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;
|
output.data[1] += result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -146,7 +146,10 @@ public:
|
||||||
|
|
||||||
// return the computed output value, with panning applied
|
// return the computed output value, with panning applied
|
||||||
template<int NumOutputs>
|
template<int NumOutputs>
|
||||||
void output(ymfm_output<NumOutputs> &output) const;
|
void output(ymfm_output<NumOutputs> &output);
|
||||||
|
|
||||||
|
// return the last output
|
||||||
|
int32_t get_last_out(int ch) { return m_lastOut[ch]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// internal state
|
// internal state
|
||||||
|
@ -158,6 +161,7 @@ private:
|
||||||
uint32_t m_curaddress; // current address
|
uint32_t m_curaddress; // current address
|
||||||
int32_t m_accumulator; // accumulator
|
int32_t m_accumulator; // accumulator
|
||||||
int32_t m_step_index; // index in the stepping table
|
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_registers &m_regs; // reference to registers
|
||||||
adpcm_a_engine &m_owner; // reference to our owner
|
adpcm_a_engine &m_owner; // reference to our owner
|
||||||
};
|
};
|
||||||
|
@ -326,7 +330,7 @@ public:
|
||||||
|
|
||||||
// return the computed output value, with panning applied
|
// return the computed output value, with panning applied
|
||||||
template<int NumOutputs>
|
template<int NumOutputs>
|
||||||
void output(ymfm_output<NumOutputs> &output, uint32_t rshift) const;
|
void output(ymfm_output<NumOutputs> &output, uint32_t rshift);
|
||||||
|
|
||||||
// return the status register
|
// return the status register
|
||||||
uint8_t status() const { return m_status; }
|
uint8_t status() const { return m_status; }
|
||||||
|
@ -337,6 +341,9 @@ public:
|
||||||
// handle special register writes
|
// handle special register writes
|
||||||
void write(uint32_t regnum, uint8_t value);
|
void write(uint32_t regnum, uint8_t value);
|
||||||
|
|
||||||
|
// return the last output
|
||||||
|
int32_t get_last_out(int ch) { return m_lastOut[ch]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// helper - return the current address shift
|
// helper - return the current address shift
|
||||||
uint32_t address_shift() const;
|
uint32_t address_shift() const;
|
||||||
|
@ -361,6 +368,7 @@ private:
|
||||||
int32_t m_accumulator; // accumulator
|
int32_t m_accumulator; // accumulator
|
||||||
int32_t m_prev_accum; // previous accumulator (for linear interp)
|
int32_t m_prev_accum; // previous accumulator (for linear interp)
|
||||||
int32_t m_adpcm_step; // next forecast
|
int32_t m_adpcm_step; // next forecast
|
||||||
|
int32_t m_lastOut[2]; // last output
|
||||||
adpcm_b_registers &m_regs; // reference to registers
|
adpcm_b_registers &m_regs; // reference to registers
|
||||||
adpcm_b_engine &m_owner; // reference to our owner
|
adpcm_b_engine &m_owner; // reference to our owner
|
||||||
};
|
};
|
||||||
|
@ -387,6 +395,9 @@ public:
|
||||||
template<int NumOutputs>
|
template<int NumOutputs>
|
||||||
void output(ymfm_output<NumOutputs> &output, uint32_t rshift);
|
void output(ymfm_output<NumOutputs> &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
|
// read from the ADPCM-B registers
|
||||||
uint32_t read(uint32_t regnum) { return m_channel->read(regnum); }
|
uint32_t read(uint32_t regnum) { return m_channel->read(regnum); }
|
||||||
|
|
||||||
|
|
|
@ -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::adpcm_b_engine* abe=fm->debug_adpcm_b_engine();
|
||||||
|
|
||||||
ymfm::ssg_engine::output_data ssgOut;
|
ymfm::ssg_engine::output_data ssgOut;
|
||||||
ymfm::ymfm_output<2> adpcmOut;
|
|
||||||
|
ymfm::fm_channel<ymfm::opn_registers_base<true>>* 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; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
os[0]=0; os[1]=0;
|
os[0]=0; os[1]=0;
|
||||||
|
@ -457,8 +465,7 @@ void DivPlatformYM2610::acquire(short* bufL, short* bufR, size_t start, size_t l
|
||||||
bufR[h]=os[1];
|
bufR[h]=os[1];
|
||||||
|
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
int ch=bchOffs[i];
|
oscBuf[i]->data[oscBuf[i]->needle++]=(fmChan[i]->debug_output(0)+fmChan[i]->debug_output(1));
|
||||||
oscBuf[i]->data[oscBuf[i]->needle++]=(fme->debug_channel(ch)->debug_output(0)+fme->debug_channel(ch)->debug_output(1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ssge->get_last_out(ssgOut);
|
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++) {
|
for (int i=7; i<13; i++) {
|
||||||
adpcmOut.clear();
|
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmAChan[i-7]->get_last_out(0)+adpcmAChan[i-7]->get_last_out(1);
|
||||||
aae->debug_channel(i-7)->output<2>(adpcmOut);
|
|
||||||
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
adpcmOut.clear();
|
oscBuf[13]->data[oscBuf[13]->needle++]=abe->get_last_out(0)+abe->get_last_out(1);
|
||||||
abe->output(adpcmOut,1);
|
|
||||||
oscBuf[13]->data[oscBuf[13]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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::adpcm_b_engine* abe=fm->debug_adpcm_b_engine();
|
||||||
|
|
||||||
ymfm::ssg_engine::output_data ssgOut;
|
ymfm::ssg_engine::output_data ssgOut;
|
||||||
ymfm::ymfm_output<2> adpcmOut;
|
|
||||||
|
ymfm::fm_channel<ymfm::opn_registers_base<true>>* 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; h<start+len; h++) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
os[0]=0; os[1]=0;
|
os[0]=0; os[1]=0;
|
||||||
|
@ -436,8 +442,9 @@ void DivPlatformYM2610B::acquire(short* bufL, short* bufR, size_t start, size_t
|
||||||
bufL[h]=os[0];
|
bufL[h]=os[0];
|
||||||
bufR[h]=os[1];
|
bufR[h]=os[1];
|
||||||
|
|
||||||
|
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
oscBuf[i]->data[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);
|
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++) {
|
for (int i=9; i<15; i++) {
|
||||||
adpcmOut.clear();
|
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmAChan[i-9]->get_last_out(0)+adpcmAChan[i-9]->get_last_out(1);
|
||||||
aae->debug_channel(i-9)->output<2>(adpcmOut);
|
|
||||||
oscBuf[i]->data[oscBuf[i]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
adpcmOut.clear();
|
oscBuf[15]->data[oscBuf[15]->needle++]=abe->get_last_out(0)+abe->get_last_out(1);
|
||||||
abe->output(adpcmOut,1);
|
|
||||||
oscBuf[15]->data[oscBuf[15]->needle++]=adpcmOut.data[0]+adpcmOut.data[1];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue