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
This commit is contained in:
tildearrow 2025-07-26 18:48:23 -05:00
parent c96d2983cd
commit 98030de8c7
9 changed files with 276 additions and 77 deletions

View file

@ -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)
```

View file

@ -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;

View file

@ -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

View file

@ -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...");

View file

@ -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<unsigned int> insPtr;
std::vector<unsigned int> wavePtr;
std::vector<unsigned int> 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; i<ds.insLen; i++) {
insPtr[i]=reader.readI();
insPtr.push_back(reader.readI());
}
wavePtr.reserve(ds.waveLen);
for (int i=0; i<ds.waveLen; i++) {
wavePtr[i]=reader.readI();
wavePtr.push_back(reader.readI());
}
samplePtr.reserve(ds.sampleLen);
for (int i=0; i<ds.sampleLen; i++) {
samplePtr[i]=reader.readI();
samplePtr.push_back(reader.readI());
}
patPtr.reserve(numberOfPats);
for (int i=0; i<numberOfPats; i++) patPtr.push_back(reader.readI());
@ -2201,15 +2204,15 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
saveLock.unlock();
return NULL;
}
if (song.wave.size()>256) {
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;
}

View file

@ -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();

View file

@ -858,9 +858,11 @@ void DivInstrument::writeFeatureWS(SafeWriter* w) {
FEATURE_END;
}
size_t DivInstrument::writeFeatureSL(SafeWriter* w, std::vector<int>& list, const DivSong* song) {
bool sampleUsed[256];
memset(sampleUsed,0,256*sizeof(bool));
size_t DivInstrument::writeFeatureLS(SafeWriter* w, std::vector<int>& 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<int>& 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<int>& list, cons
return ret;
}
size_t DivInstrument::writeFeatureWL(SafeWriter* w, std::vector<int>& list, const DivSong* song) {
bool waveUsed[256];
memset(waveUsed,0,256*sizeof(bool));
size_t DivInstrument::writeFeatureLW(SafeWriter* w, std::vector<int>& 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<std.waveMacro.len; i++) {
if (std.waveMacro.val[i]>=0 && std.waveMacro.val[i]<(int)song->wave.size()) {
@ -931,10 +937,10 @@ size_t DivInstrument::writeFeatureWL(SafeWriter* w, std::vector<int>& 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; i<sampleCount; i++) {
sampleIndex[i]=reader.readC();
sampleIndex[i]=(unsigned char)reader.readC();
}
for (int i=0; i<sampleCount; i++) {
samplePtr[i]=reader.readI();
@ -2296,7 +2302,7 @@ void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short versi
// load samples
for (int i=0; i<sampleCount; i++) {
reader.seek(samplePtr[i],SEEK_SET);
if (song->sample.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; i<waveCount; i++) {
waveIndex[i]=reader.readC();
waveIndex[i]=(unsigned char)reader.readC();
}
for (int i=0; i<waveCount; i++) {
wavePtr[i]=reader.readI();
@ -2355,7 +2365,7 @@ void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short versi
// load wavetables
for (int i=0; i<waveCount; i++) {
reader.seek(wavePtr[i],SEEK_SET);
if (song->wave.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<std.waveMacro.len; i++) {
if (std.waveMacro.val[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; i<sampleCount; i++) {
sampleIndex[i]=(unsigned short)reader.readS();
}
for (int i=0; i<sampleCount; i++) {
samplePtr[i]=reader.readI();
}
size_t lastSeek=reader.tell();
// load samples
for (int i=0; i<sampleCount; i++) {
reader.seek(samplePtr[i],SEEK_SET);
if (song->sample.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; i<waveCount; i++) {
waveIndex[i]=(unsigned short)reader.readS();
}
for (int i=0; i<waveCount; i++) {
wavePtr[i]=reader.readI();
}
size_t lastSeek=reader.tell();
// load wavetables
for (int i=0; i<waveCount; i++) {
reader.seek(wavePtr[i],SEEK_SET);
if (song->wave.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<std.waveMacro.len; 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;
}
@ -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

View file

@ -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<int>& list, const DivSong* song);
size_t writeFeatureWL(SafeWriter* w, std::vector<int>& list, const DivSong* song);
size_t writeFeatureLS(SafeWriter* w, std::vector<int>& list, const DivSong* song);
size_t writeFeatureLW(SafeWriter* w, std::vector<int>& 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);

View file

@ -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;
}