VRC6: acquireDirect()
to-do: check for regressions? I need to sleep
This commit is contained in:
parent
0efe232ae8
commit
229003c597
4 changed files with 83 additions and 34 deletions
|
|
@ -46,16 +46,28 @@ const char** DivPlatformVRC6::getRegisterSheet() {
|
|||
return regCheatSheetVRC6;
|
||||
}
|
||||
|
||||
void DivPlatformVRC6::acquire(short** buf, size_t len) {
|
||||
void DivPlatformVRC6::acquireDirect(blip_buffer_t** bb, size_t len) {
|
||||
for (int i=0; i<3; i++) {
|
||||
oscBuf[i]->begin(len);
|
||||
}
|
||||
|
||||
for (size_t h=0; h<len; h++) {
|
||||
// running heuristic
|
||||
int advance=vrc6.predict();
|
||||
if ((int)(len-h)<advance) advance=len-h;
|
||||
for (int i=0; i<2; i++) {
|
||||
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
||||
if (chan[i].dacRate<=0) continue;
|
||||
int remainTime=(rate-chan[i].dacPeriod+chan[i].dacRate-1)/chan[i].dacRate;
|
||||
if (remainTime<advance) advance=remainTime;
|
||||
if (remainTime<1) advance=1;
|
||||
}
|
||||
}
|
||||
|
||||
// PCM part
|
||||
for (int i=0; i<2; i++) {
|
||||
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) {
|
||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||
if (s->samples<=0 || chan[i].dacPos>=s->samples) {
|
||||
|
|
@ -81,11 +93,13 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) {
|
|||
}
|
||||
|
||||
// VRC6 part
|
||||
vrc6.tick();
|
||||
vrc6.tick(advance);
|
||||
h+=advance-1;
|
||||
int sample=vrc6.out()<<9; // scale to 16 bit
|
||||
if (sample>32767) sample=32767;
|
||||
if (sample<-32768) sample=-32768;
|
||||
buf[0][h]=sample;
|
||||
if (sample!=prevSample) {
|
||||
blip_add_delta(bb[0],h,sample-prevSample);
|
||||
prevSample=sample;
|
||||
}
|
||||
|
||||
// Oscilloscope buffer part
|
||||
if (++writeOscBuf>=32) {
|
||||
|
|
@ -96,7 +110,7 @@ void DivPlatformVRC6::acquire(short** buf, size_t len) {
|
|||
oscBuf[2]->putSample(h,vrc6.sawtooth_out()<<10);
|
||||
}
|
||||
|
||||
// Command part
|
||||
// Command part (what the heck why at the END?!)
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite w=writes.front();
|
||||
switch (w.addr&0xf000) {
|
||||
|
|
@ -523,6 +537,7 @@ void DivPlatformVRC6::reset() {
|
|||
}
|
||||
|
||||
sampleBank=0;
|
||||
prevSample=0;
|
||||
|
||||
vrc6.reset();
|
||||
// Initialize control register
|
||||
|
|
@ -537,6 +552,10 @@ bool DivPlatformVRC6::keyOffAffectsArp(int ch) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool DivPlatformVRC6::hasAcquireDirect() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void DivPlatformVRC6::setFlags(const DivConfig& flags) {
|
||||
int clockSel=flags.getInt("clockSel",0);
|
||||
if (clockSel==2) { // Dendy
|
||||
|
|
|
|||
|
|
@ -57,13 +57,14 @@ class DivPlatformVRC6: public DivDispatch, public vrcvi_intf {
|
|||
unsigned char sampleBank;
|
||||
unsigned char writeOscBuf;
|
||||
vrcvi_core vrc6;
|
||||
int prevSample;
|
||||
unsigned char regPool[13];
|
||||
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
public:
|
||||
void acquire(short** buf, size_t len);
|
||||
void acquireDirect(blip_buffer_t** bb, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
@ -76,6 +77,7 @@ class DivPlatformVRC6: public DivDispatch, public vrcvi_intf {
|
|||
void tick(bool sysTick=true);
|
||||
void muteChannel(int ch, bool mute);
|
||||
bool keyOffAffectsArp(int ch);
|
||||
bool hasAcquireDirect();
|
||||
void setFlags(const DivConfig& flags);
|
||||
void notifyInsDeletion(void* ins);
|
||||
void poke(unsigned int addr, unsigned short val);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue