Prepare for backward and bi-directional loop
This commit is contained in:
parent
da8f7dabd5
commit
d44f5f0b2b
27 changed files with 418 additions and 123 deletions
|
|
@ -110,13 +110,13 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le
|
|||
}
|
||||
} else {
|
||||
DivSample* s=parent->getSample(chan[i].sample);
|
||||
if (s->samples>0) {
|
||||
if (chan[i].audPos<s->samples) {
|
||||
if (s->getEndPosition()>0) {
|
||||
if (chan[i].audPos<(unsigned int)s->getEndPosition()) {
|
||||
writeAudDat(s->data8[chan[i].audPos++]);
|
||||
}
|
||||
if (s->isLoopable() && chan[i].audPos>=MIN(131071,s->getEndPosition())) {
|
||||
chan[i].audPos=s->loopStart;
|
||||
} else if (chan[i].audPos>=MIN(131071,s->samples)) {
|
||||
if (s->isLoopable() && chan[i].audPos>=MIN(131071,(unsigned int)s->getLoopEndPosition())) {
|
||||
chan[i].audPos=s->getLoopStartPosition();
|
||||
} else if (chan[i].audPos>=MIN(131071,(unsigned int)s->getEndPosition())) {
|
||||
chan[i].sample=-1;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -154,9 +154,9 @@ void DivPlatformGenesis::processDAC() {
|
|||
if (s->samples>0) {
|
||||
while (chan[i].dacPeriod>=(chipClock/576)) {
|
||||
++chan[i].dacPos;
|
||||
if (!chan[i].dacDirection && (s->isLoopable() && chan[i].dacPos>=s->getEndPosition())) {
|
||||
chan[i].dacPos=s->loopStart;
|
||||
} else if (chan[i].dacPos>=s->samples) {
|
||||
if (!chan[i].dacDirection && (s->isLoopable() && chan[i].dacPos>=(unsigned int)s->getLoopEndPosition())) {
|
||||
chan[i].dacPos=s->getLoopStartPosition();
|
||||
} else if (chan[i].dacPos>=(unsigned int)s->getEndPosition()) {
|
||||
chan[i].dacSample=-1;
|
||||
chan[i].dacPeriod=0;
|
||||
break;
|
||||
|
|
@ -200,9 +200,9 @@ void DivPlatformGenesis::processDAC() {
|
|||
}
|
||||
}
|
||||
chan[5].dacPos++;
|
||||
if (!chan[5].dacDirection && (s->isLoopable() && chan[5].dacPos>=s->getEndPosition())) {
|
||||
chan[5].dacPos=s->loopStart;
|
||||
} else if (chan[5].dacPos>=s->samples) {
|
||||
if (!chan[5].dacDirection && (s->isLoopable() && chan[5].dacPos>=(unsigned int)s->getLoopEndPosition())) {
|
||||
chan[5].dacPos=s->getLoopStartPosition();
|
||||
} else if (chan[5].dacPos>=(unsigned int)s->getEndPosition()) {
|
||||
chan[5].dacSample=-1;
|
||||
if (parent->song.brokenDACMode) {
|
||||
rWrite(0x2b,0);
|
||||
|
|
|
|||
|
|
@ -158,9 +158,9 @@ void DivPlatformLynx::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
WRITE_OUTPUT(i,(s->data8[chan[i].samplePos++]*chan[i].outVol)>>7);
|
||||
}
|
||||
|
||||
if (s->isLoopable() && chan[i].samplePos>=(int)s->getEndPosition()) {
|
||||
chan[i].samplePos=s->loopStart;
|
||||
} else if (chan[i].samplePos>=(int)s->samples) {
|
||||
if (s->isLoopable() && chan[i].samplePos>=s->getLoopEndPosition()) {
|
||||
chan[i].samplePos=s->getLoopStartPosition();
|
||||
} else if (chan[i].samplePos>=s->getEndPosition()) {
|
||||
chan[i].sample=-1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,14 +58,14 @@ void DivPlatformMMC5::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
dacPeriod+=dacRate;
|
||||
if (dacPeriod>=rate) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
if (s->samples>0) {
|
||||
if (s->getEndPosition()>0) {
|
||||
if (!isMuted[2]) {
|
||||
rWrite(0x5011,((unsigned char)s->data8[dacPos]+0x80));
|
||||
}
|
||||
dacPos++;
|
||||
if (s->isLoopable() && dacPos>=s->getEndPosition()) {
|
||||
dacPos=s->loopStart;
|
||||
} else if (dacPos>=s->samples) {
|
||||
if (s->isLoopable() && dacPos>=(unsigned int)s->getLoopEndPosition()) {
|
||||
dacPos=s->getLoopStartPosition();
|
||||
} else if (dacPos>=(unsigned int)s->getEndPosition()) {
|
||||
dacSample=-1;
|
||||
}
|
||||
dacPeriod-=rate;
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) {
|
|||
dacPeriod+=dacRate; \
|
||||
if (dacPeriod>=rate) { \
|
||||
DivSample* s=parent->getSample(dacSample); \
|
||||
if (s->samples>0) { \
|
||||
if (s->getEndPosition()>0) { \
|
||||
if (!isMuted[4]) { \
|
||||
unsigned char next=((unsigned char)s->data8[dacPos]+0x80)>>1; \
|
||||
if (dacAntiClickOn && dacAntiClick<next) { \
|
||||
|
|
@ -109,9 +109,9 @@ void DivPlatformNES::doWrite(unsigned short addr, unsigned char data) {
|
|||
} \
|
||||
} \
|
||||
dacPos++; \
|
||||
if (s->isLoopable() && dacPos>=s->getEndPosition()) { \
|
||||
dacPos=s->loopStart; \
|
||||
} else if (dacPos>=s->samples) { \
|
||||
if (s->isLoopable() && dacPos>=(unsigned int)s->getLoopEndPosition()) { \
|
||||
dacPos=s->getLoopStartPosition(); \
|
||||
} else if (dacPos>=(unsigned int)s->getEndPosition()) { \
|
||||
dacSample=-1; \
|
||||
} \
|
||||
dacPeriod-=rate; \
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
chan[i].dacPeriod+=chan[i].dacRate;
|
||||
if (chan[i].dacPeriod>rate) {
|
||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||
if (s->samples<=0) {
|
||||
if (s->getEndPosition()<=0) {
|
||||
chan[i].dacSample=-1;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -90,9 +90,9 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
|||
chWrite(i,0x04,0xdf);
|
||||
chWrite(i,0x06,(((unsigned char)s->data8[chan[i].dacPos]+0x80)>>3));
|
||||
chan[i].dacPos++;
|
||||
if (s->isLoopable() && chan[i].dacPos>=s->getEndPosition()) {
|
||||
chan[i].dacPos=s->loopStart;
|
||||
} else if (chan[i].dacPos>=s->samples) {
|
||||
if (s->isLoopable() && chan[i].dacPos>=(unsigned int)s->getLoopEndPosition()) {
|
||||
chan[i].dacPos=s->getLoopStartPosition();
|
||||
} else if (chan[i].dacPos>=(unsigned int)s->getEndPosition()) {
|
||||
chan[i].dacSample=-1;
|
||||
}
|
||||
chan[i].dacPeriod-=rate;
|
||||
|
|
|
|||
|
|
@ -49,13 +49,13 @@ void DivPlatformPCMDAC::acquire(short* bufL, short* bufR, size_t start, size_t l
|
|||
output=(chan.ws.output[chan.audPos]^0x80)<<8;
|
||||
} else {
|
||||
DivSample* s=parent->getSample(chan.sample);
|
||||
if (s->samples>0) {
|
||||
if (s->isLoopable() && chan.audPos>=s->getEndPosition()) {
|
||||
chan.audPos=s->loopStart;
|
||||
} else if (chan.audPos>=s->samples) {
|
||||
if (s->getEndPosition()>0) {
|
||||
if (s->isLoopable() && chan.audPos>=(unsigned int)s->getLoopEndPosition()) {
|
||||
chan.audPos=s->getLoopStartPosition();
|
||||
} else if (chan.audPos>=(unsigned int)s->getEndPosition()) {
|
||||
chan.sample=-1;
|
||||
}
|
||||
if (chan.audPos<s->samples) {
|
||||
if (chan.audPos<(unsigned int)s->getEndPosition()) {
|
||||
output=s->data16[chan.audPos];
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -301,16 +301,17 @@ void DivPlatformQSound::tick(bool sysTick) {
|
|||
qsound_bank = 0x8000 | (s->offQSound >> 16);
|
||||
qsound_addr = s->offQSound & 0xffff;
|
||||
|
||||
int length = s->getEndPosition();
|
||||
int loopStart=s->getLoopStartPosition();
|
||||
int length = s->getLoopEndPosition();
|
||||
if (length > 65536 - 16) {
|
||||
length = 65536 - 16;
|
||||
}
|
||||
if (s->loopStart == -1 || s->loopStart >= length) {
|
||||
if (loopStart == -1 || loopStart >= length) {
|
||||
qsound_end = s->offQSound + length + 15;
|
||||
qsound_loop = 15;
|
||||
} else {
|
||||
qsound_end = s->offQSound + length;
|
||||
qsound_loop = length - s->loopStart;
|
||||
qsound_loop = length - loopStart;
|
||||
}
|
||||
}
|
||||
if (chan[i].std.arp.had) {
|
||||
|
|
|
|||
|
|
@ -143,7 +143,7 @@ void DivPlatformRF5C68::tick(bool sysTick) {
|
|||
start=start+MIN(chan[i].audPos,s->length8);
|
||||
}
|
||||
if (s->isLoopable()) {
|
||||
loop=start+s->loopStart;
|
||||
loop=start+s->getLoopStartPosition();
|
||||
}
|
||||
start=MIN(start,getSampleMemCapacity()-31);
|
||||
loop=MIN(loop,getSampleMemCapacity()-31);
|
||||
|
|
@ -393,7 +393,7 @@ void DivPlatformRF5C68::renderSamples() {
|
|||
size_t memPos=0;
|
||||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
int length=s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT);
|
||||
int length=s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT);
|
||||
int actualLength=MIN((int)(getSampleMemCapacity()-memPos)-31,length);
|
||||
if (actualLength>0) {
|
||||
s->offRF5C68=memPos;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
for (int i=0; i<16; i++) {
|
||||
if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) {
|
||||
DivSample* s=parent->getSample(chan[i].pcm.sample);
|
||||
if (s->samples<=0) {
|
||||
if (s->getEndPosition()<=0) {
|
||||
chan[i].pcm.sample=-1;
|
||||
oscBuf[i]->data[oscBuf[i]->needle++]=0;
|
||||
continue;
|
||||
|
|
@ -56,9 +56,9 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
pcmR+=(s->data8[chan[i].pcm.pos>>8]*chan[i].chVolR);
|
||||
}
|
||||
chan[i].pcm.pos+=chan[i].pcm.freq;
|
||||
if (s->isLoopable() && chan[i].pcm.pos>=(s->getEndPosition()<<8)) {
|
||||
chan[i].pcm.pos=s->loopStart<<8;
|
||||
} else if (chan[i].pcm.pos>=(s->samples<<8)) {
|
||||
if (s->isLoopable() && chan[i].pcm.pos>=((unsigned int)s->getLoopEndPosition()<<8)) {
|
||||
chan[i].pcm.pos=s->getLoopStartPosition()<<8;
|
||||
} else if (chan[i].pcm.pos>=((unsigned int)s->getEndPosition()<<8)) {
|
||||
chan[i].pcm.sample=-1;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -200,16 +200,17 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
|||
chan[c.chan].macroInit(ins);
|
||||
if (dumpWrites) { // Sega PCM writes
|
||||
DivSample* s=parent->getSample(chan[c.chan].pcm.sample);
|
||||
int actualLength=(int)(s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT));
|
||||
int loopStart=s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT);
|
||||
int actualLength=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT));
|
||||
if (actualLength>0xfeff) actualLength=0xfeff;
|
||||
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
||||
addWrite(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff);
|
||||
addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff);
|
||||
addWrite(0x10006+(c.chan<<3),MIN(255,((s->offSegaPCM&0xffff)+actualLength-1)>>8));
|
||||
if (s->loopStart<0 || s->loopStart>=actualLength) {
|
||||
if (loopStart<0 || loopStart>=actualLength) {
|
||||
addWrite(0x10086+(c.chan<<3),2+((s->offSegaPCM>>16)<<3));
|
||||
} else {
|
||||
int loopPos=(s->offSegaPCM&0xffff)+s->loopStart+s->loopOffP;
|
||||
int loopPos=(s->offSegaPCM&0xffff)+loopStart+s->loopOffP;
|
||||
addWrite(0x10004+(c.chan<<3),loopPos&0xff);
|
||||
addWrite(0x10005+(c.chan<<3),(loopPos>>8)&0xff);
|
||||
addWrite(0x10086+(c.chan<<3),((s->offSegaPCM>>16)<<3));
|
||||
|
|
@ -233,16 +234,17 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
|||
chan[c.chan].furnacePCM=false;
|
||||
if (dumpWrites) { // Sega PCM writes
|
||||
DivSample* s=parent->getSample(chan[c.chan].pcm.sample);
|
||||
int actualLength=(int)(s->getEndPosition(DIV_SAMPLE_DEPTH_8BIT));
|
||||
int loopStart=s->getLoopStartPosition(DIV_SAMPLE_DEPTH_8BIT);
|
||||
int actualLength=(s->getLoopEndPosition(DIV_SAMPLE_DEPTH_8BIT));
|
||||
if (actualLength>65536) actualLength=65536;
|
||||
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
||||
addWrite(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff);
|
||||
addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff);
|
||||
addWrite(0x10006+(c.chan<<3),MIN(255,((s->offSegaPCM&0xffff)+actualLength-1)>>8));
|
||||
if (s->loopStart<0 || s->loopStart>=actualLength) {
|
||||
if (loopStart<0 || loopStart>=actualLength) {
|
||||
addWrite(0x10086+(c.chan<<3),2+((s->offSegaPCM>>16)<<3));
|
||||
} else {
|
||||
int loopPos=(s->offSegaPCM&0xffff)+s->loopStart+s->loopOffP;
|
||||
int loopPos=(s->offSegaPCM&0xffff)+loopStart+s->loopOffP;
|
||||
addWrite(0x10004+(c.chan<<3),loopPos&0xff);
|
||||
addWrite(0x10005+(c.chan<<3),(loopPos>>8)&0xff);
|
||||
addWrite(0x10086+(c.chan<<3),((s->offSegaPCM>>16)<<3));
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@ void DivPlatformSoundUnit::tick(bool sysTick) {
|
|||
DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_SU);
|
||||
DivSample* sample=parent->getSample(ins->amiga.getSample(chan[i].note));
|
||||
if (sample!=NULL) {
|
||||
unsigned int sampleEnd=sample->offSU+(sample->getEndPosition());
|
||||
unsigned int sampleEnd=sample->offSU+(sample->getLoopEndPosition());
|
||||
unsigned int off=sample->offSU+chan[i].hasOffset;
|
||||
chan[i].hasOffset=0;
|
||||
if (sampleEnd>=getSampleMemCapacity(0)) sampleEnd=getSampleMemCapacity(0)-1;
|
||||
|
|
@ -229,7 +229,7 @@ void DivPlatformSoundUnit::tick(bool sysTick) {
|
|||
chWrite(i,0x0c,sampleEnd&0xff);
|
||||
chWrite(i,0x0d,sampleEnd>>8);
|
||||
if (sample->isLoopable()) {
|
||||
unsigned int sampleLoop=sample->offSU+sample->loopStart;
|
||||
unsigned int sampleLoop=sample->offSU+sample->getLoopStartPosition();
|
||||
if (sampleLoop>=getSampleMemCapacity(0)) sampleLoop=getSampleMemCapacity(0)-1;
|
||||
chWrite(i,0x0e,sampleLoop&0xff);
|
||||
chWrite(i,0x0f,sampleLoop>>8);
|
||||
|
|
@ -603,7 +603,7 @@ void DivPlatformSoundUnit::renderSamples() {
|
|||
for (int i=0; i<parent->song.sampleLen; i++) {
|
||||
DivSample* s=parent->song.sample[i];
|
||||
if (s->data8==NULL) continue;
|
||||
int paddedLen=s->samples;
|
||||
int paddedLen=s->getEndPosition();
|
||||
if (memPos>=getSampleMemCapacity(0)) {
|
||||
logW("out of PCM memory for sample %d!",i);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -78,14 +78,14 @@ void DivPlatformSwan::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
dacPeriod+=dacRate;
|
||||
while (dacPeriod>rate) {
|
||||
DivSample* s=parent->getSample(dacSample);
|
||||
if (s->samples<=0) {
|
||||
if (s->getEndPosition()<=0) {
|
||||
dacSample=-1;
|
||||
continue;
|
||||
}
|
||||
rWrite(0x09,(unsigned char)s->data8[dacPos++]+0x80);
|
||||
if (s->isLoopable() && dacPos>=s->getEndPosition()) {
|
||||
dacPos=s->loopStart;
|
||||
} else if (dacPos>=s->samples) {
|
||||
if (s->isLoopable() && dacPos>=(unsigned int)s->getLoopEndPosition()) {
|
||||
dacPos=s->getLoopStartPosition();
|
||||
} else if (dacPos>=(unsigned int)s->getEndPosition()) {
|
||||
dacSample=-1;
|
||||
}
|
||||
dacPeriod-=rate;
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ void DivPlatformVERA::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
size_t pos=start;
|
||||
DivSample* s=parent->getSample(chan[16].pcm.sample);
|
||||
while (len>0) {
|
||||
if (s->samples>0) {
|
||||
if (s->getEndPosition()>0) {
|
||||
while (pcm_is_fifo_almost_empty(pcm)) {
|
||||
short tmp_l=0;
|
||||
short tmp_r=0;
|
||||
|
|
@ -96,9 +96,9 @@ void DivPlatformVERA::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
rWritePCMData(tmp_r&0xff);
|
||||
}
|
||||
chan[16].pcm.pos++;
|
||||
if (s->isLoopable() && chan[16].pcm.pos>=s->getEndPosition()) {
|
||||
chan[16].pcm.pos=s->loopStart;
|
||||
} else if (chan[16].pcm.pos>=s->samples) {
|
||||
if (s->isLoopable() && chan[16].pcm.pos>=(unsigned int)s->getLoopEndPosition()) {
|
||||
chan[16].pcm.pos=s->getLoopStartPosition();
|
||||
} else if (chan[16].pcm.pos>=(unsigned int)s->getEndPosition()) {
|
||||
chan[16].pcm.sample=-1;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ void DivPlatformVRC6::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
chan[i].dacPeriod+=chan[i].dacRate;
|
||||
if (chan[i].dacPeriod>rate) {
|
||||
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||
if (s->samples<=0) {
|
||||
if (s->getEndPosition()<=0) {
|
||||
chan[i].dacSample=-1;
|
||||
chWrite(i,0,0);
|
||||
continue;
|
||||
|
|
@ -77,9 +77,9 @@ void DivPlatformVRC6::acquire(short* bufL, short* bufR, size_t start, size_t len
|
|||
chWrite(i,0,0x80|chan[i].dacOut);
|
||||
}
|
||||
chan[i].dacPos++;
|
||||
if (s->isLoopable() && chan[i].dacPos>=s->getEndPosition()) {
|
||||
chan[i].dacPos=s->loopStart;
|
||||
} else if (chan[i].dacPos>=s->samples) {
|
||||
if (s->isLoopable() && chan[i].dacPos>=(unsigned int)s->getLoopEndPosition()) {
|
||||
chan[i].dacPos=s->getLoopStartPosition();
|
||||
} else if (chan[i].dacPos>=(unsigned int)s->getEndPosition()) {
|
||||
chan[i].dacSample=-1;
|
||||
chWrite(i,0,0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ void DivPlatformZXBeeper::acquire(short* bufL, short* bufR, size_t start, size_t
|
|||
if (curSample>=0 && curSample<parent->song.sampleLen) {
|
||||
if (--curSamplePeriod<0) {
|
||||
DivSample* s=parent->getSample(curSample);
|
||||
if (s->samples>0) {
|
||||
if (s->getEndPosition()>0) {
|
||||
sampleOut=(s->data8[curSamplePos++]>0);
|
||||
if (curSamplePos>=s->samples) curSample=-1;
|
||||
if (curSamplePos>=(unsigned int)s->getEndPosition()) curSample=-1;
|
||||
// 256 bits
|
||||
if (curSamplePos>2047) curSample=-1;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue