diff --git a/papers/format.md b/papers/format.md index 1f44f9ac6..c346dfee2 100644 --- a/papers/format.md +++ b/papers/format.md @@ -29,6 +29,7 @@ the format versions are: - 58: Furnace dev58 - 57: Furnace dev57 +- 54: Furnace 0.5.8 - 53: Furnace 0.5.7 - 52: Furnace 0.5.7pre4 - 51: Furnace 0.5.7pre3 diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 29c293e86..62c016569 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -623,6 +623,11 @@ DivWavetable* DivEngine::getWave(int 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) { remainingLoops=loops; } diff --git a/src/engine/engine.h b/src/engine/engine.h index f4324fb6c..68c003160 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -260,6 +260,7 @@ class DivEngine { void nextBuf(float** in, float** out, int inChans, int outChans, unsigned int size); DivInstrument* getIns(int index); DivWavetable* getWave(int index); + DivSample* getSample(int index); // start fresh void createNew(); // load a file. diff --git a/src/engine/platform/amiga.cpp b/src/engine/platform/amiga.cpp index 98a95a33d..3ee2fd39b 100644 --- a/src/engine/platform/amiga.cpp +++ b/src/engine/platform/amiga.cpp @@ -71,7 +71,7 @@ void DivPlatformAmiga::acquire(short* bufL, short* bufR, size_t start, size_t le if (chan[i].sample>=0 && chan[i].samplesong.sampleLen) { chan[i].audSub-=AMIGA_DIVIDER; if (chan[i].audSub<0) { - DivSample* s=parent->song.sample[chan[i].sample]; + DivSample* s=parent->getSample(chan[i].sample); if (s->samples>0) { chan[i].audDat=s->data8[chan[i].audPos++]; if (chan[i].audPos>=s->samples || chan[i].audPos>=131071) { @@ -117,7 +117,7 @@ void DivPlatformAmiga::tick() { } double off=1.0; if (chan[i].sample>=0 && chan[i].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[i].sample]; + DivSample* s=parent->getSample(chan[i].sample); if (s->centerRate<1) { off=1.0; } else { @@ -171,7 +171,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) { chan[c.chan].sample=ins->amiga.initSample; double off=1.0; if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[c.chan].sample]; + DivSample* s=parent->getSample(chan[c.chan].sample); if (s->centerRate<1) { off=1.0; } else { @@ -258,7 +258,7 @@ int DivPlatformAmiga::dispatch(DivCommand c) { case DIV_CMD_LEGATO: { double off=1.0; if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[c.chan].sample]; + DivSample* s=parent->getSample(chan[c.chan].sample); if (s->centerRate<1) { off=1.0; } else { diff --git a/src/engine/platform/genesis.cpp b/src/engine/platform/genesis.cpp index 9314c7b6f..6f666306b 100644 --- a/src/engine/platform/genesis.cpp +++ b/src/engine/platform/genesis.cpp @@ -89,7 +89,7 @@ void DivPlatformGenesis::acquire_nuked(short* bufL, short* bufR, size_t start, s if (dacMode && dacSample!=-1) { dacPeriod-=6; if (dacPeriod<1) { - DivSample* s=parent->song.sample[dacSample]; + DivSample* s=parent->getSample(dacSample); if (s->samples>0) { if (!isMuted[5]) { 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) { dacPeriod-=24; if (dacPeriod<1) { - DivSample* s=parent->song.sample[dacSample]; + DivSample* s=parent->getSample(dacSample); if (s->samples>0) { if (!isMuted[5]) { immWrite(0x2a,(unsigned char)s->data8[dacPos]+0x80); @@ -373,7 +373,7 @@ void DivPlatformGenesis::tick() { if (chan[i].furnaceDac && dacMode) { double off=1.0; if (dacSample>=0 && dacSamplesong.sampleLen) { - DivSample* s=parent->song.sample[dacSample]; + DivSample* s=parent->getSample(dacSample); if (s->centerRate<1) { off=1.0; } else { @@ -510,8 +510,8 @@ int DivPlatformGenesis::dispatch(DivCommand c) { } dacPos=0; dacPeriod=0; - dacRate=1280000/MAX(1,parent->song.sample[dacSample]->rate); - if (dumpWrites) addWrite(0xffff0001,parent->song.sample[dacSample]->rate); + dacRate=1280000/MAX(1,parent->getSample(dacSample)->rate); + if (dumpWrites) addWrite(0xffff0001,parent->getSample(dacSample)->rate); chan[c.chan].furnaceDac=false; } break; diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 10bb38fec..897d8e842 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -75,7 +75,7 @@ void DivPlatformNES::acquire(short* bufL, short* bufR, size_t start, size_t len) if (dacSample!=-1) { dacPeriod+=dacRate; if (dacPeriod>=rate) { - DivSample* s=parent->song.sample[dacSample]; + DivSample* s=parent->getSample(dacSample); if (s->samples>0) { if (!isMuted[4]) { rWrite(0x4011,((unsigned char)s->data8[dacPos]+0x80)>>1); @@ -238,7 +238,7 @@ void DivPlatformNES::tick() { if (chan[4].furnaceDac) { double off=1.0; if (dacSample>=0 && dacSamplesong.sampleLen) { - DivSample* s=parent->song.sample[dacSample]; + DivSample* s=parent->getSample(dacSample); off=(double)s->centerRate/8363.0; } dacRate=MIN(chan[4].freq*off,32000); @@ -286,7 +286,7 @@ int DivPlatformNES::dispatch(DivCommand c) { } dacPos=0; dacPeriod=0; - dacRate=parent->song.sample[dacSample]->rate; + dacRate=parent->getSample(dacSample)->rate; if (dumpWrites) addWrite(0xffff0001,dacRate); chan[c.chan].furnaceDac=false; } diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index 0ffe5043d..fd8a4fe50 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -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) { chan[i].dacPeriod+=chan[i].dacRate; if (chan[i].dacPeriod>rate) { - DivSample* s=parent->song.sample[chan[i].dacSample]; + DivSample* s=parent->getSample(chan[i].dacSample); if (s->samples<=0) { chan[i].dacSample=-1; continue; @@ -200,7 +200,7 @@ void DivPlatformPCE::tick() { if (chan[i].furnaceDac) { double off=1.0; if (chan[i].dacSample>=0 && chan[i].dacSamplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[i].dacSample]; + DivSample* s=parent->getSample(chan[i].dacSample); if (s->centerRate<1) { off=1.0; } else { @@ -280,7 +280,7 @@ int DivPlatformPCE::dispatch(DivCommand c) { } chan[c.chan].dacPos=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) { chWrite(c.chan,0x04,0xdf); addWrite(0xffff0001+(c.chan<<8),chan[c.chan].dacRate); diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index 3364e4764..0e0637d8a 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -290,7 +290,7 @@ void DivPlatformQSound::tick() { uint16_t qsound_end = 0; double off=1.0; if (chan[i].sample>=0 && chan[i].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[i].sample]; + DivSample* s=parent->getSample(chan[i].sample); if (s->centerRate<1) { off=1.0; } else { @@ -364,7 +364,7 @@ int DivPlatformQSound::dispatch(DivCommand c) { chan[c.chan].sample=ins->amiga.initSample; double off=1.0; if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[c.chan].sample]; + DivSample* s=parent->getSample(chan[c.chan].sample); if (s->centerRate<1) { off=1.0; } else { @@ -438,7 +438,7 @@ int DivPlatformQSound::dispatch(DivCommand c) { case DIV_CMD_NOTE_PORTA: { double off=1.0; if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[c.chan].sample]; + DivSample* s=parent->getSample(chan[c.chan].sample); if (s->centerRate<1) { off=1.0; } else { @@ -470,7 +470,7 @@ int DivPlatformQSound::dispatch(DivCommand c) { case DIV_CMD_LEGATO: { double off=1.0; if (chan[c.chan].sample>=0 && chan[c.chan].samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[c.chan].sample]; + DivSample* s=parent->getSample(chan[c.chan].sample); if (s->centerRate<1) { off=1.0; } else { diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index ba04c0996..7872e0b69 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -43,7 +43,7 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t pcmL=0; pcmR=0; for (int i=0; i<16; i++) { if (chan[i].pcm.sample>=0 && chan[i].pcm.samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[i].pcm.sample]; + DivSample* s=parent->getSample(chan[i].pcm.sample); if (s->samples<=0) { chan[i].pcm.sample=-1; continue; @@ -110,7 +110,7 @@ void DivPlatformSegaPCM::tick() { if (chan[i].furnacePCM) { double off=1.0; if (chan[i].pcm.sample>=0 && chan[i].pcm.samplesong.sampleLen) { - DivSample* s=parent->song.sample[chan[i].pcm.sample]; + DivSample* s=parent->getSample(chan[i].pcm.sample); 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); @@ -146,7 +146,7 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { chan[c.chan].freqChanged=true; chan[c.chan].furnacePCM=true; 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(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff); addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff); @@ -173,10 +173,10 @@ int DivPlatformSegaPCM::dispatch(DivCommand c) { break; } 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; 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(0x10084+(c.chan<<3),(s->offSegaPCM)&0xff); addWrite(0x10085+(c.chan<<3),(s->offSegaPCM>>8)&0xff); diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index eb2b43f90..7347f3e20 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -436,7 +436,7 @@ int DivPlatformYM2610::dispatch(DivCommand c) { immWrite(0x128+c.chan-7,0); 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(0x118+c.chan-7,s->offA>>16); int end=s->offA+s->lengthA-1; diff --git a/src/engine/song.h b/src/engine/song.h index c80bb6ca8..85752288e 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -275,6 +275,7 @@ struct DivSong { DivInstrument nullIns; DivWavetable nullWave; + DivSample nullSample; void unload();