mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-23 13:05:11 +00:00
bring crash fix from 0.5.8
This commit is contained in:
parent
dee74e7b14
commit
19c4f5559a
11 changed files with 33 additions and 25 deletions
|
@ -29,6 +29,7 @@ the format versions are:
|
||||||
- 58: Furnace dev58
|
- 58: Furnace dev58
|
||||||
- 57: Furnace dev57
|
- 57: Furnace dev57
|
||||||
|
|
||||||
|
- 54: Furnace 0.5.8
|
||||||
- 53: Furnace 0.5.7
|
- 53: Furnace 0.5.7
|
||||||
- 52: Furnace 0.5.7pre4
|
- 52: Furnace 0.5.7pre4
|
||||||
- 51: Furnace 0.5.7pre3
|
- 51: Furnace 0.5.7pre3
|
||||||
|
|
|
@ -623,6 +623,11 @@ DivWavetable* DivEngine::getWave(int index) {
|
||||||
return song.wave[index];
|
return song.wave[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DivSample* DivEngine::getSample(int index) {
|
||||||
|
if (index<0 || index>=song.sampleLen) return &song.nullSample;
|
||||||
|
return song.sample[index];
|
||||||
|
}
|
||||||
|
|
||||||
void DivEngine::setLoops(int loops) {
|
void DivEngine::setLoops(int loops) {
|
||||||
remainingLoops=loops;
|
remainingLoops=loops;
|
||||||
}
|
}
|
||||||
|
|
|
@ -260,6 +260,7 @@ class DivEngine {
|
||||||
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
|
void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size);
|
||||||
DivInstrument* getIns(int index);
|
DivInstrument* getIns(int index);
|
||||||
DivWavetable* getWave(int index);
|
DivWavetable* getWave(int index);
|
||||||
|
DivSample* getSample(int index);
|
||||||
// start fresh
|
// start fresh
|
||||||
void createNew();
|
void createNew();
|
||||||
// load a file.
|
// load a file.
|
||||||
|
|
|
@ -71,7 +71,7 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le
|
||||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
chan[i].audSub-=AMIGA_DIVIDER;
|
chan[i].audSub-=AMIGA_DIVIDER;
|
||||||
if (chan[i].audSub<0) {
|
if (chan[i].audSub<0) {
|
||||||
DivSample* s=parent->song.sample[chan[i].sample];
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
if (s->samples>0) {
|
if (s->samples>0) {
|
||||||
chan[i].audDat=s->data8[chan[i].audPos++];
|
chan[i].audDat=s->data8[chan[i].audPos++];
|
||||||
if (chan[i].audPos>=s->samples || chan[i].audPos>=131071) {
|
if (chan[i].audPos>=s->samples || chan[i].audPos>=131071) {
|
||||||
|
@ -117,7 +117,7 @@ void DivPlatformAmiga::tick() {
|
||||||
}
|
}
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[i].sample];
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -171,7 +171,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
||||||
chan[c.chan].sample=ins->amiga.initSample;
|
chan[c.chan].sample=ins->amiga.initSample;
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].sample];
|
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -258,7 +258,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_LEGATO: {
|
case DIV_CMD_LEGATO: {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].sample];
|
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -89,7 +89,7 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s
|
||||||
if (dacMode && dacSample!=-1) {
|
if (dacMode && dacSample!=-1) {
|
||||||
dacPeriod-=6;
|
dacPeriod-=6;
|
||||||
if (dacPeriod<1) {
|
if (dacPeriod<1) {
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
DivSample* s=parent->getSample(dacSample);
|
||||||
if (s->samples>0) {
|
if (s->samples>0) {
|
||||||
if (!isMuted[5]) {
|
if (!isMuted[5]) {
|
||||||
immWrite(0x2a,(unsigned char)s->data8[dacPos]+0x80);
|
immWrite(0x2a,(unsigned char)s->data8[dacPos]+0x80);
|
||||||
|
@ -159,7 +159,7 @@ void DivPlatformGenesis::acquire_ymfm(short* bufL, short* bufR, size_t start, si
|
||||||
if (dacMode && dacSample!=-1) {
|
if (dacMode && dacSample!=-1) {
|
||||||
dacPeriod-=24;
|
dacPeriod-=24;
|
||||||
if (dacPeriod<1) {
|
if (dacPeriod<1) {
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
DivSample* s=parent->getSample(dacSample);
|
||||||
if (s->samples>0) {
|
if (s->samples>0) {
|
||||||
if (!isMuted[5]) {
|
if (!isMuted[5]) {
|
||||||
immWrite(0x2a,(unsigned char)s->data8[dacPos]+0x80);
|
immWrite(0x2a,(unsigned char)s->data8[dacPos]+0x80);
|
||||||
|
@ -373,7 +373,7 @@ void DivPlatformGenesis::tick() {
|
||||||
if (chan[i].furnaceDac && dacMode) {
|
if (chan[i].furnaceDac && dacMode) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
DivSample* s=parent->getSample(dacSample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -510,8 +510,8 @@ int DivPlatformGenesis::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
dacPos=0;
|
dacPos=0;
|
||||||
dacPeriod=0;
|
dacPeriod=0;
|
||||||
dacRate=1280000/MAX(1,parent->song.sample[dacSample]->rate);
|
dacRate=1280000/MAX(1,parent->getSample(dacSample)->rate);
|
||||||
if (dumpWrites) addWrite(0xffff0001,parent->song.sample[dacSample]->rate);
|
if (dumpWrites) addWrite(0xffff0001,parent->getSample(dacSample)->rate);
|
||||||
chan[c.chan].furnaceDac=false;
|
chan[c.chan].furnaceDac=false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -75,7 +75,7 @@ void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
||||||
if (dacSample!=-1) {
|
if (dacSample!=-1) {
|
||||||
dacPeriod+=dacRate;
|
dacPeriod+=dacRate;
|
||||||
if (dacPeriod>=rate) {
|
if (dacPeriod>=rate) {
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
DivSample* s=parent->getSample(dacSample);
|
||||||
if (s->samples>0) {
|
if (s->samples>0) {
|
||||||
if (!isMuted[4]) {
|
if (!isMuted[4]) {
|
||||||
rWrite(0x4011,((unsigned char)s->data8[dacPos]+0x80)>>1);
|
rWrite(0x4011,((unsigned char)s->data8[dacPos]+0x80)>>1);
|
||||||
|
@ -238,7 +238,7 @@ void DivPlatformNES::tick() {
|
||||||
if (chan[4].furnaceDac) {
|
if (chan[4].furnaceDac) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
if (dacSample>=0 && dacSample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[dacSample];
|
DivSample* s=parent->getSample(dacSample);
|
||||||
off=(double)s->centerRate/8363.0;
|
off=(double)s->centerRate/8363.0;
|
||||||
}
|
}
|
||||||
dacRate=MIN(chan[4].freq*off,32000);
|
dacRate=MIN(chan[4].freq*off,32000);
|
||||||
|
@ -286,7 +286,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
dacPos=0;
|
dacPos=0;
|
||||||
dacPeriod=0;
|
dacPeriod=0;
|
||||||
dacRate=parent->song.sample[dacSample]->rate;
|
dacRate=parent->getSample(dacSample)->rate;
|
||||||
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
if (dumpWrites) addWrite(0xffff0001,dacRate);
|
||||||
chan[c.chan].furnaceDac=false;
|
chan[c.chan].furnaceDac=false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,7 @@ void DivPlatformPCE::acquire(short* bufL, short* bufR, size_t start, size_t len)
|
||||||
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
if (chan[i].pcm && chan[i].dacSample!=-1) {
|
||||||
chan[i].dacPeriod+=chan[i].dacRate;
|
chan[i].dacPeriod+=chan[i].dacRate;
|
||||||
if (chan[i].dacPeriod>rate) {
|
if (chan[i].dacPeriod>rate) {
|
||||||
DivSample* s=parent->song.sample[chan[i].dacSample];
|
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||||
if (s->samples<=0) {
|
if (s->samples<=0) {
|
||||||
chan[i].dacSample=-1;
|
chan[i].dacSample=-1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -200,7 +200,7 @@ void DivPlatformPCE::tick() {
|
||||||
if (chan[i].furnaceDac) {
|
if (chan[i].furnaceDac) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
if (chan[i].dacSample>=0 && chan[i].dacSample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[i].dacSample];
|
DivSample* s=parent->getSample(chan[i].dacSample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -280,7 +280,7 @@ int DivPlatformPCE::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
chan[c.chan].dacPos=0;
|
chan[c.chan].dacPos=0;
|
||||||
chan[c.chan].dacPeriod=0;
|
chan[c.chan].dacPeriod=0;
|
||||||
chan[c.chan].dacRate=parent->song.sample[chan[c.chan].dacSample]->rate;
|
chan[c.chan].dacRate=parent->getSample(chan[c.chan].dacSample)->rate;
|
||||||
if (dumpWrites) {
|
if (dumpWrites) {
|
||||||
chWrite(c.chan,0x04,0xdf);
|
chWrite(c.chan,0x04,0xdf);
|
||||||
addWrite(0xffff0001+(c.chan<<8),chan[c.chan].dacRate);
|
addWrite(0xffff0001+(c.chan<<8),chan[c.chan].dacRate);
|
||||||
|
|
|
@ -290,7 +290,7 @@ void DivPlatformQSound::tick() {
|
||||||
uint16_t qsound_end = 0;
|
uint16_t qsound_end = 0;
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
if (chan[i].sample>=0 && chan[i].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[i].sample];
|
DivSample* s=parent->getSample(chan[i].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -364,7 +364,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
|
||||||
chan[c.chan].sample=ins->amiga.initSample;
|
chan[c.chan].sample=ins->amiga.initSample;
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].sample];
|
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -438,7 +438,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].sample];
|
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
@ -470,7 +470,7 @@ int DivPlatformQSound::dispatch(DivCommand c) {
|
||||||
case DIV_CMD_LEGATO: {
|
case DIV_CMD_LEGATO: {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
if (chan[c.chan].sample>=0 && chan[c.chan].sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].sample];
|
DivSample* s=parent->getSample(chan[c.chan].sample);
|
||||||
if (s->centerRate<1) {
|
if (s->centerRate<1) {
|
||||||
off=1.0;
|
off=1.0;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -43,7 +43,7 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t
|
||||||
pcmL=0; pcmR=0;
|
pcmL=0; pcmR=0;
|
||||||
for (int i=0; i<16; i++) {
|
for (int i=0; i<16; i++) {
|
||||||
if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) {
|
if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[i].pcm.sample];
|
DivSample* s=parent->getSample(chan[i].pcm.sample);
|
||||||
if (s->samples<=0) {
|
if (s->samples<=0) {
|
||||||
chan[i].pcm.sample=-1;
|
chan[i].pcm.sample=-1;
|
||||||
continue;
|
continue;
|
||||||
|
@ -110,7 +110,7 @@ void DivPlatformSegaPCM::tick() {
|
||||||
if (chan[i].furnacePCM) {
|
if (chan[i].furnacePCM) {
|
||||||
double off=1.0;
|
double off=1.0;
|
||||||
if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) {
|
if (chan[i].pcm.sample>=0 && chan[i].pcm.sample<parent->song.sampleLen) {
|
||||||
DivSample* s=parent->song.sample[chan[i].pcm.sample];
|
DivSample* s=parent->getSample(chan[i].pcm.sample);
|
||||||
off=(double)s->centerRate/8363.0;
|
off=(double)s->centerRate/8363.0;
|
||||||
}
|
}
|
||||||
chan[i].pcm.freq=MIN(255,((off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250);
|
chan[i].pcm.freq=MIN(255,((off*parent->song.tuning*pow(2.0,double(chan[i].freq+256)/(64.0*12.0)))*255)/31250);
|
||||||
|
@ -146,7 +146,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
chan[c.chan].furnacePCM=true;
|
chan[c.chan].furnacePCM=true;
|
||||||
if (dumpWrites) { // Sega PCM writes
|
if (dumpWrites) { // Sega PCM writes
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].pcm.sample];
|
DivSample* s=parent->getSample(chan[c.chan].pcm.sample);
|
||||||
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
||||||
addWrite(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff);
|
addWrite(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff);
|
||||||
addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff);
|
addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff);
|
||||||
|
@ -173,10 +173,10 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
chan[c.chan].pcm.pos=0;
|
chan[c.chan].pcm.pos=0;
|
||||||
chan[c.chan].pcm.freq=MIN(255,(parent->song.sample[chan[c.chan].pcm.sample]->rate*255)/31250);
|
chan[c.chan].pcm.freq=MIN(255,(parent->getSample(chan[c.chan].pcm.sample)->rate*255)/31250);
|
||||||
chan[c.chan].furnacePCM=false;
|
chan[c.chan].furnacePCM=false;
|
||||||
if (dumpWrites) { // Sega PCM writes
|
if (dumpWrites) { // Sega PCM writes
|
||||||
DivSample* s=parent->song.sample[chan[c.chan].pcm.sample];
|
DivSample* s=parent->getSample(chan[c.chan].pcm.sample);
|
||||||
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
addWrite(0x10086+(c.chan<<3),3+((s->offSegaPCM>>16)<<3));
|
||||||
addWrite(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff);
|
addWrite(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff);
|
||||||
addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff);
|
addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff);
|
||||||
|
|
|
@ -436,7 +436,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) {
|
||||||
immWrite(0x128+c.chan-7,0);
|
immWrite(0x128+c.chan-7,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DivSample* s=parent->song.sample[12*sampleBank+c.value%12];
|
DivSample* s=parent->getSample(12*sampleBank+c.value%12);
|
||||||
immWrite(0x110+c.chan-7,(s->offA>>8)&0xff);
|
immWrite(0x110+c.chan-7,(s->offA>>8)&0xff);
|
||||||
immWrite(0x118+c.chan-7,s->offA>>16);
|
immWrite(0x118+c.chan-7,s->offA>>16);
|
||||||
int end=s->offA+s->lengthA-1;
|
int end=s->offA+s->lengthA-1;
|
||||||
|
|
|
@ -275,6 +275,7 @@ struct DivSong {
|
||||||
|
|
||||||
DivInstrument nullIns;
|
DivInstrument nullIns;
|
||||||
DivWavetable nullWave;
|
DivWavetable nullWave;
|
||||||
|
DivSample nullSample;
|
||||||
|
|
||||||
void unload();
|
void unload();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue