Merge branch 'master' into amigaOpt
This commit is contained in:
commit
655b3621f6
|
@ -459,7 +459,7 @@ struct DivDispatchOscBuffer {
|
||||||
//lastSample=val;
|
//lastSample=val;
|
||||||
data[pos]=val;
|
data[pos]=val;
|
||||||
}*/
|
}*/
|
||||||
inline void begin(unsigned short len) {
|
inline void begin(size_t len) {
|
||||||
size_t calc=(len*rateMul);
|
size_t calc=(len*rateMul);
|
||||||
unsigned short start=needle>>16;
|
unsigned short start=needle>>16;
|
||||||
unsigned short end=(needle+calc)>>16;
|
unsigned short end=(needle+calc)>>16;
|
||||||
|
@ -476,7 +476,7 @@ struct DivDispatchOscBuffer {
|
||||||
memset(&data[start],-1,(end-start)*sizeof(short));
|
memset(&data[start],-1,(end-start)*sizeof(short));
|
||||||
//data[needle>>16]=lastSample;
|
//data[needle>>16]=lastSample;
|
||||||
}
|
}
|
||||||
inline void end(unsigned short len) {
|
inline void end(size_t len) {
|
||||||
size_t calc=len*rateMul;
|
size_t calc=len*rateMul;
|
||||||
needle+=calc;
|
needle+=calc;
|
||||||
//data[needle>>16]=lastSample;
|
//data[needle>>16]=lastSample;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
rWrite(a,v); \
|
rWrite(a,v); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHIP_DIVIDER 32
|
#define CHIP_DIVIDER 64
|
||||||
|
|
||||||
const char* regCheatSheetPCE[]={
|
const char* regCheatSheetPCE[]={
|
||||||
"Select", "0",
|
"Select", "0",
|
||||||
|
@ -55,15 +55,44 @@ const char** DivPlatformPCE::getRegisterSheet() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformPCE::acquire(short** buf, size_t len) {
|
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++) {
|
for (int i=0; i<6; i++) {
|
||||||
oscBuf[i]->begin(len);
|
oscBuf[i]->begin(len);
|
||||||
|
pce->channel[i].oscBuf=oscBuf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t h=0; h<len; h++) {
|
pce->bb[0]=bb[0];
|
||||||
|
pce->bb[1]=bb[1];
|
||||||
|
|
||||||
|
size_t pos=off;
|
||||||
|
pce->ResetTS(pos);
|
||||||
|
|
||||||
|
while (!writes.empty()) {
|
||||||
|
QueuedWrite w=writes.front();
|
||||||
|
pce->Write(pos,w.addr,w.val);
|
||||||
|
regPool[w.addr&0x0f]=w.val;
|
||||||
|
writes.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t h=0; h<len;) {
|
||||||
|
int advance=len-h;
|
||||||
|
// heuristic
|
||||||
|
int remainTime=9;
|
||||||
|
for (int i=0; i<6; i++) {
|
||||||
|
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
||||||
|
if (chan[i].dacRate<=0) continue;
|
||||||
|
remainTime=(rate-chan[i].dacPeriod+chan[i].dacRate-1)/chan[i].dacRate;
|
||||||
|
if (remainTime<advance) advance=remainTime;
|
||||||
|
if (remainTime<1) advance=1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 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) {
|
||||||
chan[i].dacPeriod+=chan[i].dacRate;
|
chan[i].dacPeriod+=chan[i].dacRate*advance;
|
||||||
if (chan[i].dacPeriod>rate) {
|
if (chan[i].dacPeriod>rate) {
|
||||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||||
if (s->samples<=0 || chan[i].dacPos>=s->samples) {
|
if (s->samples<=0 || chan[i].dacPos>=s->samples) {
|
||||||
|
@ -92,33 +121,19 @@ void DivPlatformPCE::acquire(short** buf, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// PCE part
|
// PCE part
|
||||||
|
// WHAT?????????
|
||||||
|
pos+=advance;
|
||||||
|
|
||||||
while (!writes.empty()) {
|
while (!writes.empty()) {
|
||||||
QueuedWrite w=writes.front();
|
QueuedWrite w=writes.front();
|
||||||
pce->Write(0,w.addr,w.val);
|
pce->Write(pos,w.addr,w.val);
|
||||||
regPool[w.addr&0x0f]=w.val;
|
regPool[w.addr&0x0f]=w.val;
|
||||||
writes.pop();
|
writes.pop();
|
||||||
}
|
}
|
||||||
tempL[0]=0;
|
|
||||||
tempR[0]=0;
|
|
||||||
pce->Update(coreQuality);
|
|
||||||
pce->ResetTS(0);
|
|
||||||
|
|
||||||
for (int i=0; i<6; i++) {
|
h+=advance;
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
pce->Update(pos);
|
||||||
|
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
oscBuf[i]->end(len);
|
oscBuf[i]->end(len);
|
||||||
|
@ -244,7 +259,7 @@ void DivPlatformPCE::tick(bool sysTick) {
|
||||||
off=parent->getCenterRate()/(double)s->centerRate;
|
off=parent->getCenterRate()/(double)s->centerRate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
chan[i].dacRate=((double)chipClock/2)/MAX(1,off*chan[i].freq);
|
chan[i].dacRate=(double)chipClock/(4*MAX(1,off*chan[i].freq));
|
||||||
if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dacRate);
|
if (dumpWrites) addWrite(0xffff0001+(i<<8),chan[i].dacRate);
|
||||||
}
|
}
|
||||||
if (chan[i].freq<1) chan[i].freq=1;
|
if (chan[i].freq<1) chan[i].freq=1;
|
||||||
|
@ -614,8 +629,6 @@ void DivPlatformPCE::reset() {
|
||||||
}
|
}
|
||||||
pce->Power(0);
|
pce->Power(0);
|
||||||
lastPan=0xff;
|
lastPan=0xff;
|
||||||
memset(tempL,0,32*sizeof(int));
|
|
||||||
memset(tempR,0,32*sizeof(int));
|
|
||||||
curChan=-1;
|
curChan=-1;
|
||||||
sampleBank=0;
|
sampleBank=0;
|
||||||
lfoMode=0;
|
lfoMode=0;
|
||||||
|
@ -639,6 +652,10 @@ bool DivPlatformPCE::keyOffAffectsArp(int ch) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformPCE::hasAcquireDirect() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformPCE::notifyWaveChange(int wave) {
|
void DivPlatformPCE::notifyWaveChange(int wave) {
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
if (chan[i].wave==wave) {
|
if (chan[i].wave==wave) {
|
||||||
|
@ -656,13 +673,13 @@ void DivPlatformPCE::notifyInsDeletion(void* ins) {
|
||||||
|
|
||||||
void DivPlatformPCE::setFlags(const DivConfig& flags) {
|
void DivPlatformPCE::setFlags(const DivConfig& flags) {
|
||||||
if (flags.getInt("clockSel",0)) { // technically there is no PAL PC Engine but oh well...
|
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 {
|
} else {
|
||||||
chipClock=COLOR_NTSC;
|
chipClock=COLOR_NTSC*2.0;
|
||||||
}
|
}
|
||||||
CHECK_CUSTOM_CLOCK;
|
CHECK_CUSTOM_CLOCK;
|
||||||
antiClickEnabled=!flags.getBool("noAntiClick",false);
|
antiClickEnabled=!flags.getBool("noAntiClick",false);
|
||||||
rate=chipClock/(coreQuality>>1);
|
rate=chipClock;
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
oscBuf[i]->setRate(rate);
|
oscBuf[i]->setRate(rate);
|
||||||
}
|
}
|
||||||
|
@ -671,7 +688,7 @@ void DivPlatformPCE::setFlags(const DivConfig& flags) {
|
||||||
delete pce;
|
delete pce;
|
||||||
pce=NULL;
|
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) {
|
void DivPlatformPCE::poke(unsigned int addr, unsigned short val) {
|
||||||
|
|
|
@ -70,8 +70,6 @@ class DivPlatformPCE: public DivDispatch {
|
||||||
unsigned char lastPan;
|
unsigned char lastPan;
|
||||||
|
|
||||||
int curChan;
|
int curChan;
|
||||||
int tempL[32];
|
|
||||||
int tempR[32];
|
|
||||||
unsigned char sampleBank, lfoMode, lfoSpeed;
|
unsigned char sampleBank, lfoMode, lfoSpeed;
|
||||||
int coreQuality;
|
int coreQuality;
|
||||||
PCE_PSG* pce;
|
PCE_PSG* pce;
|
||||||
|
@ -81,6 +79,7 @@ class DivPlatformPCE: public DivDispatch {
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
public:
|
public:
|
||||||
void acquire(short** buf, size_t len);
|
void acquire(short** buf, size_t len);
|
||||||
|
void acquireDirect(blip_buffer_t** bb, size_t off, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void* getChanState(int chan);
|
void* getChanState(int chan);
|
||||||
DivMacroInt* getChanMacroInt(int ch);
|
DivMacroInt* getChanMacroInt(int ch);
|
||||||
|
@ -99,6 +98,7 @@ class DivPlatformPCE: public DivDispatch {
|
||||||
void muteChannel(int ch, bool mute);
|
void muteChannel(int ch, bool mute);
|
||||||
int getOutputCount();
|
int getOutputCount();
|
||||||
bool keyOffAffectsArp(int ch);
|
bool keyOffAffectsArp(int ch);
|
||||||
|
bool hasAcquireDirect();
|
||||||
void setCoreQuality(unsigned char q);
|
void setCoreQuality(unsigned char q);
|
||||||
void setFlags(const DivConfig& flags);
|
void setFlags(const DivConfig& flags);
|
||||||
void notifyWaveChange(int wave);
|
void notifyWaveChange(int wave);
|
||||||
|
|
|
@ -70,34 +70,15 @@ 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)
|
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];
|
int32_t delta[2];
|
||||||
|
|
||||||
delta[0] = samp0 - ch->blip_prev_samp[0];
|
delta[0] = samp0 - ch->blip_prev_samp[0];
|
||||||
delta[1] = samp1 - ch->blip_prev_samp[1];
|
delta[1] = samp1 - ch->blip_prev_samp[1];
|
||||||
|
|
||||||
const int16_t* c = Phase_Filter[(timestamp >> 1) & 1];
|
if (delta[0]) blip_add_delta(bb[0],timestamp,delta[0]);
|
||||||
const int32_t l = (timestamp >> 2) & 0xFFFF;
|
if (delta[1]) blip_add_delta(bb[1],timestamp,delta[1]);
|
||||||
|
|
||||||
HRBufs[0][l + 0] += delta[0] * c[0];
|
ch->oscBuf->putSample(timestamp-ch->lasttsbase,CLAMP(samp0+samp1,-32768,32767));
|
||||||
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];
|
|
||||||
*/
|
|
||||||
|
|
||||||
ch->blip_prev_samp[0] = samp0;
|
ch->blip_prev_samp[0] = samp0;
|
||||||
ch->blip_prev_samp[1] = samp1;
|
ch->blip_prev_samp[1] = samp1;
|
||||||
|
@ -405,7 +386,7 @@ void PSG_SetRegister(const unsigned int id, const uint32_t value)
|
||||||
}
|
}
|
||||||
#endif
|
#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]);
|
//printf("Test: %u, %u\n", sizeof(psg_channel), (uint8_t*)&channel[0].balance - (uint8_t*)&channel[0].waveform[0]);
|
||||||
|
|
||||||
|
@ -424,15 +405,17 @@ PCE_PSG::PCE_PSG(int32_t* hr_l, int32_t* hr_r, int want_revision)
|
||||||
UpdateOutput_Accum = &PCE_PSG::UpdateOutput_Accum_HuC6280A;
|
UpdateOutput_Accum = &PCE_PSG::UpdateOutput_Accum_HuC6280A;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
HRBufs[0] = hr_l;
|
bb[0]=NULL;
|
||||||
HRBufs[1] = hr_r;
|
bb[1]=NULL;
|
||||||
|
|
||||||
lastts = 0;
|
lastts = 0;
|
||||||
|
lasttsbase = 0;
|
||||||
for(int ch = 0; ch < 6; ch++)
|
for(int ch = 0; ch < 6; ch++)
|
||||||
{
|
{
|
||||||
channel[ch].blip_prev_samp[0] = 0;
|
channel[ch].blip_prev_samp[0] = 0;
|
||||||
channel[ch].blip_prev_samp[1] = 0;
|
channel[ch].blip_prev_samp[1] = 0;
|
||||||
channel[ch].lastts = 0;
|
channel[ch].lastts = 0;
|
||||||
|
channel[ch].lasttsbase = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetVolume(1.0); // Will build dbtable in the process.
|
SetVolume(1.0); // Will build dbtable in the process.
|
||||||
|
@ -770,9 +753,12 @@ void PCE_PSG::Update(int32_t timestamp)
|
||||||
void PCE_PSG::ResetTS(int32_t ts_base)
|
void PCE_PSG::ResetTS(int32_t ts_base)
|
||||||
{
|
{
|
||||||
lastts = ts_base;
|
lastts = ts_base;
|
||||||
|
lasttsbase = ts_base;
|
||||||
|
|
||||||
for(int chc = 0; chc < 6; chc++)
|
for(int chc = 0; chc < 6; chc++) {
|
||||||
channel[chc].lastts = ts_base;
|
channel[chc].lastts = ts_base;
|
||||||
|
channel[chc].lasttsbase = ts_base;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCE_PSG::Power(const int32_t timestamp)
|
void PCE_PSG::Power(const int32_t timestamp)
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#define __MDFN_HW_SOUND_PCE_PSG_PCE_PSG_H
|
#define __MDFN_HW_SOUND_PCE_PSG_PCE_PSG_H
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "../../blip_buf.h"
|
||||||
|
#include "../../dispatch.h"
|
||||||
|
|
||||||
class PCE_PSG;
|
class PCE_PSG;
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ struct psg_channel
|
||||||
int32_t counter;
|
int32_t counter;
|
||||||
|
|
||||||
void (PCE_PSG::*UpdateOutput)(const int32_t timestamp, psg_channel *ch);
|
void (PCE_PSG::*UpdateOutput)(const int32_t timestamp, psg_channel *ch);
|
||||||
|
DivDispatchOscBuffer* oscBuf;
|
||||||
|
|
||||||
uint32_t freq_cache;
|
uint32_t freq_cache;
|
||||||
uint32_t noise_freq_cache; // Channel 4,5 only
|
uint32_t noise_freq_cache; // Channel 4,5 only
|
||||||
|
@ -49,6 +52,7 @@ struct psg_channel
|
||||||
int32_t samp_accum; // The result of adding up all the samples in the waveform buffer(part of an optimization for high-frequency playback).
|
int32_t samp_accum; // The result of adding up all the samples in the waveform buffer(part of an optimization for high-frequency playback).
|
||||||
int32_t blip_prev_samp[2];
|
int32_t blip_prev_samp[2];
|
||||||
int32_t lastts;
|
int32_t lastts;
|
||||||
|
int32_t lasttsbase;
|
||||||
|
|
||||||
uint16_t frequency; /* Channel frequency */
|
uint16_t frequency; /* Channel frequency */
|
||||||
uint8_t balance; /* Channel balance */
|
uint8_t balance; /* Channel balance */
|
||||||
|
@ -130,7 +134,7 @@ class PCE_PSG
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
PCE_PSG(int32_t* hr_l, int32_t* hr_r, int want_revision);
|
PCE_PSG(int want_revision);
|
||||||
~PCE_PSG();
|
~PCE_PSG();
|
||||||
|
|
||||||
void Power(const int32_t timestamp);
|
void Power(const int32_t timestamp);
|
||||||
|
@ -150,6 +154,8 @@ class PCE_PSG
|
||||||
|
|
||||||
psg_channel channel[6];
|
psg_channel channel[6];
|
||||||
|
|
||||||
|
blip_buffer_t* bb[2];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void UpdateSubLFO(int32_t timestamp);
|
void UpdateSubLFO(int32_t timestamp);
|
||||||
|
@ -181,10 +187,9 @@ class PCE_PSG
|
||||||
bool vol_pending;
|
bool vol_pending;
|
||||||
|
|
||||||
int32_t lastts;
|
int32_t lastts;
|
||||||
|
int32_t lasttsbase;
|
||||||
int revision;
|
int revision;
|
||||||
|
|
||||||
int32_t* HRBufs[2];
|
|
||||||
|
|
||||||
int32_t dbtable_volonly[32];
|
int32_t dbtable_volonly[32];
|
||||||
|
|
||||||
int32_t dbtable[32][32];
|
int32_t dbtable[32][32];
|
||||||
|
|
|
@ -1432,7 +1432,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
break;
|
break;
|
||||||
case DIV_SYSTEM_PCE:
|
case DIV_SYSTEM_PCE:
|
||||||
if (!hasPCE) {
|
if (!hasPCE) {
|
||||||
hasPCE=disCont[i].dispatch->chipClock;
|
// the clock is halved in VGM...
|
||||||
|
hasPCE=disCont[i].dispatch->chipClock/2;
|
||||||
CHIP_VOL(27,0.98);
|
CHIP_VOL(27,0.98);
|
||||||
willExport[i]=true;
|
willExport[i]=true;
|
||||||
writePCESamples=true;
|
writePCESamples=true;
|
||||||
|
|
Loading…
Reference in a new issue