Save the size of each block in a Furnace module

This commit is contained in:
Ian Karlsson 2022-05-27 21:40:26 +02:00
parent f61a114637
commit 5378974b96
4 changed files with 47 additions and 7 deletions

View file

@ -130,7 +130,7 @@ size | description
size | description size | description
-----|------------------------------------ -----|------------------------------------
4 | "INFO" block ID 4 | "INFO" block ID
4 | reserved 4 | size of the block excluding the ID and this field
1 | time base (of first song) 1 | time base (of first song)
1 | speed 1 (of first song) 1 | speed 1 (of first song)
1 | speed 2 (of first song) 1 | speed 2 (of first song)
@ -332,7 +332,7 @@ the way it's currently done is really weird, but it provides for some backwards
size | description size | description
-----|------------------------------------ -----|------------------------------------
4 | "SONG" block ID 4 | "SONG" block ID
4 | reserved 4 | size of the block excluding the ID and this field
1 | time base 1 | time base
1 | speed 1 1 | speed 1
1 | speed 2 1 | speed 2
@ -386,7 +386,7 @@ notes:
size | description size | description
-----|------------------------------------ -----|------------------------------------
4 | "INST" block ID 4 | "INST" block ID
4 | reserved 4 | size of the block excluding the ID and this field
2 | format version (see header) 2 | format version (see header)
1 | instrument type 1 | instrument type
| - 0: standard | - 0: standard
@ -795,7 +795,7 @@ size | description
size | description size | description
-----|------------------------------------ -----|------------------------------------
4 | "WAVE" block ID 4 | "WAVE" block ID
4 | reserved 4 | size of the block excluding the ID and this field
STR | wavetable name STR | wavetable name
4 | wavetable size 4 | wavetable size
4 | wavetable min 4 | wavetable min
@ -809,7 +809,7 @@ size | description
size | description size | description
-----|------------------------------------ -----|------------------------------------
4 | "SMPL" block ID 4 | "SMPL" block ID
4 | reserved 4 | size of the block excluding the ID and this field
STR | sample name STR | sample name
4 | length 4 | length
4 | rate 4 | rate
@ -841,7 +841,7 @@ size | description
size | description size | description
-----|------------------------------------ -----|------------------------------------
4 | "PATR" block ID 4 | "PATR" block ID
4 | reserved 4 | size of the block excluding the ID and this field
2 | channel 2 | channel
2 | pattern index 2 | pattern index
2 | subsong (>=95) or reserved 2 | subsong (>=95) or reserved

View file

@ -2696,7 +2696,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
std::vector<int> wavePtr; std::vector<int> wavePtr;
std::vector<int> samplePtr; std::vector<int> samplePtr;
std::vector<int> patPtr; std::vector<int> patPtr;
size_t ptrSeek, subSongPtrSeek; size_t ptrSeek, subSongPtrSeek, blockStartSeek, blockEndSeek;
size_t subSongIndex=0; size_t subSongIndex=0;
DivSubSong* subSong=song.subsong[subSongIndex]; DivSubSong* subSong=song.subsong[subSongIndex];
warnings=""; warnings="";
@ -2775,6 +2775,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
/// SONG INFO /// SONG INFO
w->write("INFO",4); w->write("INFO",4);
blockStartSeek=w->tell();
w->writeI(0); w->writeI(0);
w->writeC(subSong->timeBase); w->writeC(subSong->timeBase);
@ -2932,11 +2933,17 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
w->writeI(0); w->writeI(0);
} }
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
/// SUBSONGS /// SUBSONGS
for (subSongIndex=1; subSongIndex<song.subsong.size(); subSongIndex++) { for (subSongIndex=1; subSongIndex<song.subsong.size(); subSongIndex++) {
subSong=song.subsong[subSongIndex]; subSong=song.subsong[subSongIndex];
subSongPtr.push_back(w->tell()); subSongPtr.push_back(w->tell());
w->write("SONG",4); w->write("SONG",4);
blockStartSeek=w->tell();
w->writeI(0); w->writeI(0);
w->writeC(subSong->timeBase); w->writeC(subSong->timeBase);
@ -2979,6 +2986,11 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
for (int i=0; i<chans; i++) { for (int i=0; i<chans; i++) {
w->writeString(subSong->chanShortName[i],false); w->writeString(subSong->chanShortName[i],false);
} }
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
} }
/// INSTRUMENT /// INSTRUMENT
@ -3000,6 +3012,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
DivSample* sample=song.sample[i]; DivSample* sample=song.sample[i];
samplePtr.push_back(w->tell()); samplePtr.push_back(w->tell());
w->write("SMPL",4); w->write("SMPL",4);
blockStartSeek=w->tell();
w->writeI(0); w->writeI(0);
w->writeString(sample->name,false); w->writeString(sample->name,false);
@ -3012,6 +3025,11 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
w->writeI(sample->loopStart); w->writeI(sample->loopStart);
w->write(sample->getCurBuf(),sample->getCurBufLen()); w->write(sample->getCurBuf(),sample->getCurBufLen());
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
} }
/// PATTERN /// PATTERN
@ -3019,6 +3037,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
DivPattern* pat=song.subsong[i.subsong]->pat[i.chan].getPattern(i.pat,false); DivPattern* pat=song.subsong[i.subsong]->pat[i.chan].getPattern(i.pat,false);
patPtr.push_back(w->tell()); patPtr.push_back(w->tell());
w->write("PATR",4); w->write("PATR",4);
blockStartSeek=w->tell();
w->writeI(0); w->writeI(0);
w->writeS(i.chan); w->writeS(i.chan);
@ -3036,6 +3055,11 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
} }
w->writeString(pat->name,false); w->writeString(pat->name,false);
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
} }
/// POINTERS /// POINTERS

View file

@ -24,7 +24,10 @@
#include "../fileutils.h" #include "../fileutils.h"
void DivInstrument::putInsData(SafeWriter* w) { void DivInstrument::putInsData(SafeWriter* w) {
size_t blockStartSeek, blockEndSeek;
w->write("INST",4); w->write("INST",4);
blockStartSeek=w->tell();
w->writeI(0); w->writeI(0);
w->writeS(DIV_ENGINE_VERSION); w->writeS(DIV_ENGINE_VERSION);
@ -520,6 +523,11 @@ void DivInstrument::putInsData(SafeWriter* w) {
for (int j=0; j<23; j++) { // reserved for (int j=0; j<23; j++) { // reserved
w->writeC(0); w->writeC(0);
} }
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
} }
DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {

View file

@ -24,7 +24,10 @@
#include "../fileutils.h" #include "../fileutils.h"
void DivWavetable::putWaveData(SafeWriter* w) { void DivWavetable::putWaveData(SafeWriter* w) {
size_t blockStartSeek, blockEndSeek;
w->write("WAVE",4); w->write("WAVE",4);
blockStartSeek=w->tell();
w->writeI(0); w->writeI(0);
w->writeC(0); // name w->writeC(0); // name
@ -34,6 +37,11 @@ void DivWavetable::putWaveData(SafeWriter* w) {
for (int j=0; j<len; j++) { for (int j=0; j<len; j++) {
w->writeI(data[j]); w->writeI(data[j]);
} }
blockEndSeek=w->tell();
w->seek(blockStartSeek,SEEK_SET);
w->writeI(blockEndSeek-blockStartSeek-4);
w->seek(0,SEEK_END);
} }
DivDataErrors DivWavetable::readWaveData(SafeReader& reader, short version) { DivDataErrors DivWavetable::readWaveData(SafeReader& reader, short version) {