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:
parent
c96d2983cd
commit
98030de8c7
|
@ -151,8 +151,10 @@ the following feature codes are recognized:
|
||||||
- `N1`: Namco 163 ins data
|
- `N1`: Namco 163 ins data
|
||||||
- `FD`: FDS/Virtual Boy ins data
|
- `FD`: FDS/Virtual Boy ins data
|
||||||
- `WS`: wavetable synth data
|
- `WS`: wavetable synth data
|
||||||
- `SL`: list of samples
|
- `SL`: list of samples (<233)
|
||||||
- `WL`: list of wavetables
|
- `WL`: list of wavetables (<233)
|
||||||
|
- `LS`: list of samples (>=233)
|
||||||
|
- `LW`: list of wavetables (>=233)
|
||||||
- `MP`: MultiPCM ins data
|
- `MP`: MultiPCM ins data
|
||||||
- `SU`: Sound Unit ins data
|
- `SU`: Sound Unit ins data
|
||||||
- `ES`: ES5506 ins data
|
- `ES`: ES5506 ins data
|
||||||
|
@ -555,7 +557,7 @@ size | description
|
||||||
1 | parameter 4
|
1 | parameter 4
|
||||||
```
|
```
|
||||||
|
|
||||||
# list of samples (SL)
|
# old list of samples (SL) (<233)
|
||||||
|
|
||||||
```
|
```
|
||||||
size | description
|
size | description
|
||||||
|
@ -566,7 +568,7 @@ size | description
|
||||||
| - these use the Furnace sample format.
|
| - these use the Furnace sample format.
|
||||||
```
|
```
|
||||||
|
|
||||||
# list of wavetables (WL)
|
# old list of wavetables (WL) (<233)
|
||||||
|
|
||||||
```
|
```
|
||||||
size | description
|
size | description
|
||||||
|
@ -577,6 +579,28 @@ size | description
|
||||||
| - these use the Furnace wavetable format.
|
| - 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)
|
# MultiPCM data (MP)
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -932,11 +932,13 @@ void DivEngine::delUnusedWaves() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivEngine::delUnusedSamples() {
|
void DivEngine::delUnusedSamples() {
|
||||||
|
if (song.sample.empty()) return;
|
||||||
|
|
||||||
BUSY_BEGIN;
|
BUSY_BEGIN;
|
||||||
saveLock.lock();
|
saveLock.lock();
|
||||||
|
|
||||||
bool isUsed[256];
|
bool* isUsed=new bool[song.sample.size()];
|
||||||
memset(isUsed,0,256*sizeof(bool));
|
memset(isUsed,0,song.sample.size()*sizeof(bool));
|
||||||
|
|
||||||
// scan in instruments
|
// scan in instruments
|
||||||
for (DivInstrument* i: song.ins) {
|
for (DivInstrument* i: song.ins) {
|
||||||
|
@ -1029,6 +1031,8 @@ void DivEngine::delUnusedSamples() {
|
||||||
// render
|
// render
|
||||||
renderSamples();
|
renderSamples();
|
||||||
|
|
||||||
|
delete[] isUsed;
|
||||||
|
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
}
|
}
|
||||||
|
@ -2707,7 +2711,7 @@ void DivEngine::delInstrument(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::addWave() {
|
int DivEngine::addWave() {
|
||||||
if (song.wave.size()>=256) {
|
if (song.wave.size()>=32768) {
|
||||||
lastError=_("too many wavetables!");
|
lastError=_("too many wavetables!");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2724,7 +2728,7 @@ int DivEngine::addWave() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int DivEngine::addWavePtr(DivWavetable* which) {
|
int DivEngine::addWavePtr(DivWavetable* which) {
|
||||||
if (song.wave.size()>=256) {
|
if (song.wave.size()>=32768) {
|
||||||
lastError=_("too many wavetables!");
|
lastError=_("too many wavetables!");
|
||||||
delete which;
|
delete which;
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -54,8 +54,8 @@ class DivWorkPool;
|
||||||
|
|
||||||
#define DIV_UNSTABLE
|
#define DIV_UNSTABLE
|
||||||
|
|
||||||
#define DIV_VERSION "dev232"
|
#define DIV_VERSION "dev233"
|
||||||
#define DIV_ENGINE_VERSION 232
|
#define DIV_ENGINE_VERSION 233
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
|
@ -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.modSpeed = reader.readI();
|
||||||
ins->fds.modDepth = reader.readI();
|
ins->fds.modDepth = reader.readI();
|
||||||
reader.readI(); // this is delay. currently ignored. TODO.
|
reader.readI(); // this is delay. currently ignored. TODO.
|
||||||
if (ds.wave.size()>=256) {
|
if (ds.wave.size()>=32768) {
|
||||||
logW("too many waves! ignoring...");
|
logW("too many waves! ignoring...");
|
||||||
delete wave;
|
delete wave;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1210,7 +1210,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
||||||
wave->data[jj] = val;
|
wave->data[jj] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ds.wave.size()<256) {
|
if (ds.wave.size()<32768) {
|
||||||
ds.wave.push_back(wave);
|
ds.wave.push_back(wave);
|
||||||
} else {
|
} else {
|
||||||
logW("too many waves...");
|
logW("too many waves...");
|
||||||
|
|
|
@ -692,9 +692,9 @@ void DivEngine::convertOldFlags(unsigned int oldFlags, DivConfig& newFlags, DivS
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
||||||
unsigned int insPtr[256];
|
std::vector<unsigned int> insPtr;
|
||||||
unsigned int wavePtr[256];
|
std::vector<unsigned int> wavePtr;
|
||||||
unsigned int samplePtr[256];
|
std::vector<unsigned int> samplePtr;
|
||||||
unsigned int subSongPtr[256];
|
unsigned int subSongPtr[256];
|
||||||
unsigned int sysFlagsPtr[DIV_MAX_CHIPS];
|
unsigned int sysFlagsPtr[DIV_MAX_CHIPS];
|
||||||
unsigned int assetDirPtr[3];
|
unsigned int assetDirPtr[3];
|
||||||
|
@ -934,13 +934,13 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.waveLen<0 || ds.waveLen>256) {
|
if (ds.waveLen<0 || ds.waveLen>32768) {
|
||||||
logE("invalid wavetable count!");
|
logE("invalid wavetable count!");
|
||||||
lastError="invalid wavetable count!";
|
lastError="invalid wavetable count!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ds.sampleLen<0 || ds.sampleLen>256) {
|
if (ds.sampleLen<0 || ds.sampleLen>32768) {
|
||||||
logE("invalid sample count!");
|
logE("invalid sample count!");
|
||||||
lastError="invalid sample count!";
|
lastError="invalid sample count!";
|
||||||
delete[] file;
|
delete[] file;
|
||||||
|
@ -1142,14 +1142,17 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// pointers
|
// pointers
|
||||||
|
insPtr.reserve(ds.insLen);
|
||||||
for (int i=0; i<ds.insLen; i++) {
|
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++) {
|
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++) {
|
for (int i=0; i<ds.sampleLen; i++) {
|
||||||
samplePtr[i]=reader.readI();
|
samplePtr.push_back(reader.readI());
|
||||||
}
|
}
|
||||||
patPtr.reserve(numberOfPats);
|
patPtr.reserve(numberOfPats);
|
||||||
for (int i=0; i<numberOfPats; i++) patPtr.push_back(reader.readI());
|
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();
|
saveLock.unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (song.wave.size()>256) {
|
if (song.wave.size()>32768) {
|
||||||
logE("maximum number of wavetables is 256!");
|
logE("maximum number of wavetables is 32768!");
|
||||||
lastError="maximum number of wavetables is 256";
|
lastError="maximum number of wavetables is 32768";
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (song.sample.size()>256) {
|
if (song.sample.size()>32768) {
|
||||||
logE("maximum number of samples is 256!");
|
logE("maximum number of samples is 32768!");
|
||||||
lastError="maximum number of samples is 256";
|
lastError="maximum number of samples is 32768";
|
||||||
saveLock.unlock();
|
saveLock.unlock();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1334,7 +1334,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
ds.sampleLen=ds.sample.size();
|
ds.sampleLen=ds.sample.size();
|
||||||
if (ds.sampleLen>256) {
|
if (ds.sampleLen>32768) {
|
||||||
logE("too many samples!");
|
logE("too many samples!");
|
||||||
lastError="too many samples";
|
lastError="too many samples";
|
||||||
ds.unload();
|
ds.unload();
|
||||||
|
|
|
@ -858,9 +858,11 @@ void DivInstrument::writeFeatureWS(SafeWriter* w) {
|
||||||
FEATURE_END;
|
FEATURE_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DivInstrument::writeFeatureSL(SafeWriter* w, std::vector<int>& list, const DivSong* song) {
|
size_t DivInstrument::writeFeatureLS(SafeWriter* w, std::vector<int>& list, const DivSong* song) {
|
||||||
bool sampleUsed[256];
|
if (song==NULL) return 0;
|
||||||
memset(sampleUsed,0,256*sizeof(bool));
|
|
||||||
|
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()) {
|
if (amiga.initSample>=0 && amiga.initSample<(int)song->sample.size()) {
|
||||||
sampleUsed[amiga.initSample]=true;
|
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;
|
if (list.empty()) return 0;
|
||||||
|
|
||||||
FEATURE_BEGIN("SL");
|
FEATURE_BEGIN("SL");
|
||||||
|
|
||||||
w->writeC(list.size());
|
w->writeS(list.size());
|
||||||
|
|
||||||
for (int i: list) {
|
for (int i: list) {
|
||||||
w->writeC(i);
|
w->writeS(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ret=w->tell();
|
size_t ret=w->tell();
|
||||||
|
@ -902,9 +906,11 @@ size_t DivInstrument::writeFeatureSL(SafeWriter* w, std::vector<int>& list, cons
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t DivInstrument::writeFeatureWL(SafeWriter* w, std::vector<int>& list, const DivSong* song) {
|
size_t DivInstrument::writeFeatureLW(SafeWriter* w, std::vector<int>& list, const DivSong* song) {
|
||||||
bool waveUsed[256];
|
if (song==NULL) return 0;
|
||||||
memset(waveUsed,0,256*sizeof(bool));
|
|
||||||
|
bool* waveUsed=new bool[song->wave.size()];
|
||||||
|
memset(waveUsed,0,song->wave.size()*sizeof(bool));
|
||||||
|
|
||||||
for (int i=0; i<std.waveMacro.len; i++) {
|
for (int i=0; i<std.waveMacro.len; i++) {
|
||||||
if (std.waveMacro.val[i]>=0 && std.waveMacro.val[i]<(int)song->wave.size()) {
|
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");
|
FEATURE_BEGIN("WL");
|
||||||
|
|
||||||
w->writeC(list.size());
|
w->writeS(list.size());
|
||||||
|
|
||||||
for (int i: list) {
|
for (int i: list) {
|
||||||
w->writeC(i);
|
w->writeS(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ret=w->tell();
|
size_t ret=w->tell();
|
||||||
|
@ -1621,10 +1627,10 @@ void DivInstrument::putInsData2(SafeWriter* w, bool fui, const DivSong* song, bo
|
||||||
writeFeatureWS(w);
|
writeFeatureWS(w);
|
||||||
}
|
}
|
||||||
if (featureSL) {
|
if (featureSL) {
|
||||||
slSeek=writeFeatureSL(w,sampleList,song);
|
slSeek=writeFeatureLS(w,sampleList,song);
|
||||||
}
|
}
|
||||||
if (featureWL) {
|
if (featureWL) {
|
||||||
wlSeek=writeFeatureWL(w,waveList,song);
|
wlSeek=writeFeatureLW(w,waveList,song);
|
||||||
}
|
}
|
||||||
if (featureMP) {
|
if (featureMP) {
|
||||||
writeFeatureMP(w);
|
writeFeatureMP(w);
|
||||||
|
@ -2275,17 +2281,17 @@ void DivInstrument::readFeatureWS(SafeReader& reader, short version) {
|
||||||
void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short version) {
|
void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short version) {
|
||||||
READ_FEAT_BEGIN;
|
READ_FEAT_BEGIN;
|
||||||
|
|
||||||
unsigned int samplePtr[256];
|
unsigned int* samplePtr=new unsigned int[32768];
|
||||||
unsigned char sampleIndex[256];
|
unsigned short* sampleIndex=new unsigned short[65536];
|
||||||
unsigned char sampleRemap[256];
|
unsigned short* sampleRemap=new unsigned short[65536];
|
||||||
memset(samplePtr,0,256*sizeof(unsigned int));
|
memset(samplePtr,0,32768*sizeof(unsigned int));
|
||||||
memset(sampleIndex,0,256);
|
memset(sampleIndex,0,65536*sizeof(unsigned short));
|
||||||
memset(sampleRemap,0,256);
|
memset(sampleRemap,0,65536*sizeof(unsigned short));
|
||||||
|
|
||||||
unsigned char sampleCount=reader.readC();
|
unsigned char sampleCount=reader.readC();
|
||||||
|
|
||||||
for (int i=0; i<sampleCount; i++) {
|
for (int i=0; i<sampleCount; i++) {
|
||||||
sampleIndex[i]=reader.readC();
|
sampleIndex[i]=(unsigned char)reader.readC();
|
||||||
}
|
}
|
||||||
for (int i=0; i<sampleCount; i++) {
|
for (int i=0; i<sampleCount; i++) {
|
||||||
samplePtr[i]=reader.readI();
|
samplePtr[i]=reader.readI();
|
||||||
|
@ -2296,7 +2302,7 @@ void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short versi
|
||||||
// load samples
|
// load samples
|
||||||
for (int i=0; i<sampleCount; i++) {
|
for (int i=0; i<sampleCount; i++) {
|
||||||
reader.seek(samplePtr[i],SEEK_SET);
|
reader.seek(samplePtr[i],SEEK_SET);
|
||||||
if (song->sample.size()>=256) {
|
if (song->sample.size()>=32768) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DivSample* sample=new DivSample;
|
DivSample* sample=new DivSample;
|
||||||
|
@ -2316,35 +2322,39 @@ void DivInstrument::readFeatureSL(SafeReader& reader, DivSong* song, short versi
|
||||||
reader.seek(lastSeek,SEEK_SET);
|
reader.seek(lastSeek,SEEK_SET);
|
||||||
|
|
||||||
// re-map samples
|
// re-map samples
|
||||||
if (amiga.initSample>=0 && amiga.initSample<256) {
|
if (amiga.initSample>=0) {
|
||||||
amiga.initSample=sampleRemap[amiga.initSample];
|
amiga.initSample=sampleRemap[amiga.initSample];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amiga.useNoteMap) {
|
if (amiga.useNoteMap) {
|
||||||
for (int i=0; i<120; i++) {
|
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];
|
amiga.noteMap[i].map=sampleRemap[amiga.noteMap[i].map];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] samplePtr;
|
||||||
|
delete[] sampleIndex;
|
||||||
|
delete[] sampleRemap;
|
||||||
|
|
||||||
READ_FEAT_END;
|
READ_FEAT_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short version) {
|
void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short version) {
|
||||||
READ_FEAT_BEGIN;
|
READ_FEAT_BEGIN;
|
||||||
|
|
||||||
unsigned int wavePtr[256];
|
unsigned int* wavePtr=new unsigned int[32768];
|
||||||
unsigned char waveIndex[256];
|
unsigned short* waveIndex=new unsigned short[65536];
|
||||||
unsigned char waveRemap[256];
|
unsigned short* waveRemap=new unsigned short[65536];
|
||||||
memset(wavePtr,0,256*sizeof(unsigned int));
|
memset(wavePtr,0,32768*sizeof(unsigned int));
|
||||||
memset(waveIndex,0,256);
|
memset(waveIndex,0,65536*sizeof(unsigned short));
|
||||||
memset(waveRemap,0,256);
|
memset(waveRemap,0,65536*sizeof(unsigned short));
|
||||||
|
|
||||||
unsigned char waveCount=reader.readC();
|
unsigned char waveCount=reader.readC();
|
||||||
|
|
||||||
for (int i=0; i<waveCount; i++) {
|
for (int i=0; i<waveCount; i++) {
|
||||||
waveIndex[i]=reader.readC();
|
waveIndex[i]=(unsigned char)reader.readC();
|
||||||
}
|
}
|
||||||
for (int i=0; i<waveCount; i++) {
|
for (int i=0; i<waveCount; i++) {
|
||||||
wavePtr[i]=reader.readI();
|
wavePtr[i]=reader.readI();
|
||||||
|
@ -2355,7 +2365,7 @@ void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short versi
|
||||||
// load wavetables
|
// load wavetables
|
||||||
for (int i=0; i<waveCount; i++) {
|
for (int i=0; i<waveCount; i++) {
|
||||||
reader.seek(wavePtr[i],SEEK_SET);
|
reader.seek(wavePtr[i],SEEK_SET);
|
||||||
if (song->wave.size()>=256) {
|
if (song->wave.size()>=32768) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DivWavetable* wave=new DivWavetable;
|
DivWavetable* wave=new DivWavetable;
|
||||||
|
@ -2376,16 +2386,164 @@ void DivInstrument::readFeatureWL(SafeReader& reader, DivSong* song, short versi
|
||||||
|
|
||||||
// re-map wavetables
|
// re-map wavetables
|
||||||
if (ws.enabled) {
|
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.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++) {
|
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;
|
READ_FEAT_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2647,10 +2805,14 @@ DivDataErrors DivInstrument::readInsDataNew(SafeReader& reader, short version, b
|
||||||
readFeatureFD(reader,version);
|
readFeatureFD(reader,version);
|
||||||
} else if (memcmp(featCode,"WS",2)==0) { // WaveSynth
|
} else if (memcmp(featCode,"WS",2)==0) { // WaveSynth
|
||||||
readFeatureWS(reader,version);
|
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);
|
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);
|
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
|
} else if (memcmp(featCode,"MP",2)==0) { // MultiPCM
|
||||||
readFeatureMP(reader,version);
|
readFeatureMP(reader,version);
|
||||||
} else if (memcmp(featCode,"SU",2)==0) { // Sound Unit
|
} else if (memcmp(featCode,"SU",2)==0) { // Sound Unit
|
||||||
|
|
|
@ -1097,8 +1097,8 @@ struct DivInstrument : DivInstrumentPOD {
|
||||||
void writeFeatureN1(SafeWriter* w);
|
void writeFeatureN1(SafeWriter* w);
|
||||||
void writeFeatureFD(SafeWriter* w);
|
void writeFeatureFD(SafeWriter* w);
|
||||||
void writeFeatureWS(SafeWriter* w);
|
void writeFeatureWS(SafeWriter* w);
|
||||||
size_t writeFeatureSL(SafeWriter* w, std::vector<int>& list, const DivSong* song);
|
size_t writeFeatureLS(SafeWriter* w, std::vector<int>& list, const DivSong* song);
|
||||||
size_t writeFeatureWL(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 writeFeatureMP(SafeWriter* w);
|
||||||
void writeFeatureSU(SafeWriter* w);
|
void writeFeatureSU(SafeWriter* w);
|
||||||
void writeFeatureES(SafeWriter* w);
|
void writeFeatureES(SafeWriter* w);
|
||||||
|
@ -1123,6 +1123,8 @@ struct DivInstrument : DivInstrumentPOD {
|
||||||
void readFeatureWS(SafeReader& reader, short version);
|
void readFeatureWS(SafeReader& reader, short version);
|
||||||
void readFeatureSL(SafeReader& reader, DivSong* song, short version);
|
void readFeatureSL(SafeReader& reader, DivSong* song, short version);
|
||||||
void readFeatureWL(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 readFeatureMP(SafeReader& reader, short version);
|
||||||
void readFeatureSU(SafeReader& reader, short version);
|
void readFeatureSU(SafeReader& reader, short version);
|
||||||
void readFeatureES(SafeReader& reader, short version);
|
void readFeatureES(SafeReader& reader, short version);
|
||||||
|
|
|
@ -764,8 +764,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
pendingFreq[streamID]=write.val;
|
pendingFreq[streamID]=write.val;
|
||||||
} else {
|
} else {
|
||||||
DivSample* sample=song.sample[write.val];
|
DivSample* sample=song.sample[write.val];
|
||||||
int pos=sampleOff8[write.val&0xff]+setPos[streamID];
|
int pos=sampleOff8[write.val&0x7fff]+setPos[streamID];
|
||||||
int len=(int)sampleLen8[write.val&0xff]-setPos[streamID];
|
int len=(int)sampleLen8[write.val&0x7fff]-setPos[streamID];
|
||||||
|
|
||||||
if (len<0) len=0;
|
if (len<0) len=0;
|
||||||
|
|
||||||
|
@ -807,8 +807,8 @@ void DivEngine::performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write
|
||||||
loopFreq[streamID]=realFreq;
|
loopFreq[streamID]=realFreq;
|
||||||
if (pendingFreq[streamID]!=-1) {
|
if (pendingFreq[streamID]!=-1) {
|
||||||
DivSample* sample=song.sample[pendingFreq[streamID]];
|
DivSample* sample=song.sample[pendingFreq[streamID]];
|
||||||
int pos=sampleOff8[pendingFreq[streamID]&0xff]+setPos[streamID];
|
int pos=sampleOff8[pendingFreq[streamID]&0x7fff]+setPos[streamID];
|
||||||
int len=(int)sampleLen8[pendingFreq[streamID]&0xff]-setPos[streamID];
|
int len=(int)sampleLen8[pendingFreq[streamID]&0x7fff]-setPos[streamID];
|
||||||
|
|
||||||
if (len<0) len=0;
|
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) {
|
if (playingSample[streamID]!=-1 && pendingFreq[streamID]==-1) {
|
||||||
// play the sample again
|
// play the sample again
|
||||||
DivSample* sample=song.sample[playingSample[streamID]];
|
DivSample* sample=song.sample[playingSample[streamID]];
|
||||||
int pos=sampleOff8[playingSample[streamID]&0xff]+setPos[streamID];
|
int pos=sampleOff8[playingSample[streamID]&0x7fff]+setPos[streamID];
|
||||||
int len=(int)sampleLen8[playingSample[streamID]&0xff]-setPos[streamID];
|
int len=(int)sampleLen8[playingSample[streamID]&0x7fff]-setPos[streamID];
|
||||||
|
|
||||||
if (len<0) len=0;
|
if (len<0) len=0;
|
||||||
|
|
||||||
|
@ -1329,9 +1329,9 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
int loopTickSong=-1;
|
int loopTickSong=-1;
|
||||||
int songTick=0;
|
int songTick=0;
|
||||||
|
|
||||||
unsigned int sampleOff8[256];
|
unsigned int* sampleOff8=new unsigned int[32768];
|
||||||
unsigned int sampleLen8[256];
|
unsigned int* sampleLen8=new unsigned int[32768];
|
||||||
unsigned int sampleOffSegaPCM[256];
|
unsigned int* sampleOffSegaPCM=new unsigned int[32768];
|
||||||
|
|
||||||
SafeWriter* w=new SafeWriter;
|
SafeWriter* w=new SafeWriter;
|
||||||
w->init();
|
w->init();
|
||||||
|
@ -2202,9 +2202,9 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
||||||
unsigned int songOff=w->tell();
|
unsigned int songOff=w->tell();
|
||||||
|
|
||||||
// initialize sample offsets
|
// initialize sample offsets
|
||||||
memset(sampleOff8,0,256*sizeof(unsigned int));
|
memset(sampleOff8,0,32768*sizeof(unsigned int));
|
||||||
memset(sampleLen8,0,256*sizeof(unsigned int));
|
memset(sampleLen8,0,32768*sizeof(unsigned int));
|
||||||
memset(sampleOffSegaPCM,0,256*sizeof(unsigned int));
|
memset(sampleOffSegaPCM,0,32768*sizeof(unsigned int));
|
||||||
|
|
||||||
// write samples
|
// write samples
|
||||||
unsigned int sampleSeek=0;
|
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);
|
logI("%d register writes total.",writeCount);
|
||||||
|
|
||||||
|
delete[] sampleOff8;
|
||||||
|
delete[] sampleLen8;
|
||||||
|
delete[] sampleOffSegaPCM;
|
||||||
|
|
||||||
BUSY_END;
|
BUSY_END;
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue