Lynx: direct stream mode
This commit is contained in:
parent
3c892ada2a
commit
5eae36f092
|
@ -22,7 +22,7 @@
|
||||||
#include "../bsr.h"
|
#include "../bsr.h"
|
||||||
#include <math.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_VOLUME(ch,v) rWrite(0x20+(ch<<3),(v))
|
||||||
#define WRITE_FEEDBACK(ch,v) rWrite(0x21+(ch<<3),(v))
|
#define WRITE_FEEDBACK(ch,v) rWrite(0x21+(ch<<3),(v))
|
||||||
|
@ -123,13 +123,12 @@ const char** DivPlatformLynx::getRegisterSheet() {
|
||||||
return regCheatSheetLynx;
|
return regCheatSheetLynx;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivPlatformLynx::acquire(short** buf, size_t len) {
|
void DivPlatformLynx::processDAC(int sRate) {
|
||||||
for (size_t h=0; h<len; h++) {
|
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
if (chan[i].pcm && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].pcm && chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
chan[i].sampleAccum-=chan[i].sampleFreq;
|
chan[i].sampleAccum-=chan[i].sampleFreq;
|
||||||
if (chan[i].sampleAccum<0) {
|
while (chan[i].sampleAccum<0) {
|
||||||
chan[i].sampleAccum+=rate;
|
chan[i].sampleAccum+=sRate;
|
||||||
DivSample* s=parent->getSample(chan[i].sample);
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
if (s!=NULL) {
|
if (s!=NULL) {
|
||||||
if (isMuted[i]) {
|
if (isMuted[i]) {
|
||||||
|
@ -152,11 +151,36 @@ void DivPlatformLynx::acquire(short** buf, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
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) {
|
void DivPlatformLynx::tick(bool sysTick) {
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
@ -308,7 +332,9 @@ int DivPlatformLynx::dispatch(DivCommand c) {
|
||||||
} else {
|
} else {
|
||||||
chan[c.chan].samplePos=0;
|
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) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
chan[c.chan].baseFreq=NOTE_PERIODIC(c.value);
|
||||||
|
@ -499,6 +525,7 @@ void DivPlatformLynx::reset() {
|
||||||
chan[i]=DivPlatformLynx::Channel();
|
chan[i]=DivPlatformLynx::Channel();
|
||||||
chan[i].std.setEngine(parent);
|
chan[i].std.setEngine(parent);
|
||||||
}
|
}
|
||||||
|
writes.clear();
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
addWrite(0xffffffff,0);
|
addWrite(0xffffffff,0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,10 +68,20 @@ class DivPlatformLynx: public DivDispatch {
|
||||||
bool isMuted[4];
|
bool isMuted[4];
|
||||||
bool tuned;
|
bool tuned;
|
||||||
std::unique_ptr<Lynx::Mikey> mikey;
|
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 putDispatchChip(void*,int);
|
||||||
friend void putDispatchChan(void*,int,int);
|
friend void putDispatchChan(void*,int,int);
|
||||||
|
|
||||||
|
void processDAC(int sRate);
|
||||||
public:
|
public:
|
||||||
void acquire(short** buf, size_t len);
|
void acquire(short** buf, size_t len);
|
||||||
|
void fillStream(std::vector<DivDelayedWrite>& stream, int sRate, 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);
|
||||||
|
|
Loading…
Reference in a new issue