ES5506: optimize, part 1

man this core is so CPU heavy...
accuracy for what?
This commit is contained in:
tildearrow 2023-02-06 03:00:25 -05:00
parent 4c39de927b
commit 3a4057ece3
5 changed files with 75 additions and 68 deletions

View file

@ -9,6 +9,8 @@
#include "es5506.hpp"
// Internal functions
// DO NOT USE THIS ONE!
void es5506_core::tick()
{
// CLKIN
@ -216,18 +218,8 @@ void es5506_core::tick_perf()
m_intf.e_pin(false);
m_host_intf.clear_host_access();
m_host_intf.clear_strobe();
m_voice[m_voice_cycle].fetch(m_voice_cycle, m_voice_fetch);
voice_tick();
// rising edge
m_e.edge().set(true);
m_intf.e_pin(true);
m_host_intf.update_strobe();
// falling edge
m_e.edge().set(false);
m_intf.e_pin(false);
m_host_intf.clear_host_access();
m_host_intf.clear_strobe();
m_voice[m_voice_cycle].fetch(m_voice_cycle, m_voice_fetch);
m_voice[m_voice_cycle].fetch(m_voice_cycle, 0);
m_voice[m_voice_cycle].fetch(m_voice_cycle, 1);
voice_tick();
// rising edge
m_e.edge().set(true);
@ -238,38 +230,33 @@ void es5506_core::tick_perf()
void es5506_core::voice_tick()
{
// Voice updates every 2 E clock cycle (or 4 BCLK clock cycle)
m_voice_update = bitfield(m_voice_fetch++, 0);
if (m_voice_update)
{
// Update voice
m_voice[m_voice_cycle].tick(m_voice_cycle);
// Update voice
m_voice[m_voice_cycle].tick(m_voice_cycle);
// Refresh output
if ((++m_voice_cycle) > clamp<u8>(m_active, 4, 31)) // 5 ~ 32 voices
{
m_voice_end = true;
m_voice_cycle = 0;
for (output_t &elem : m_ch)
{
elem.reset();
}
// Refresh output
if ((++m_voice_cycle) > clamp<u8>(m_active, 4, 31)) // 5 ~ 32 voices
{
m_voice_end = true;
m_voice_cycle = 0;
for (output_t &elem : m_ch)
{
elem.reset();
}
for (voice_t &elem : m_voice)
{
const u8 ca = bitfield<u8>(elem.cr().ca(), 0, 3);
if (ca < 6)
{
m_ch[ca] += elem.ch();
}
elem.ch().reset();
}
}
else
{
m_voice_end = false;
}
m_voice_fetch = 0;
}
for (voice_t &elem : m_voice)
{
const u8 ca = bitfield<u8>(elem.cr().ca(), 0, 3);
if (ca < 6)
{
m_ch[ca] += elem.ch();
}
elem.ch().reset();
}
}
else
{
m_voice_end = false;
}
}
void es5506_core::voice_t::fetch(u8 voice, u8 cycle)

View file

@ -145,10 +145,9 @@ class es5506_core : public es550x_shared_core
, m_k2ramp(filter_ramp_t())
, m_k1ramp(filter_ramp_t())
, m_filtcount(0)
, m_ch(output_t())
, m_mute(false)
, m_output{0,0}
{
m_output.fill(0);
}
// internal state
@ -211,7 +210,7 @@ class es5506_core : public es550x_shared_core
u8 m_filtcount = 0; // Internal counter for slow mode
output_t m_ch; // channel output
bool m_mute = false; // mute flag (for debug purpose)
std::array<s32, 2> m_output; // output preview (for debug purpose)
s32 m_output[2]; // output preview (for debug purpose)
};
// 5 bit mode
@ -352,7 +351,7 @@ class es5506_core : public es550x_shared_core
virtual void voice_tick() override;
private:
std::array<voice_t, 32> m_voice; // 32 voices
voice_t m_voice[32]; // 32 voices
// Host interfaces
u32 m_read_latch = 0; // 32 bit register latch for host read
@ -372,10 +371,10 @@ class es5506_core : public es550x_shared_core
s16 m_wclk = 0; // WCLK
bool m_wclk_lr = false; // WCLK, L/R output select
s8 m_output_bit = 0; // Bit position in output
std::array<output_t, 6> m_ch; // 6 stereo output channels
std::array<output_t, 6> m_output; // Serial outputs
std::array<output_t, 6> m_output_temp; // temporary signal for serial output
std::array<output_t, 6> m_output_latch; // output latch
output_t m_ch[6]; // 6 stereo output channels
output_t m_output[6]; // Serial outputs
output_t m_output_temp[6]; // temporary signal for serial output
output_t m_output_latch[6]; // output latch
};
#endif

View file

@ -14,6 +14,8 @@
#include "../core/core.hpp"
#include "../core/util/clock_pulse.hpp"
#include <string.h>
using namespace vgsound_emu;
// ES5504/ES5505/ES5506 interface
@ -166,8 +168,8 @@ class es550x_shared_core : public vgsound_emu_core
, m_start(0)
, m_end(0)
, m_accum(0)
, m_sample{0,0}
{
m_sample.fill(0);
}
// configurations
@ -367,7 +369,7 @@ class es550x_shared_core : public vgsound_emu_core
// 21 integer, 11 fraction for ES5506
u32 m_accum = 0;
// Samples
std::array<s32, 2> m_sample;
s32 m_sample[2];
};
// Filter
@ -380,10 +382,7 @@ class es550x_shared_core : public vgsound_emu_core
, m_k2(0)
, m_k1(0)
{
for (std::array<s32, 2> &elem : m_o)
{
std::fill(elem.begin(), elem.end(), 0);
}
memset(m_o,0,2*5*sizeof(s32));
}
void reset();
@ -441,7 +440,7 @@ class es550x_shared_core : public vgsound_emu_core
s32 m_k1 = 0; // Filter coefficient 1
// Filter storage registers
std::array<std::array<s32, 2>, 5> m_o;
s32 m_o[5][2];
};
public:

View file

@ -14,10 +14,7 @@ void es550x_shared_core::es550x_voice_t::es550x_filter_t::reset()
m_lp = 0;
m_k2 = 0;
m_k1 = 0;
for (std::array<s32, 2> &elem : m_o)
{
std::fill(elem.begin(), elem.end(), 0);
}
memset(m_o,0,2*5*sizeof(s32));
}
void es550x_shared_core::es550x_voice_t::es550x_filter_t::tick(s32 in)

View file

@ -113,7 +113,21 @@ const char** DivPlatformES5506::getRegisterSheet() {
}
void DivPlatformES5506::acquire(short** buf, size_t len) {
int coL[6], coR[6];
for (size_t h=0; h<len; h++) {
coL[0]=0;
coL[1]=0;
coL[2]=0;
coL[3]=0;
coL[4]=0;
coL[5]=0;
coR[0]=0;
coR[1]=0;
coR[2]=0;
coR[3]=0;
coR[4]=0;
coR[5]=0;
for (int i=31; i>(int)chanMax; i--) {
oscBuf[i]->data[oscBuf[i]->needle++]=0;
}
@ -133,11 +147,21 @@ void DivPlatformES5506::acquire(short** buf, size_t len) {
}
hostIntf32.pop();
}
prevChanCycle=es5506.voice_cycle();
es5506.tick_perf();
for (int i=0; i<32; i++) {
prevChanCycle=es5506.voice_cycle();
es5506.tick_perf();
for (int o=0; o<6; o++) {
coL[o]+=es5506.lout(o);
coR[o]+=es5506.rout(o);
}
}
for (int o=0; o<6; o++) {
buf[(o<<1)|0][h]=es5506.lout(o);
buf[(o<<1)|1][h]=es5506.rout(o);
coL[o]>>=3;
coR[o]>>=3;
}
for (int o=0; o<6; o++) {
buf[(o<<1)|0][h]=coL[o];
buf[(o<<1)|1][h]=coR[o];
}
for (int i=chanMax; i>=0; i--) {
oscBuf[i]->data[oscBuf[i]->needle++]=(short)(chan[i].oscOut&0xffff);
@ -146,14 +170,15 @@ void DivPlatformES5506::acquire(short** buf, size_t len) {
}
void DivPlatformES5506::e_pin(bool state) {
/*
if (es5506.e_falling_edge()) { // get channel outputs
if (es5506.voice_update()) {
const signed int lOut=es5506.voice_lout(prevChanCycle);
const signed int rOut=es5506.voice_rout(prevChanCycle);
chan[prevChanCycle].oscOut=CLAMP((lOut+rOut)>>5,-32768,32767);
}
}
if (es5506.e_rising_edge()) { // host interface
}*/
if (state) { // host interface
if (cycle) { // wait until delay
cycle--;
} else if (!hostIntf8.empty()) {
@ -1196,7 +1221,7 @@ void DivPlatformES5506::notifyInsDeletion(void* ins) {
void DivPlatformES5506::setFlags(const DivConfig& flags) {
chipClock=16000000;
CHECK_CUSTOM_CLOCK;
rate=chipClock/16; // 2 E clock tick (16 CLKIN tick) per voice
rate=chipClock/512; // 2 E clock tick (16 CLKIN tick) per voice / 4
for (int i=0; i<32; i++) {
oscBuf[i]->rate=rate;
}