mirror of
https://github.com/tildearrow/furnace.git
synced 2024-12-03 09:47:26 +00:00
Lynx: direct stream mode
This commit is contained in:
parent
3c892ada2a
commit
5eae36f092
2 changed files with 60 additions and 23 deletions
|
@ -22,7 +22,7 @@
|
|||
#include "../bsr.h"
|
||||
#include <math.h>
|
||||
|
||||
#define rWrite(a,v) {if (!skipRegisterWrites) {mikey->write(a,v); if (dumpWrites) {addWrite(a,v);}}}
|
||||
#define rWrite(a,v) {if (!skipRegisterWrites) {writes.push(QueuedWrite(a,v)); if (dumpWrites) {addWrite(a,v);}}}
|
||||
|
||||
#define WRITE_VOLUME(ch,v) rWrite(0x20+(ch<<3),(v))
|
||||
#define WRITE_FEEDBACK(ch,v) rWrite(0x21+(ch<<3),(v))
|
||||
|
@ -123,40 +123,64 @@ const char** DivPlatformLynx::getRegisterSheet() {
|
|||
return regCheatSheetLynx;
|
||||
}
|
||||
|
||||
void DivPlatformLynx::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
for (int i=0; i<4; i++) {
|
||||
if (chan[i].pcm && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||
chan[i].sampleAccum-=chan[i].sampleFreq;
|
||||
if (chan[i].sampleAccum<0) {
|
||||
chan[i].sampleAccum+=rate;
|
||||
DivSample* s=parent->getSample(chan[i].sample);
|
||||
if (s!=NULL) {
|
||||
if (isMuted[i]) {
|
||||
void DivPlatformLynx::processDAC(int sRate) {
|
||||
for (int i=0; i<4; i++) {
|
||||
if (chan[i].pcm && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||
chan[i].sampleAccum-=chan[i].sampleFreq;
|
||||
while (chan[i].sampleAccum<0) {
|
||||
chan[i].sampleAccum+=sRate;
|
||||
DivSample* s=parent->getSample(chan[i].sample);
|
||||
if (s!=NULL) {
|
||||
if (isMuted[i]) {
|
||||
WRITE_OUTPUT(i,0);
|
||||
} else {
|
||||
if (chan[i].samplePos<0 || chan[i].samplePos>=(int)s->samples) {
|
||||
WRITE_OUTPUT(i,0);
|
||||
} else {
|
||||
if (chan[i].samplePos<0 || chan[i].samplePos>=(int)s->samples) {
|
||||
WRITE_OUTPUT(i,0);
|
||||
} else {
|
||||
WRITE_OUTPUT(i,CLAMP((s->data8[chan[i].samplePos]*chan[i].outVol)>>7,-128,127));
|
||||
}
|
||||
WRITE_OUTPUT(i,CLAMP((s->data8[chan[i].samplePos]*chan[i].outVol)>>7,-128,127));
|
||||
}
|
||||
chan[i].samplePos++;
|
||||
}
|
||||
chan[i].samplePos++;
|
||||
|
||||
if (s->isLoopable() && chan[i].samplePos>=s->loopEnd) {
|
||||
chan[i].samplePos=s->loopStart;
|
||||
} else if (chan[i].samplePos>=(int)s->samples) {
|
||||
chan[i].sample=-1;
|
||||
}
|
||||
if (s->isLoopable() && chan[i].samplePos>=s->loopEnd) {
|
||||
chan[i].samplePos=s->loopStart;
|
||||
} else if (chan[i].samplePos>=(int)s->samples) {
|
||||
chan[i].sample=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformLynx::acquire(short** buf, size_t len) {
|
||||
for (size_t h=0; h<len; h++) {
|
||||
processDAC(rate);
|
||||
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite& w=writes.front();
|
||||
mikey->write(w.addr,w.val);
|
||||
writes.pop_front();
|
||||
}
|
||||
|
||||
mikey->sampleAudio(buf[0]+h,buf[1]+h,1,oscBuf);
|
||||
}
|
||||
}
|
||||
|
||||
void DivPlatformLynx::fillStream(std::vector<DivDelayedWrite>& stream, int sRate, size_t len) {
|
||||
writes.clear();
|
||||
for (size_t i=0; i<len; i++) {
|
||||
processDAC(sRate);
|
||||
|
||||
while (!writes.empty()) {
|
||||
QueuedWrite& w=writes.front();
|
||||
stream.push_back(DivDelayedWrite(i,w.addr,w.val));
|
||||
writes.pop_front();
|
||||
}
|
||||
}
|
||||
regWrites.clear();
|
||||
}
|
||||
|
||||
void DivPlatformLynx::tick(bool sysTick) {
|
||||
for (int i=0; i<4; i++) {
|
||||
chan[i].std.next();
|
||||
|
@ -308,7 +332,9 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
|||
} else {
|
||||
chan[c.chan].samplePos=0;
|
||||
}
|
||||
if (dumpWrites) addWrite(0xffff0000+(c.chan<<8),chan[c.chan].sample);
|
||||
if (dumpWrites) {
|
||||
addWrite(0xffff0000+(c.chan<<8),chan[c.chan].sample);
|
||||
}
|
||||
}
|
||||
if (c.value!=DIV_NOTE_NULL) {
|
||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||
|
@ -499,6 +525,7 @@ void DivPlatformLynx::reset() {
|
|||
chan[i]=DivPlatformLynx::Channel();
|
||||
chan[i].std.setEngine(parent);
|
||||
}
|
||||
writes.clear();
|
||||
if (dumpWrites) {
|
||||
addWrite(0xffffffff,0);
|
||||
}
|
||||
|
|
|
@ -68,10 +68,20 @@ class DivPlatformLynx: public DivDispatch {
|
|||
bool isMuted[4];
|
||||
bool tuned;
|
||||
std::unique_ptr<Lynx::Mikey> mikey;
|
||||
struct QueuedWrite {
|
||||
unsigned char addr;
|
||||
unsigned char val;
|
||||
QueuedWrite(): addr(0), val(9) {}
|
||||
QueuedWrite(unsigned char a, unsigned char v): addr(a), val(v) {}
|
||||
};
|
||||
FixedQueue<QueuedWrite,512> writes;
|
||||
friend void putDispatchChip(void*,int);
|
||||
friend void putDispatchChan(void*,int,int);
|
||||
|
||||
void processDAC(int sRate);
|
||||
public:
|
||||
void acquire(short** buf, size_t len);
|
||||
void fillStream(std::vector<DivDelayedWrite>& stream, int sRate, size_t len);
|
||||
int dispatch(DivCommand c);
|
||||
void* getChanState(int chan);
|
||||
DivMacroInt* getChanMacroInt(int ch);
|
||||
|
|
Loading…
Reference in a new issue