prepare for possible major optimization

by just forwarding an output buffer to the dispatch and begin/length,
the number of calls may be reduced which improves performance.
This commit is contained in:
tildearrow 2021-12-06 05:21:42 -05:00
parent 055b4f9c26
commit 6efcfc2e8a
19 changed files with 178 additions and 132 deletions

View file

@ -1,6 +1,8 @@
#ifndef _DISPATCH_H #ifndef _DISPATCH_H
#define _DISPATCH_H #define _DISPATCH_H
#include <stdint.h>
#define ONE_SEMITONE 2200 #define ONE_SEMITONE 2200
enum DivDispatchCmds { enum DivDispatchCmds {
@ -83,7 +85,7 @@ class DivDispatch {
* the engine shall resample to the output rate. * the engine shall resample to the output rate.
*/ */
int rate; int rate;
virtual void acquire(int& l, int& r); virtual void acquire(short** buf, size_t start, size_t len);
virtual int dispatch(DivCommand c); virtual int dispatch(DivCommand c);
virtual void tick(); virtual void tick();

View file

@ -738,6 +738,10 @@ bool DivEngine::init() {
bbOut[0]=new short[got.bufsize]; bbOut[0]=new short[got.bufsize];
bbOut[1]=new short[got.bufsize]; bbOut[1]=new short[got.bufsize];
bbIn[0]=new short[32768];
bbIn[1]=new short[32768];
bbInLen=32768;
for (int i=0; i<64; i++) { for (int i=0; i<64; i++) {
vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI)); vibTable[i]=127*sin(((double)i/64.0)*(2*M_PI));
} }

View file

@ -67,7 +67,9 @@ class DivEngine {
short vibTable[64]; short vibTable[64];
blip_buffer_t* bb[2]; blip_buffer_t* bb[2];
size_t bbInLen;
int temp[2], prevSample[2]; int temp[2], prevSample[2];
short* bbIn[2];
short* bbOut[2]; short* bbOut[2];
int dispatchCmd(DivCommand c); int dispatchCmd(DivCommand c);
@ -117,6 +119,7 @@ class DivEngine {
cmdsPerSecond(0), cmdsPerSecond(0),
view(DIV_STATUS_PATTERN), view(DIV_STATUS_PATTERN),
audioEngine(DIV_AUDIO_SDL), audioEngine(DIV_AUDIO_SDL),
bbInLen(0),
temp{0,0}, temp{0,0},
prevSample{0,0} {} prevSample{0,0} {}
}; };

View file

@ -1,8 +1,6 @@
#include "../dispatch.h" #include "../dispatch.h"
void DivDispatch::acquire(int& l, int& r) { void DivDispatch::acquire(short** buf, size_t start, size_t len) {
l=0;
r=0;
} }
void DivDispatch::tick() { void DivDispatch::tick() {

View file

@ -4,10 +4,12 @@
#define FREQ_BASE 277.0f #define FREQ_BASE 277.0f
void DivPlatformC64::acquire(int& l, int& r) { void DivPlatformC64::acquire(short** buf, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) {
sid.clock(); sid.clock();
l=sid.output(); buf[0][i]=sid.output();
r=l; buf[1][i]=buf[0][i];
}
} }
void DivPlatformC64::tick() { void DivPlatformC64::tick() {

View file

@ -39,7 +39,7 @@ class DivPlatformC64: public DivDispatch {
void updateWave(); void updateWave();
public: public:
void acquire(int& l, int& r); void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -2,16 +2,17 @@
#include <stdio.h> #include <stdio.h>
#include <math.h> #include <math.h>
void DivPlatformDummy::acquire(int& l, int& r) { void DivPlatformDummy::acquire(short** buf, size_t start, size_t len) {
l=0; for (size_t i=start; i<start+len; i++) {
for (unsigned char i=0; i<chans; i++) { buf[0][i]=0;
if (chan[i].active) { for (unsigned char j=0; j<chans; j++) {
l+=((chan[i].pos>=0x8000)?chan[i].vol:-chan[i].vol)*chan[i].amp; if (chan[j].active) {
buf[0][i]+=((chan[j].pos>=0x8000)?chan[j].vol:-chan[j].vol)*chan[j].amp;
chan[i].pos+=chan[i].freq; chan[j].pos+=chan[j].freq;
} }
} }
r=l; buf[1][i]=buf[0][i];
}
} }
void DivPlatformDummy::tick() { void DivPlatformDummy::tick() {

View file

@ -15,7 +15,7 @@ class DivPlatformDummy: public DivDispatch {
Channel chan[17]; Channel chan[17];
unsigned char chans; unsigned char chans;
public: public:
void acquire(int& l, int& r); void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -7,10 +7,12 @@
#define FREQ_BASE 8015.85f #define FREQ_BASE 8015.85f
void DivPlatformGB::acquire(int& l, int& r) { void DivPlatformGB::acquire(short** buf, size_t start, size_t len) {
for (int i=start; i<start+len; i++) {
GB_advance_cycles(gb,16); GB_advance_cycles(gb,16);
l=gb->apu_output.final_sample.left<<2; buf[0][i]=gb->apu_output.final_sample.left<<2;
r=gb->apu_output.final_sample.right<<2; buf[1][i]=gb->apu_output.final_sample.right<<2;
}
} }
void DivPlatformGB::updateWave() { void DivPlatformGB::updateWave() {

View file

@ -36,7 +36,7 @@ class DivPlatformGB: public DivDispatch {
GB_gameboy_t* gb; GB_gameboy_t* gb;
void updateWave(); void updateWave();
public: public:
void acquire(int& l, int& r); void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -12,10 +12,11 @@ static unsigned char konOffs[6]={
0, 1, 2, 4, 5, 6 0, 1, 2, 4, 5, 6
}; };
void DivPlatformGenesis::acquire(int& l, int& r) { void DivPlatformGenesis::acquire(short** buf, size_t start, size_t len) {
static short o[2]; static short o[2];
static int os[2]; static int os[2];
for (size_t h=start; h<start+len; h++) {
if (dacMode && dacSample!=-1) { if (dacMode && dacSample!=-1) {
dacPeriod-=6; dacPeriod-=6;
if (dacPeriod<1) { if (dacPeriod<1) {
@ -58,13 +59,13 @@ void DivPlatformGenesis::acquire(int& l, int& r) {
psgClocks+=223722; psgClocks+=223722;
while (psgClocks>=rate) { while (psgClocks>=rate) {
psg.acquire(psgOut,psgOut); psgOut=(psg.acquireOne()*3)>>3;
psgClocks-=rate; psgClocks-=rate;
psgOut=(psgOut>>2)+(psgOut>>3);
} }
l=(os[0]<<5)+psgOut; buf[0][h]=(os[0]<<5)+psgOut;
r=(os[1]<<5)+psgOut; buf[1][h]=(os[1]<<5)+psgOut;
}
} }
void DivPlatformGenesis::tick() { void DivPlatformGenesis::tick() {

View file

@ -48,7 +48,7 @@ class DivPlatformGenesis: public DivDispatch {
int toFreq(int freq); int toFreq(int freq);
public: public:
void acquire(int& l, int& r); void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -5,7 +5,8 @@
#define FREQ_BASE 3424.0f #define FREQ_BASE 3424.0f
void DivPlatformNES::acquire(int& l, int& r) { void DivPlatformNES::acquire(short** buf, size_t start, size_t len) {
for (size_t i=start; i<start+len; i++) {
if (dacSample!=-1) { if (dacSample!=-1) {
dacPeriod+=dacRate; dacPeriod+=dacRate;
if (dacPeriod>=rate) { if (dacPeriod>=rate) {
@ -26,10 +27,11 @@ void DivPlatformNES::acquire(int& l, int& r) {
apu.odd_cycle=!apu.odd_cycle; apu.odd_cycle=!apu.odd_cycle;
if (apu.clocked) { if (apu.clocked) {
apu.clocked=false; apu.clocked=false;
l=(pulse_output()+tnd_output())*30; buf[0][i]=(pulse_output()+tnd_output())*30;
r=l; buf[1][i]=buf[0][i];
//printf("output value: %d\n",l); //printf("output value: %d\n",l);
} }
}
} }
static int dacRates[6]={ static int dacRates[6]={

View file

@ -36,7 +36,7 @@ class DivPlatformNES: public DivDispatch {
void updateWave(); void updateWave();
public: public:
void acquire(int& l, int& r); void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -13,7 +13,8 @@
#define FREQ_BASE 1712.0f*2 #define FREQ_BASE 1712.0f*2
void DivPlatformPCE::acquire(int& l, int& r) { void DivPlatformPCE::acquire(short** buf, size_t start, size_t len) {
for (size_t h=start; h<start+len; h++) {
// PCM part // PCM part
for (int i=0; i<6; i++) { for (int i=0; i<6; i++) {
if (chan[i].pcm && chan[i].dacSample!=-1) { if (chan[i].pcm && chan[i].dacSample!=-1) {
@ -46,8 +47,9 @@ void DivPlatformPCE::acquire(int& l, int& r) {
pce->ResetTS(0); pce->ResetTS(0);
//printf("tempL: %d tempR: %d\n",tempL,tempR); //printf("tempL: %d tempR: %d\n",tempL,tempR);
l=tempL; buf[0][h]=tempL;
r=tempR; buf[1][h]=tempR;
}
} }
void DivPlatformPCE::updateWave(int ch) { void DivPlatformPCE::updateWave(int ch) {

View file

@ -50,7 +50,7 @@ class DivPlatformPCE: public DivDispatch {
PCE_PSG* pce; PCE_PSG* pce;
void updateWave(int ch); void updateWave(int ch);
public: public:
void acquire(int& l, int& r); void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -2,11 +2,15 @@
#include "../engine.h" #include "../engine.h"
#include <math.h> #include <math.h>
void DivPlatformSMS::acquire(int& l, int& r) { void DivPlatformSMS::acquire(short** buf, size_t start, size_t len) {
sn->sound_stream_update(buf[0]+start,len);
memcpy(buf[1]+start,buf[0]+start,sizeof(short)*len);
}
int DivPlatformSMS::acquireOne() {
short v; short v;
sn->sound_stream_update(&v,1); sn->sound_stream_update(&v,1);
l=v; return v;
r=v;
} }
void DivPlatformSMS::tick() { void DivPlatformSMS::tick() {

View file

@ -30,7 +30,8 @@ class DivPlatformSMS: public DivDispatch {
bool updateSNMode; bool updateSNMode;
sn76496_device* sn; sn76496_device* sn;
public: public:
void acquire(int& l, int& r); int acquireOne();
void acquire(short** buf, size_t start, size_t len);
int dispatch(DivCommand c); int dispatch(DivCommand c);
void tick(); void tick();
int init(DivEngine* parent, int channels, int sugRate); int init(DivEngine* parent, int channels, int sugRate);

View file

@ -604,15 +604,39 @@ void DivEngine::nextTick() {
void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) { void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size) {
size_t runtotal=blip_clocks_needed(bb[0],size); size_t runtotal=blip_clocks_needed(bb[0],size);
for (size_t i=0; i<runtotal; i++) {
if (--cycles<=0) {
nextTick();
}
dispatch->acquire(temp[0],temp[1]);
if (runtotal>bbInLen) {
delete bbIn[0];
delete bbIn[1];
bbIn[0]=new short[runtotal+256];
bbIn[1]=new short[runtotal+256];
bbInLen=runtotal+256;
}
size_t runLeft=runtotal;
size_t runPos=0;
while (runLeft) {
if (runLeft>=cycles) {
runLeft-=cycles;
dispatch->acquire(bbIn,runPos,cycles);
runPos+=cycles;
nextTick();
} else {
dispatch->acquire(bbIn,runPos,runLeft);
cycles-=runLeft;
break;
}
}
for (size_t i=0; i<runtotal; i++) {
temp[0]=bbIn[0][i];
blip_add_delta(bb[0],i,temp[0]-prevSample[0]); blip_add_delta(bb[0],i,temp[0]-prevSample[0]);
blip_add_delta(bb[1],i,temp[1]-prevSample[1]);
prevSample[0]=temp[0]; prevSample[0]=temp[0];
}
for (size_t i=0; i<runtotal; i++) {
temp[1]=bbIn[1][i];
blip_add_delta(bb[1],i,temp[1]-prevSample[1]);
prevSample[1]=temp[1]; prevSample[1]=temp[1];
} }