From 98030de8c708a24ad9dc1b50f8fa1fa076121cc5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 26 Jul 2025 18:48:23 -0500 Subject: [PATCH] dev233 - breaking the limit, part 1 now up to 32768 wavetables and 32768 samples this is the first part and does not implement the new sample limit correctly I have to adapt every dispatch to the new limit... see you in the next part the format version had to be bumped because the WL and SL .fui features were limited to 256 entries there are new LW and LS blocks with more space howwver there's a new issue... we can have a feature larger than 65536, which is a limit imposed by the feature header :< this will be addressed though --- papers/newIns.md | 32 ++++- src/engine/engine.cpp | 12 +- src/engine/engine.h | 4 +- src/engine/fileOps/ftm.cpp | 4 +- src/engine/fileOps/fur.cpp | 31 ++--- src/engine/fileOps/xm.cpp | 2 +- src/engine/instrument.cpp | 234 +++++++++++++++++++++++++++++++------ src/engine/instrument.h | 6 +- src/engine/vgmOps.cpp | 28 +++-- 9 files changed, 276 insertions(+), 77 deletions(-) diff --git a/papers/newIns.md b/papers/newIns.md index 7b6512f0f..6a4a94198 100644 --- a/papers/newIns.md +++ b/papers/newIns.md @@ -151,8 +151,10 @@ the following feature codes are recognized: - `N1`: Namco 163 ins data - `FD`: FDS/Virtual Boy ins data - `WS`: wavetable synth data -- `SL`: list of samples -- `WL`: list of wavetables +- `SL`: list of samples (<233) +- `WL`: list of wavetables (<233) +- `LS`: list of samples (>=233) +- `LW`: list of wavetables (>=233) - `MP`: MultiPCM ins data - `SU`: Sound Unit ins data - `ES`: ES5506 ins data @@ -555,7 +557,7 @@ size | description 1 | parameter 4 ``` -# list of samples (SL) +# old list of samples (SL) (<233) ``` size | description @@ -566,7 +568,7 @@ size | description | - these use the Furnace sample format. ``` -# list of wavetables (WL) +# old list of wavetables (WL) (<233) ``` size | description @@ -577,6 +579,28 @@ size | description | - these use the Furnace wavetable format. ``` +# new list of samples (LS) (>=233) + +``` +size | description +-----|------------------------------------ + 2 | number of samples + 2?? | sample indexes... + 4?? | pointers to samples... + | - these use the Furnace sample format. +``` + +# new list of wavetables (LW) (>=233) + +``` +size | description +-----|------------------------------------ + 2 | number of wavetables + 2?? | wavetable indexes... + 4?? | pointers to wavetables... + | - these use the Furnace wavetable format. +``` + # MultiPCM data (MP) ``` diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 9aa669974..315f77c4b 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -932,11 +932,13 @@ void DivEngine::delUnusedWaves() { } void DivEngine::delUnusedSamples() { + if (song.sample.empty()) return; + BUSY_BEGIN; saveLock.lock(); - bool isUsed[256]; - memset(isUsed,0,256*sizeof(bool)); + bool* isUsed=new bool[song.sample.size()]; + memset(isUsed,0,song.sample.size()*sizeof(bool)); // scan in instruments for (DivInstrument* i: song.ins) { @@ -1029,6 +1031,8 @@ void DivEngine::delUnusedSamples() { // render renderSamples(); + delete[] isUsed; + saveLock.unlock(); BUSY_END; } @@ -2707,7 +2711,7 @@ void DivEngine::delInstrument(int index) { } int DivEngine::addWave() { - if (song.wave.size()>=256) { + if (song.wave.size()>=32768) { lastError=_("too many wavetables!"); return -1; } @@ -2724,7 +2728,7 @@ int DivEngine::addWave() { } int DivEngine::addWavePtr(DivWavetable* which) { - if (song.wave.size()>=256) { + if (song.wave.size()>=32768) { lastError=_("too many wavetables!"); delete which; return -1; diff --git a/src/engine/engine.h b/src/engine/engine.h index 5594ad359..74b8064f5 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,8 +54,8 @@ class DivWorkPool; #define DIV_UNSTABLE -#define DIV_VERSION "dev232" -#define DIV_ENGINE_VERSION 232 +#define DIV_VERSION "dev233" +#define DIV_ENGINE_VERSION 233 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/fileOps/ftm.cpp b/src/engine/fileOps/ftm.cpp index f1ee0eb15..b471959d6 100644 --- a/src/engine/fileOps/ftm.cpp +++ b/src/engine/fileOps/ftm.cpp @@ -1089,7 +1089,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si ins->fds.modSpeed = reader.readI(); ins->fds.modDepth = reader.readI(); reader.readI(); // this is delay. currently ignored. TODO. - if (ds.wave.size()>=256) { + if (ds.wave.size()>=32768) { logW("too many waves! ignoring..."); delete wave; } else { @@ -1210,7 +1210,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si wave->data[jj] = val; } - if (ds.wave.size()<256) { + if (ds.wave.size()<32768) { ds.wave.push_back(wave); } else { logW("too many waves..."); diff --git a/src/engine/fileOps/fur.cpp b/src/engine/fileOps/fur.cpp index 2193c0510..e67360108 100644 --- a/src/engine/fileOps/fur.cpp +++ b/src/engine/fileOps/fur.cpp @@ -692,9 +692,9 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS } bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { - unsigned int insPtr[256]; - unsigned int wavePtr[256]; - unsigned int samplePtr[256]; + std::vector insPtr; + std::vector wavePtr; + std::vector samplePtr; unsigned int subSongPtr[256]; unsigned int sysFlagsPtr[DIV_MAX_CHIPS]; unsigned int assetDirPtr[3]; @@ -934,13 +934,13 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { delete[] file; return false; } - if (ds.waveLen<0 || ds.waveLen>256) { + if (ds.waveLen<0 || ds.waveLen>32768) { logE("invalid wavetable count!"); lastError="invalid wavetable count!"; delete[] file; return false; } - if (ds.sampleLen<0 || ds.sampleLen>256) { + if (ds.sampleLen<0 || ds.sampleLen>32768) { logE("invalid sample count!"); lastError="invalid sample count!"; delete[] file; @@ -1142,14 +1142,17 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { } // pointers + insPtr.reserve(ds.insLen); for (int i=0; i256) { - logE("maximum number of wavetables is 256!"); - lastError="maximum number of wavetables is 256"; + if (song.wave.size()>32768) { + logE("maximum number of wavetables is 32768!"); + lastError="maximum number of wavetables is 32768"; saveLock.unlock(); return NULL; } - if (song.sample.size()>256) { - logE("maximum number of samples is 256!"); - lastError="maximum number of samples is 256"; + if (song.sample.size()>32768) { + logE("maximum number of samples is 32768!"); + lastError="maximum number of samples is 32768"; saveLock.unlock(); return NULL; } diff --git a/src/engine/fileOps/xm.cpp b/src/engine/fileOps/xm.cpp index 7579c04b5..0a798d090 100644 --- a/src/engine/fileOps/xm.cpp +++ b/src/engine/fileOps/xm.cpp @@ -1334,7 +1334,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) { } ds.sampleLen=ds.sample.size(); - if (ds.sampleLen>256) { + if (ds.sampleLen>32768) { logE("too many samples!"); lastError="too many samples"; ds.unload(); diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index bdb16391c..d76f21997 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -858,9 +858,11 @@ void DivInstrument::writeFeatureWS(SafeWriter* w) { FEATURE_END; } -size_t DivInstrument::writeFeatureSL(SafeWriter* w, std::vector& list, const DivSong* song) { - bool sampleUsed[256]; - memset(sampleUsed,0,256*sizeof(bool)); +size_t DivInstrument::writeFeatureLS(SafeWriter* w, std::vector& list, const DivSong* song) { + if (song==NULL) return 0; + + bool* sampleUsed=new bool[song->sample.size()]; + memset(sampleUsed,0,song->sample.size()*sizeof(bool)); if (amiga.initSample>=0 && amiga.initSample<(int)song->sample.size()) { sampleUsed[amiga.initSample]=true; @@ -880,14 +882,16 @@ size_t DivInstrument::writeFeatureSL(SafeWriter* w, std::vector& list, cons } } + delete[] sampleUsed; + if (list.empty()) return 0; FEATURE_BEGIN("SL"); - w->writeC(list.size()); + w->writeS(list.size()); for (int i: list) { - w->writeC(i); + w->writeS(i); } size_t ret=w->tell(); @@ -902,9 +906,11 @@ size_t DivInstrument::writeFeatureSL(SafeWriter* w, std::vector& list, cons return ret; } -size_t DivInstrument::writeFeatureWL(SafeWriter* w, std::vector& list, const DivSong* song) { - bool waveUsed[256]; - memset(waveUsed,0,256*sizeof(bool)); +size_t DivInstrument::writeFeatureLW(SafeWriter* w, std::vector& list, const DivSong* song) { + if (song==NULL) return 0; + + bool* waveUsed=new bool[song->wave.size()]; + memset(waveUsed,0,song->wave.size()*sizeof(bool)); for (int i=0; i=0 && std.waveMacro.val[i]<(int)song->wave.size()) { @@ -931,10 +937,10 @@ size_t DivInstrument::writeFeatureWL(SafeWriter* w, std::vector& list, cons FEATURE_BEGIN("WL"); - w->writeC(list.size()); + w->writeS(list.size()); for (int i: list) { - w->writeC(i); + w->writeS(i); } size_t ret=w->tell(); @@ -1621,10 +1627,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo writeFeatureWS(w); } if (featureSL) { - slSeek=writeFeatureSL(w,sampleList,song); + slSeek=writeFeatureLS(w,sampleList,song); } if (featureWL) { - wlSeek=writeFeatureWL(w,waveList,song); + wlSeek=writeFeatureLW(w,waveList,song); } if (featureMP) { writeFeatureMP(w); @@ -2275,17 +2281,17 @@ void DivInstrument::readFeatureWS(SafeReader& reader, short version) { void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short version) { READ_FEAT_BEGIN; - unsigned int samplePtr[256]; - unsigned char sampleIndex[256]; - unsigned char sampleRemap[256]; - memset(samplePtr,0,256*sizeof(unsigned int)); - memset(sampleIndex,0,256); - memset(sampleRemap,0,256); + unsigned int* samplePtr=new unsigned int[32768]; + unsigned short* sampleIndex=new unsigned short[65536]; + unsigned short* sampleRemap=new unsigned short[65536]; + memset(samplePtr,0,32768*sizeof(unsigned int)); + memset(sampleIndex,0,65536*sizeof(unsigned short)); + memset(sampleRemap,0,65536*sizeof(unsigned short)); unsigned char sampleCount=reader.readC(); for (int i=0; isample.size()>=256) { + if (song->sample.size()>=32768) { break; } DivSample* sample=new DivSample; @@ -2316,35 +2322,39 @@ void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short versi reader.seek(lastSeek,SEEK_SET); // re-map samples - if (amiga.initSample>=0 && amiga.initSample<256) { + if (amiga.initSample>=0) { amiga.initSample=sampleRemap[amiga.initSample]; } if (amiga.useNoteMap) { for (int i=0; i<120; i++) { - if (amiga.noteMap[i].map>=0 && amiga.noteMap[i].map<256) { + if (amiga.noteMap[i].map>=0) { amiga.noteMap[i].map=sampleRemap[amiga.noteMap[i].map]; } } } + delete[] samplePtr; + delete[] sampleIndex; + delete[] sampleRemap; + READ_FEAT_END; } void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short version) { READ_FEAT_BEGIN; - unsigned int wavePtr[256]; - unsigned char waveIndex[256]; - unsigned char waveRemap[256]; - memset(wavePtr,0,256*sizeof(unsigned int)); - memset(waveIndex,0,256); - memset(waveRemap,0,256); + unsigned int* wavePtr=new unsigned int[32768]; + unsigned short* waveIndex=new unsigned short[65536]; + unsigned short* waveRemap=new unsigned short[65536]; + memset(wavePtr,0,32768*sizeof(unsigned int)); + memset(waveIndex,0,65536*sizeof(unsigned short)); + memset(waveRemap,0,65536*sizeof(unsigned short)); unsigned char waveCount=reader.readC(); for (int i=0; iwave.size()>=256) { + if (song->wave.size()>=32768) { break; } DivWavetable* wave=new DivWavetable; @@ -2376,16 +2386,164 @@ void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short versi // re-map wavetables if (ws.enabled) { - if (ws.wave1>=0 && ws.wave1<256) ws.wave1=waveRemap[ws.wave1]; + if (ws.wave1>=0 && ws.wave1<32768) ws.wave1=waveRemap[ws.wave1]; if (ws.effect&0x80) { - if (ws.wave2>=0 && ws.wave2<256) ws.wave2=waveRemap[ws.wave2]; + if (ws.wave2>=0 && ws.wave2<32768) ws.wave2=waveRemap[ws.wave2]; } } - if (n163.wave>=0 && n163.wave<256) n163.wave=waveRemap[n163.wave]; + if (n163.wave>=0 && n163.wave<32768) n163.wave=waveRemap[n163.wave]; for (int i=0; i=0 && std.waveMacro.val[i]<256) std.waveMacro.val[i]=waveRemap[std.waveMacro.val[i]]; + if (std.waveMacro.val[i]>=0 && std.waveMacro.val[i]<32768) std.waveMacro.val[i]=waveRemap[std.waveMacro.val[i]]; } + delete[] wavePtr; + delete[] waveIndex; + delete[] waveRemap; + + READ_FEAT_END; +} + +// new versions +void DivInstrument::readFeatureLS(SafeReader& reader, DivSong* song, short version) { + READ_FEAT_BEGIN; + + unsigned int* samplePtr=new unsigned int[32768]; + unsigned short* sampleIndex=new unsigned short[65536]; + unsigned short* sampleRemap=new unsigned short[65536]; + memset(samplePtr,0,32768*sizeof(unsigned int)); + memset(sampleIndex,0,65536*sizeof(unsigned short)); + memset(sampleRemap,0,65536*sizeof(unsigned short)); + + unsigned short sampleCount=reader.readS(); + + if (sampleCount>32768) { + logW("invalid sample count!"); + delete[] samplePtr; + delete[] sampleIndex; + delete[] sampleRemap; + READ_FEAT_END; + return; + } + + for (int i=0; isample.size()>=32768) { + break; + } + DivSample* sample=new DivSample; + int sampleCount=(int)song->sample.size(); + + DivDataErrors result=sample->readSampleData(reader,version); + if (result==DIV_DATA_SUCCESS) { + song->sample.push_back(sample); + song->sampleLen=sampleCount+1; + sampleRemap[sampleIndex[i]]=sampleCount; + } else { + delete sample; + sampleRemap[sampleIndex[i]]=0; + } + } + + reader.seek(lastSeek,SEEK_SET); + + // re-map samples + if (amiga.initSample>=0) { + amiga.initSample=sampleRemap[amiga.initSample]; + } + + if (amiga.useNoteMap) { + for (int i=0; i<120; i++) { + if (amiga.noteMap[i].map>=0) { + amiga.noteMap[i].map=sampleRemap[amiga.noteMap[i].map]; + } + } + } + + delete[] samplePtr; + delete[] sampleIndex; + delete[] sampleRemap; + + READ_FEAT_END; +} + +void DivInstrument::readFeatureLW(SafeReader& reader, DivSong* song, short version) { + READ_FEAT_BEGIN; + + unsigned int* wavePtr=new unsigned int[32768]; + unsigned short* waveIndex=new unsigned short[65536]; + unsigned short* waveRemap=new unsigned short[65536]; + memset(wavePtr,0,32768*sizeof(unsigned int)); + memset(waveIndex,0,65536*sizeof(unsigned short)); + memset(waveRemap,0,65536*sizeof(unsigned short)); + + unsigned short waveCount=reader.readS(); + + if (waveCount>32768) { + logW("invalid wave count!"); + delete[] wavePtr; + delete[] waveIndex; + delete[] waveRemap; + READ_FEAT_END; + return; + } + + for (int i=0; iwave.size()>=32768) { + break; + } + DivWavetable* wave=new DivWavetable; + int waveCount=(int)song->wave.size(); + + DivDataErrors result=wave->readWaveData(reader,version); + if (result==DIV_DATA_SUCCESS) { + song->wave.push_back(wave); + song->waveLen=waveCount+1; + waveRemap[waveIndex[i]]=waveCount; + } else { + delete wave; + waveRemap[waveIndex[i]]=0; + } + } + + reader.seek(lastSeek,SEEK_SET); + + // re-map wavetables + if (ws.enabled) { + if (ws.wave1>=0 && ws.wave1<32768) ws.wave1=waveRemap[ws.wave1]; + if (ws.effect&0x80) { + if (ws.wave2>=0 && ws.wave2<32768) ws.wave2=waveRemap[ws.wave2]; + } + } + if (n163.wave>=0 && n163.wave<32768) n163.wave=waveRemap[n163.wave]; + for (int i=0; i=0 && std.waveMacro.val[i]<32768) std.waveMacro.val[i]=waveRemap[std.waveMacro.val[i]]; + } + + delete[] wavePtr; + delete[] waveIndex; + delete[] waveRemap; + READ_FEAT_END; } @@ -2647,10 +2805,14 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b readFeatureFD(reader,version); } else if (memcmp(featCode,"WS",2)==0) { // WaveSynth readFeatureWS(reader,version); - } else if (memcmp(featCode,"SL",2)==0 && fui && song!=NULL) { // sample list + } else if (memcmp(featCode,"SL",2)==0 && fui && song!=NULL) { // sample list (old) readFeatureSL(reader,song,version); - } else if (memcmp(featCode,"WL",2)==0 && fui && song!=NULL) { // wave list + } else if (memcmp(featCode,"WL",2)==0 && fui && song!=NULL) { // wave list (old) readFeatureWL(reader,song,version); + } else if (memcmp(featCode,"LS",2)==0 && fui && song!=NULL) { // sample list (new) + readFeatureLS(reader,song,version); + } else if (memcmp(featCode,"LW",2)==0 && fui && song!=NULL) { // wave list (new) + readFeatureLW(reader,song,version); } else if (memcmp(featCode,"MP",2)==0) { // MultiPCM readFeatureMP(reader,version); } else if (memcmp(featCode,"SU",2)==0) { // Sound Unit diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 2c7d91be7..dfabfeaef 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -1097,8 +1097,8 @@ struct DivInstrument : DivInstrumentPOD { void writeFeatureN1(SafeWriter* w); void writeFeatureFD(SafeWriter* w); void writeFeatureWS(SafeWriter* w); - size_t writeFeatureSL(SafeWriter* w, std::vector& list, const DivSong* song); - size_t writeFeatureWL(SafeWriter* w, std::vector& list, const DivSong* song); + size_t writeFeatureLS(SafeWriter* w, std::vector& list, const DivSong* song); + size_t writeFeatureLW(SafeWriter* w, std::vector& list, const DivSong* song); void writeFeatureMP(SafeWriter* w); void writeFeatureSU(SafeWriter* w); void writeFeatureES(SafeWriter* w); @@ -1123,6 +1123,8 @@ struct DivInstrument : DivInstrumentPOD { void readFeatureWS(SafeReader& reader, short version); void readFeatureSL(SafeReader& reader, DivSong* song, short version); void readFeatureWL(SafeReader& reader, DivSong* song, short version); + void readFeatureLS(SafeReader& reader, DivSong* song, short version); + void readFeatureLW(SafeReader& reader, DivSong* song, short version); void readFeatureMP(SafeReader& reader, short version); void readFeatureSU(SafeReader& reader, short version); void readFeatureES(SafeReader& reader, short version); diff --git a/src/engine/vgmOps.cpp b/src/engine/vgmOps.cpp index 3ed2a888b..7081a8e1f 100644 --- a/src/engine/vgmOps.cpp +++ b/src/engine/vgmOps.cpp @@ -764,8 +764,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write pendingFreq[streamID]=write.val; } else { DivSample* sample=song.sample[write.val]; - int pos=sampleOff8[write.val&0xff]+setPos[streamID]; - int len=(int)sampleLen8[write.val&0xff]-setPos[streamID]; + int pos=sampleOff8[write.val&0x7fff]+setPos[streamID]; + int len=(int)sampleLen8[write.val&0x7fff]-setPos[streamID]; if (len<0) len=0; @@ -807,8 +807,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write loopFreq[streamID]=realFreq; if (pendingFreq[streamID]!=-1) { DivSample* sample=song.sample[pendingFreq[streamID]]; - int pos=sampleOff8[pendingFreq[streamID]&0xff]+setPos[streamID]; - int len=(int)sampleLen8[pendingFreq[streamID]&0xff]-setPos[streamID]; + int pos=sampleOff8[pendingFreq[streamID]&0x7fff]+setPos[streamID]; + int len=(int)sampleLen8[pendingFreq[streamID]&0x7fff]-setPos[streamID]; if (len<0) len=0; @@ -859,8 +859,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write if (playingSample[streamID]!=-1 && pendingFreq[streamID]==-1) { // play the sample again DivSample* sample=song.sample[playingSample[streamID]]; - int pos=sampleOff8[playingSample[streamID]&0xff]+setPos[streamID]; - int len=(int)sampleLen8[playingSample[streamID]&0xff]-setPos[streamID]; + int pos=sampleOff8[playingSample[streamID]&0x7fff]+setPos[streamID]; + int len=(int)sampleLen8[playingSample[streamID]&0x7fff]-setPos[streamID]; if (len<0) len=0; @@ -1329,9 +1329,9 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p int loopTickSong=-1; int songTick=0; - unsigned int sampleOff8[256]; - unsigned int sampleLen8[256]; - unsigned int sampleOffSegaPCM[256]; + unsigned int* sampleOff8=new unsigned int[32768]; + unsigned int* sampleLen8=new unsigned int[32768]; + unsigned int* sampleOffSegaPCM=new unsigned int[32768]; SafeWriter* w=new SafeWriter; w->init(); @@ -2202,9 +2202,9 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p unsigned int songOff=w->tell(); // initialize sample offsets - memset(sampleOff8,0,256*sizeof(unsigned int)); - memset(sampleLen8,0,256*sizeof(unsigned int)); - memset(sampleOffSegaPCM,0,256*sizeof(unsigned int)); + memset(sampleOff8,0,32768*sizeof(unsigned int)); + memset(sampleLen8,0,32768*sizeof(unsigned int)); + memset(sampleOffSegaPCM,0,32768*sizeof(unsigned int)); // write samples unsigned int sampleSeek=0; @@ -2968,6 +2968,10 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p logI("%d register writes total.",writeCount); + delete[] sampleOff8; + delete[] sampleLen8; + delete[] sampleOffSegaPCM; + BUSY_END; return w; }