Merge branch 'master' of github.com:tildearrow/furnace
This commit is contained in:
commit
145403e7dd
|
@ -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,10 +85,12 @@ 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* bufL, short* bufR, size_t start, size_t len);
|
||||||
virtual int dispatch(DivCommand c);
|
virtual int dispatch(DivCommand c);
|
||||||
virtual void tick();
|
virtual void tick();
|
||||||
|
|
||||||
|
virtual bool isStereo();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* initialize this DivDispatch.
|
* initialize this DivDispatch.
|
||||||
* @param parent the parent DivEngine.
|
* @param parent the parent DivEngine.
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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} {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#include "../dispatch.h"
|
#include "../dispatch.h"
|
||||||
|
|
||||||
void DivDispatch::acquire(int& l, int& r) {
|
void DivDispatch::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
l=0;
|
|
||||||
r=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivDispatch::tick() {
|
void DivDispatch::tick() {
|
||||||
|
@ -12,6 +10,10 @@ int DivDispatch::dispatch(DivCommand c) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivDispatch::isStereo() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int DivDispatch::init(DivEngine* p, int channels, int sugRate) {
|
int DivDispatch::init(DivEngine* p, int channels, int sugRate) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,11 @@
|
||||||
|
|
||||||
#define FREQ_BASE 277.0f
|
#define FREQ_BASE 277.0f
|
||||||
|
|
||||||
void DivPlatformC64::acquire(int& l, int& r) {
|
void DivPlatformC64::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
sid.clock();
|
for (size_t i=start; i<start+len; i++) {
|
||||||
l=sid.output();
|
sid.clock();
|
||||||
r=l;
|
bufL[i]=sid.output();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformC64::tick() {
|
void DivPlatformC64::tick() {
|
||||||
|
|
|
@ -39,7 +39,7 @@ class DivPlatformC64: public DivDispatch {
|
||||||
|
|
||||||
void updateWave();
|
void updateWave();
|
||||||
public:
|
public:
|
||||||
void acquire(int& l, int& r);
|
void acquire(short* bufL, short* bufR, 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);
|
||||||
|
|
|
@ -2,16 +2,16 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
void DivPlatformDummy::acquire(int& l, int& r) {
|
void DivPlatformDummy::acquire(short* bufL, short* bufR, 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++) {
|
bufL[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) {
|
||||||
|
bufL[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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformDummy::tick() {
|
void DivPlatformDummy::tick() {
|
||||||
|
|
|
@ -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* bufL, short* bufR, 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);
|
||||||
|
|
|
@ -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* bufL, short* bufR, size_t start, size_t len) {
|
||||||
GB_advance_cycles(gb,16);
|
for (int i=start; i<start+len; i++) {
|
||||||
l=gb->apu_output.final_sample.left<<2;
|
GB_advance_cycles(gb,16);
|
||||||
r=gb->apu_output.final_sample.right<<2;
|
bufL[i]=gb->apu_output.final_sample.left<<2;
|
||||||
|
bufR[i]=gb->apu_output.final_sample.right<<2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformGB::updateWave() {
|
void DivPlatformGB::updateWave() {
|
||||||
|
@ -268,6 +270,10 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformGB::isStereo() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int DivPlatformGB::init(DivEngine* p, int channels, int sugRate) {
|
int DivPlatformGB::init(DivEngine* p, int channels, int sugRate) {
|
||||||
parent=p;
|
parent=p;
|
||||||
rate=262144;
|
rate=262144;
|
||||||
|
|
|
@ -36,9 +36,10 @@ 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* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void tick();
|
void tick();
|
||||||
|
bool isStereo();
|
||||||
int init(DivEngine* parent, int channels, int sugRate);
|
int init(DivEngine* parent, int channels, int sugRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -12,59 +12,60 @@ 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* bufL, short* bufR, size_t start, size_t len) {
|
||||||
static short o[2];
|
static short o[2];
|
||||||
static int os[2];
|
static int os[2];
|
||||||
|
|
||||||
if (dacMode && dacSample!=-1) {
|
for (size_t h=start; h<start+len; h++) {
|
||||||
dacPeriod-=6;
|
if (dacMode && dacSample!=-1) {
|
||||||
if (dacPeriod<1) {
|
dacPeriod-=6;
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
if (dacPeriod<1) {
|
||||||
if (s->depth==8) {
|
DivSample* s=parent->song.sample[dacSample];
|
||||||
writes.emplace(0x2a,(unsigned char)s->rendData[dacPos++]+0x80);
|
if (s->depth==8) {
|
||||||
} else {
|
writes.emplace(0x2a,(unsigned char)s->rendData[dacPos++]+0x80);
|
||||||
writes.emplace(0x2a,((unsigned short)s->rendData[dacPos++]+0x8000)>>8);
|
} else {
|
||||||
|
writes.emplace(0x2a,((unsigned short)s->rendData[dacPos++]+0x8000)>>8);
|
||||||
|
}
|
||||||
|
if (dacPos>=s->rendLength) {
|
||||||
|
dacSample=-1;
|
||||||
|
}
|
||||||
|
dacPeriod+=dacRate;
|
||||||
}
|
}
|
||||||
if (dacPos>=s->rendLength) {
|
|
||||||
dacSample=-1;
|
|
||||||
}
|
|
||||||
dacPeriod+=dacRate;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
os[0]=0; os[1]=0;
|
||||||
os[0]=0; os[1]=0;
|
for (int i=0; i<6; i++) {
|
||||||
for (int i=0; i<6; i++) {
|
if (!writes.empty() && --delay<0) {
|
||||||
if (!writes.empty() && --delay<0) {
|
delay=0;
|
||||||
delay=0;
|
QueuedWrite& w=writes.front();
|
||||||
QueuedWrite& w=writes.front();
|
if (w.addrOrVal) {
|
||||||
if (w.addrOrVal) {
|
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
|
||||||
OPN2_Write(&fm,0x1+((w.addr>>8)<<1),w.val);
|
//printf("write: %x = %.2x\n",w.addr,w.val);
|
||||||
//printf("write: %x = %.2x\n",w.addr,w.val);
|
lastBusy=0;
|
||||||
lastBusy=0;
|
writes.pop();
|
||||||
writes.pop();
|
} else {
|
||||||
} else {
|
lastBusy++;
|
||||||
lastBusy++;
|
if (fm.write_busy==0) {
|
||||||
if (fm.write_busy==0) {
|
//printf("busycounter: %d\n",lastBusy);
|
||||||
//printf("busycounter: %d\n",lastBusy);
|
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
|
||||||
OPN2_Write(&fm,0x0+((w.addr>>8)<<1),w.addr);
|
w.addrOrVal=true;
|
||||||
w.addrOrVal=true;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
OPN2_Clock(&fm,o); os[0]+=o[0]; os[1]+=o[1];
|
||||||
|
//OPN2_Write(&fm,0,0);
|
||||||
|
}
|
||||||
|
|
||||||
OPN2_Clock(&fm,o); os[0]+=o[0]; os[1]+=o[1];
|
psgClocks+=223722;
|
||||||
//OPN2_Write(&fm,0,0);
|
while (psgClocks>=rate) {
|
||||||
}
|
psgOut=(psg.acquireOne()*3)>>3;
|
||||||
|
psgClocks-=rate;
|
||||||
|
}
|
||||||
|
|
||||||
psgClocks+=223722;
|
bufL[h]=(os[0]<<5)+psgOut;
|
||||||
while (psgClocks>=rate) {
|
bufR[h]=(os[1]<<5)+psgOut;
|
||||||
psg.acquire(psgOut,psgOut);
|
|
||||||
psgClocks-=rate;
|
|
||||||
psgOut=(psgOut>>2)+(psgOut>>3);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l=(os[0]<<5)+psgOut;
|
|
||||||
r=(os[1]<<5)+psgOut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformGenesis::tick() {
|
void DivPlatformGenesis::tick() {
|
||||||
|
@ -339,6 +340,10 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformGenesis::isStereo() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate) {
|
int DivPlatformGenesis::init(DivEngine* p, int channels, int sugRate) {
|
||||||
parent=p;
|
parent=p;
|
||||||
rate=213068;
|
rate=213068;
|
||||||
|
|
|
@ -48,9 +48,10 @@ class DivPlatformGenesis: public DivDispatch {
|
||||||
int toFreq(int freq);
|
int toFreq(int freq);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void acquire(int& l, int& r);
|
void acquire(short* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void tick();
|
void tick();
|
||||||
|
bool isStereo();
|
||||||
int init(DivEngine* parent, int channels, int sugRate);
|
int init(DivEngine* parent, int channels, int sugRate);
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,30 +5,30 @@
|
||||||
|
|
||||||
#define FREQ_BASE 3424.0f
|
#define FREQ_BASE 3424.0f
|
||||||
|
|
||||||
void DivPlatformNES::acquire(int& l, int& r) {
|
void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
if (dacSample!=-1) {
|
for (size_t i=start; i<start+len; i++) {
|
||||||
dacPeriod+=dacRate;
|
if (dacSample!=-1) {
|
||||||
if (dacPeriod>=rate) {
|
dacPeriod+=dacRate;
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
if (dacPeriod>=rate) {
|
||||||
if (s->depth==8) {
|
DivSample* s=parent->song.sample[dacSample];
|
||||||
apu_wr_reg(0x4011,((unsigned char)s->rendData[dacPos++]+0x80)>>1);
|
if (s->depth==8) {
|
||||||
} else {
|
apu_wr_reg(0x4011,((unsigned char)s->rendData[dacPos++]+0x80)>>1);
|
||||||
apu_wr_reg(0x4011,((unsigned short)s->rendData[dacPos++]+0x8000)>>9);
|
} else {
|
||||||
|
apu_wr_reg(0x4011,((unsigned short)s->rendData[dacPos++]+0x8000)>>9);
|
||||||
|
}
|
||||||
|
if (dacPos>=s->rendLength) {
|
||||||
|
dacSample=-1;
|
||||||
|
}
|
||||||
|
dacPeriod-=rate;
|
||||||
}
|
}
|
||||||
if (dacPos>=s->rendLength) {
|
|
||||||
dacSample=-1;
|
|
||||||
}
|
|
||||||
dacPeriod-=rate;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
apu_tick(NULL);
|
||||||
apu_tick(NULL);
|
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;
|
bufL[i]=(pulse_output()+tnd_output())*30;
|
||||||
r=l;
|
|
||||||
//printf("output value: %d\n",l);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ class DivPlatformNES: public DivDispatch {
|
||||||
|
|
||||||
void updateWave();
|
void updateWave();
|
||||||
public:
|
public:
|
||||||
void acquire(int& l, int& r);
|
void acquire(short* bufL, short* bufR, 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);
|
||||||
|
|
|
@ -13,41 +13,43 @@
|
||||||
|
|
||||||
#define FREQ_BASE 1712.0f*2
|
#define FREQ_BASE 1712.0f*2
|
||||||
|
|
||||||
void DivPlatformPCE::acquire(int& l, int& r) {
|
void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
// PCM part
|
for (size_t h=start; h<start+len; h++) {
|
||||||
for (int i=0; i<6; i++) {
|
// PCM part
|
||||||
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
for (int i=0; i<6; i++) {
|
||||||
if (--chan[i].dacPeriod<1) {
|
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
||||||
DivSample* s=parent->song.sample[chan[i].dacSample];
|
if (--chan[i].dacPeriod<1) {
|
||||||
chWrite(i,0x07,0);
|
DivSample* s=parent->song.sample[chan[i].dacSample];
|
||||||
if (s->depth==8) {
|
chWrite(i,0x07,0);
|
||||||
chWrite(i,0x04,0xdf);
|
if (s->depth==8) {
|
||||||
chWrite(i,0x06,(((unsigned char)s->rendData[chan[i].dacPos++]+0x80)>>3));
|
chWrite(i,0x04,0xdf);
|
||||||
} else {
|
chWrite(i,0x06,(((unsigned char)s->rendData[chan[i].dacPos++]+0x80)>>3));
|
||||||
chWrite(i,0x04,0xdf);
|
} else {
|
||||||
chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>11));
|
chWrite(i,0x04,0xdf);
|
||||||
|
chWrite(i,0x06,(((unsigned short)s->rendData[chan[i].dacPos++]+0x8000)>>11));
|
||||||
|
}
|
||||||
|
if (chan[i].dacPos>=s->rendLength) {
|
||||||
|
chan[i].dacSample=-1;
|
||||||
|
}
|
||||||
|
chan[i].dacPeriod=chan[i].dacRate;
|
||||||
}
|
}
|
||||||
if (chan[i].dacPos>=s->rendLength) {
|
|
||||||
chan[i].dacSample=-1;
|
|
||||||
}
|
|
||||||
chan[i].dacPeriod=chan[i].dacRate;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// PCE part
|
|
||||||
while (!writes.empty()) {
|
|
||||||
QueuedWrite w=writes.front();
|
|
||||||
pce->Write(cycles,w.addr,w.val);
|
|
||||||
writes.pop();
|
|
||||||
}
|
|
||||||
tempL=0; tempR=0;
|
|
||||||
pce->Update(4);
|
|
||||||
pce->ResetTS(0);
|
|
||||||
|
|
||||||
//printf("tempL: %d tempR: %d\n",tempL,tempR);
|
// PCE part
|
||||||
l=tempL;
|
while (!writes.empty()) {
|
||||||
r=tempR;
|
QueuedWrite w=writes.front();
|
||||||
|
pce->Write(cycles,w.addr,w.val);
|
||||||
|
writes.pop();
|
||||||
|
}
|
||||||
|
tempL=0; tempR=0;
|
||||||
|
pce->Update(4);
|
||||||
|
pce->ResetTS(0);
|
||||||
|
|
||||||
|
//printf("tempL: %d tempR: %d\n",tempL,tempR);
|
||||||
|
bufL[h]=tempL;
|
||||||
|
bufR[h]=tempR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformPCE::updateWave(int ch) {
|
void DivPlatformPCE::updateWave(int ch) {
|
||||||
|
@ -248,6 +250,10 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DivPlatformPCE::isStereo() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate) {
|
int DivPlatformPCE::init(DivEngine* p, int channels, int sugRate) {
|
||||||
parent=p;
|
parent=p;
|
||||||
rate=1789773;
|
rate=1789773;
|
||||||
|
|
|
@ -50,9 +50,10 @@ 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* bufL, short* bufR, size_t start, size_t len);
|
||||||
int dispatch(DivCommand c);
|
int dispatch(DivCommand c);
|
||||||
void tick();
|
void tick();
|
||||||
|
bool isStereo();
|
||||||
int init(DivEngine* parent, int channels, int sugRate);
|
int init(DivEngine* parent, int channels, int sugRate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,14 @@
|
||||||
#include "../engine.h"
|
#include "../engine.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
void DivPlatformSMS::acquire(int& l, int& r) {
|
void DivPlatformSMS::acquire(short* bufL, short* bufR, size_t start, size_t len) {
|
||||||
|
sn->sound_stream_update(bufL+start,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() {
|
||||||
|
|
|
@ -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* bufL, short* bufR, 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);
|
||||||
|
|
|
@ -604,26 +604,59 @@ 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[0],bbIn[1],runPos,cycles);
|
||||||
|
runPos+=cycles;
|
||||||
|
nextTick();
|
||||||
|
} else {
|
||||||
|
dispatch->acquire(bbIn[0],bbIn[1],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];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispatch->isStereo()) 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];
|
||||||
}
|
}
|
||||||
|
|
||||||
blip_end_frame(bb[0],runtotal);
|
blip_end_frame(bb[0],runtotal);
|
||||||
blip_end_frame(bb[1],runtotal);
|
|
||||||
|
|
||||||
blip_read_samples(bb[0],bbOut[0],size,0);
|
blip_read_samples(bb[0],bbOut[0],size,0);
|
||||||
blip_read_samples(bb[1],bbOut[1],size,0);
|
|
||||||
|
|
||||||
for (size_t i=0; i<size; i++) {
|
if (dispatch->isStereo()) {
|
||||||
out[0][i]=(float)bbOut[0][i]/16384.0;
|
blip_end_frame(bb[1],runtotal);
|
||||||
out[1][i]=(float)bbOut[1][i]/16384.0;
|
blip_read_samples(bb[1],bbOut[1],size,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dispatch->isStereo()) {
|
||||||
|
for (size_t i=0; i<size; i++) {
|
||||||
|
out[0][i]=(float)bbOut[0][i]/16384.0;
|
||||||
|
out[1][i]=(float)bbOut[1][i]/16384.0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (size_t i=0; i<size; i++) {
|
||||||
|
out[0][i]=(float)bbOut[0][i]/16384.0;
|
||||||
|
out[1][i]=(float)bbOut[0][i]/16384.0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue