PCE: Mednafen is wonderful

the PSG emulator already comes with heuristics... I stripped them off
for Furnace but now that we have acquireDirect() we can give it our
blip_buf and handle everything there

from 40-70% to 10% CPU usage on my phone, and highest quality!

TODO:
- PCM
- chan osc (should be very easy)
This commit is contained in:
tildearrow 2025-03-03 20:27:35 -05:00
parent f5589d0084
commit f0a3e3f590
4 changed files with 37 additions and 57 deletions

View file

@ -34,7 +34,7 @@
rWrite(a,v); \
}
#define CHIP_DIVIDER 32
#define CHIP_DIVIDER 64
const char* regCheatSheetPCE[]={
"Select", "0",
@ -55,12 +55,20 @@ const char** DivPlatformPCE::getRegisterSheet() {
}
void DivPlatformPCE::acquire(short** buf, size_t len) {
}
void DivPlatformPCE::acquireDirect(blip_buffer_t** bb, size_t off, size_t len) {
for (int i=0; i<6; i++) {
oscBuf[i]->begin(len);
}
pce->bb[0]=bb[0];
pce->bb[1]=bb[1];
size_t pos=off;
for (size_t h=0; h<len; h++) {
// PCM part
/*
for (int i=0; i<6; i++) {
if (chan[i].pcm && chan[i].dacSample!=-1) {
chan[i].dacPeriod+=chan[i].dacRate;
@ -89,35 +97,25 @@ void DivPlatformPCE::acquire(short** buf, size_t len) {
chan[i].dacPeriod-=rate;
}
}
}
}*/
// PCE part
// WHAT?????????
pce->ResetTS(pos);
while (!writes.empty()) {
QueuedWrite w=writes.front();
pce->Write(0,w.addr,w.val);
pce->Write(pos,w.addr,w.val);
regPool[w.addr&0x0f]=w.val;
writes.pop();
}
tempL[0]=0;
tempR[0]=0;
pce->Update(coreQuality);
pce->ResetTS(0);
pce->Update(len+pos);
break;
/*
for (int i=0; i<6; i++) {
oscBuf[i]->putSample(h,CLAMP(pce->channel[i].blip_prev_samp[0]+pce->channel[i].blip_prev_samp[1],-32768,32767));
}
tempL[0]=(tempL[0]>>1)+(tempL[0]>>2);
tempR[0]=(tempR[0]>>1)+(tempR[0]>>2);
if (tempL[0]<-32768) tempL[0]=-32768;
if (tempL[0]>32767) tempL[0]=32767;
if (tempR[0]<-32768) tempR[0]=-32768;
if (tempR[0]>32767) tempR[0]=32767;
//printf("tempL: %d tempR: %d\n",tempL,tempR);
buf[0][h]=tempL[0];
buf[1][h]=tempR[0];
}*/
pos++;
}
for (int i=0; i<6; i++) {
@ -614,8 +612,6 @@ void DivPlatformPCE::reset() {
}
pce->Power(0);
lastPan=0xff;
memset(tempL,0,32*sizeof(int));
memset(tempR,0,32*sizeof(int));
curChan=-1;
sampleBank=0;
lfoMode=0;
@ -639,6 +635,10 @@ bool DivPlatformPCE::keyOffAffectsArp(int ch) {
return true;
}
bool DivPlatformPCE::hasAcquireDirect() {
return true;
}
void DivPlatformPCE::notifyWaveChange(int wave) {
for (int i=0; i<6; i++) {
if (chan[i].wave==wave) {
@ -656,13 +656,13 @@ void DivPlatformPCE::notifyInsDeletion(void* ins) {
void DivPlatformPCE::setFlags(const DivConfig& flags) {
if (flags.getInt("clockSel",0)) { // technically there is no PAL PC Engine but oh well...
chipClock=COLOR_PAL*4.0/5.0;
chipClock=COLOR_PAL*8.0/5.0;
} else {
chipClock=COLOR_NTSC;
chipClock=COLOR_NTSC*2.0;
}
CHECK_CUSTOM_CLOCK;
antiClickEnabled=!flags.getBool("noAntiClick",false);
rate=chipClock/(coreQuality>>1);
rate=chipClock;
for (int i=0; i<6; i++) {
oscBuf[i]->setRate(rate);
}
@ -671,7 +671,7 @@ void DivPlatformPCE::setFlags(const DivConfig& flags) {
delete pce;
pce=NULL;
}
pce=new PCE_PSG(tempL,tempR,flags.getInt("chipType",0)?PCE_PSG::REVISION_HUC6280A:PCE_PSG::REVISION_HUC6280);
pce=new PCE_PSG(flags.getInt("chipType",0)?PCE_PSG::REVISION_HUC6280A:PCE_PSG::REVISION_HUC6280);
}
void DivPlatformPCE::poke(unsigned int addr, unsigned short val) {

View file

@ -70,8 +70,6 @@ class DivPlatformPCE: public DivDispatch {
unsigned char lastPan;
int curChan;
int tempL[32];
int tempR[32];
unsigned char sampleBank, lfoMode, lfoSpeed;
int coreQuality;
PCE_PSG* pce;
@ -81,6 +79,7 @@ class DivPlatformPCE: public DivDispatch {
friend void putDispatchChan(void*,int,int);
public:
void acquire(short** buf, size_t len);
void acquireDirect(blip_buffer_t** bb, size_t off, size_t len);
int dispatch(DivCommand c);
void* getChanState(int chan);
DivMacroInt* getChanMacroInt(int ch);
@ -99,6 +98,7 @@ class DivPlatformPCE: public DivDispatch {
void muteChannel(int ch, bool mute);
int getOutputCount();
bool keyOffAffectsArp(int ch);
bool hasAcquireDirect();
void setCoreQuality(unsigned char q);
void setFlags(const DivConfig& flags);
void notifyWaveChange(int wave);

View file

@ -70,34 +70,13 @@ static const int scale_tab[] =
inline void PCE_PSG::UpdateOutputSub(const int32_t timestamp, psg_channel *ch, const int32_t samp0, const int32_t samp1)
{
if (timestamp>0) return;
HRBufs[0][timestamp]+=samp0;
HRBufs[1][timestamp]+=samp1;
/*
int32_t delta[2];
delta[0] = samp0 - ch->blip_prev_samp[0];
delta[1] = samp1 - ch->blip_prev_samp[1];
const int16_t* c = Phase_Filter[(timestamp >> 1) & 1];
const int32_t l = (timestamp >> 2) & 0xFFFF;
HRBufs[0][l + 0] += delta[0] * c[0];
HRBufs[0][l + 1] += delta[0] * c[1];
HRBufs[0][l + 2] += delta[0] * c[2];
HRBufs[0][l + 3] += delta[0] * c[3];
HRBufs[0][l + 4] += delta[0] * c[4];
HRBufs[0][l + 5] += delta[0] * c[5];
HRBufs[0][l + 6] += delta[0] * c[6];
HRBufs[1][l + 0] += delta[1] * c[0];
HRBufs[1][l + 1] += delta[1] * c[1];
HRBufs[1][l + 2] += delta[1] * c[2];
HRBufs[1][l + 3] += delta[1] * c[3];
HRBufs[1][l + 4] += delta[1] * c[4];
HRBufs[1][l + 5] += delta[1] * c[5];
HRBufs[1][l + 6] += delta[1] * c[6];
*/
blip_add_delta(bb[0],timestamp,delta[0]);
blip_add_delta(bb[1],timestamp,delta[1]);
ch->blip_prev_samp[0] = samp0;
ch->blip_prev_samp[1] = samp1;
@ -405,7 +384,7 @@ void PSG_SetRegister(const unsigned int id, const uint32_t value)
}
#endif
PCE_PSG::PCE_PSG(int32_t* hr_l, int32_t* hr_r, int want_revision)
PCE_PSG::PCE_PSG(int want_revision)
{
//printf("Test: %u, %u\n", sizeof(psg_channel), (uint8_t*)&channel[0].balance - (uint8_t*)&channel[0].waveform[0]);
@ -424,8 +403,8 @@ PCE_PSG::PCE_PSG(int32_t* hr_l, int32_t* hr_r, int want_revision)
UpdateOutput_Accum = &PCE_PSG::UpdateOutput_Accum_HuC6280A;
break;
}
HRBufs[0] = hr_l;
HRBufs[1] = hr_r;
bb[0]=NULL;
bb[1]=NULL;
lastts = 0;
for(int ch = 0; ch < 6; ch++)

View file

@ -24,6 +24,7 @@
#define __MDFN_HW_SOUND_PCE_PSG_PCE_PSG_H
#include <stdint.h>
#include "../../blip_buf.h"
class PCE_PSG;
@ -130,7 +131,7 @@ class PCE_PSG
};
PCE_PSG(int32_t* hr_l, int32_t* hr_r, int want_revision);
PCE_PSG(int want_revision);
~PCE_PSG();
void Power(const int32_t timestamp);
@ -150,6 +151,8 @@ class PCE_PSG
psg_channel channel[6];
blip_buffer_t* bb[2];
private:
void UpdateSubLFO(int32_t timestamp);
@ -183,8 +186,6 @@ class PCE_PSG
int32_t lastts;
int revision;
int32_t* HRBufs[2];
int32_t dbtable_volonly[32];
int32_t dbtable[32][32];