Skip to content

Commit 5be1e7a

Browse files
committed
Refactor instrument loading
1 parent c580ff3 commit 5be1e7a

File tree

5 files changed

+66
-39
lines changed

5 files changed

+66
-39
lines changed

Source/FamiTrackerDoc.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -1812,7 +1812,7 @@ void CFamiTrackerDoc::ReadBlock_Parameters(CDocumentFile *pDocFile, const int Ve
18121812
switch (m_iPlaybackRateType) {
18131813
case 1:
18141814
// workaround for now
1815-
m_iEngineSpeed = static_cast<int>(1000000. / m_iPlaybackRate + .5);
1815+
m_iEngineSpeed = static_cast<unsigned int>(1000000. / m_iPlaybackRate + .5);
18161816
break;
18171817
case 0: case 2:
18181818
default:
@@ -1949,7 +1949,9 @@ void CFamiTrackerDoc::ReadBlock_Header(CDocumentFile *pDocFile, const int Versio
19491949
for (unsigned int i = 0; i < m_iTrackCount; ++i) {
19501950
int First = static_cast<unsigned char>(pDocFile->GetBlockChar());
19511951
int Second = static_cast<unsigned char>(pDocFile->GetBlockChar());
1952-
if (!i) {
1952+
1953+
// we don't have per-track row highlights yet, just use the first track
1954+
if (i == 0) {
19531955
m_vHighlight.First = First;
19541956
m_vHighlight.Second = Second;
19551957
}

Source/Instrument2A03.cpp

+33-27
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void CInstrument2A03::Store(CDocumentFile *pDocFile)
6767
{
6868
CSeqInstrument::Store(pDocFile); // // //
6969

70-
int Version = 6;
70+
int Version = pDocFile->GetBlockVersion();
7171
int Octaves = Version >= 2 ? OCTAVE_RANGE : 6;
7272

7373
if (Version >= 7) // // // 050B
@@ -76,7 +76,7 @@ void CInstrument2A03::Store(CDocumentFile *pDocFile)
7676
for (int j = 0; j < NOTE_RANGE; ++j) {
7777
if (Version >= 7) { // // // 050B
7878
if (!GetSampleIndex(i, j)) continue;
79-
pDocFile->WriteBlockChar(i * NOTE_RANGE + j);
79+
pDocFile->WriteBlockChar(MIDI_NOTE(i, j)+1);
8080
}
8181
pDocFile->WriteBlockChar(GetSampleIndex(i, j));
8282
pDocFile->WriteBlockChar(GetSamplePitch(i, j));
@@ -95,11 +95,12 @@ bool CInstrument2A03::Load(CDocumentFile *pDocFile)
9595

9696
const auto ReadAssignment = [&] (int Octave, int Note) {
9797
try {
98-
int Index = CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(
98+
char Sample = CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(
9999
pDocFile->GetBlockChar(), 0, MAX_DSAMPLES, "DPCM sample assignment index", "%i");
100-
if (Index > MAX_DSAMPLES)
101-
Index = 0;
102-
SetSampleIndex(Octave, Note, Index);
100+
if (Sample > MAX_DSAMPLES)
101+
Sample = 0;
102+
103+
SetSampleIndex(Octave, Note, Sample);
103104
char Pitch = pDocFile->GetBlockChar();
104105
CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(Pitch & 0x7F, 0, 0xF, "DPCM sample pitch", "%i");
105106
SetSamplePitch(Octave, Note, Pitch & 0x8F);
@@ -122,7 +123,7 @@ bool CInstrument2A03::Load(CDocumentFile *pDocFile)
122123
for (int i = 0; i < Count; ++i) {
123124
int Note = CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(
124125
pDocFile->GetBlockChar(), 0, NOTE_COUNT - 1, "DPCM sample assignment note index", "%i");
125-
ReadAssignment(GET_OCTAVE(Note), GET_NOTE(Note) - 1);
126+
ReadAssignment(GET_OCTAVE(Note - 1), GET_NOTE(Note - 1));
126127
}
127128
}
128129
else
@@ -155,10 +156,10 @@ void CInstrument2A03::SaveFile(CInstrumentFile *pFile)
155156
memset(UsedSamples, 0, sizeof(bool) * MAX_DSAMPLES);
156157

157158
int UsedCount = 0;
158-
for (int i = 0; i < OCTAVE_RANGE; ++i) { // octaves
159-
for (int j = 0; j < NOTE_RANGE; ++j) { // notes
159+
for (int i = 0; i < OCTAVE_RANGE; ++i) {
160+
for (int j = 0; j < NOTE_RANGE; ++j) {
160161
if (unsigned char Sample = GetSampleIndex(i, j)) {
161-
unsigned char Index = i * NOTE_RANGE + j;
162+
unsigned char Index = MIDI_NOTE(i, j) + 1;
162163
pFile->WriteChar(Index);
163164
pFile->WriteChar(Sample);
164165
pFile->WriteChar(GetSamplePitch(i, j));
@@ -189,28 +190,28 @@ void CInstrument2A03::SaveFile(CInstrumentFile *pFile)
189190

190191
bool CInstrument2A03::LoadFile(CInstrumentFile *pFile, int iVersion)
191192
{
192-
char SampleNames[MAX_DSAMPLES][256];
193-
194193
if (!CSeqInstrument::LoadFile(pFile, iVersion)) // // //
195194
return false;
196195

197-
unsigned int Count;
198-
pFile->Read(&Count, sizeof(int));
199-
CModuleException::AssertRangeFmt(Count, 0U, static_cast<unsigned>(NOTE_COUNT), "DPCM assignment count", "%u");
196+
unsigned int Count = CModuleException::AssertRangeFmt(pFile->ReadInt(), 0U, static_cast<unsigned>(NOTE_COUNT), "DPCM assignment count", "%u");
200197

201198
// DPCM instruments
202199
for (unsigned int i = 0; i < Count; ++i) {
203-
unsigned char InstNote = pFile->ReadChar();
204-
int Octave = InstNote / NOTE_RANGE;
205-
int Note = InstNote % NOTE_RANGE;
200+
unsigned char InstNote = CModuleException::AssertRangeFmt(
201+
pFile->ReadChar(), 0, NOTE_COUNT - 1, "DPCM sample assignment note index", "%i");
202+
int Octave = GET_OCTAVE(InstNote - 1);
203+
int Note = GET_NOTE(InstNote - 1);
206204
try {
207-
unsigned char Sample = CModuleException::AssertRangeFmt(pFile->ReadChar(), 0U, 0x7FU, "DPCM sample assignment index", "%u");
205+
char Sample = CModuleException::AssertRangeFmt(pFile->ReadChar(), 0, MAX_DSAMPLES, "DPCM sample assignment index", "%u");
208206
if (Sample > MAX_DSAMPLES)
209207
Sample = 0;
210-
unsigned char Pitch = pFile->ReadChar();
211-
CModuleException::AssertRangeFmt(Pitch & 0x7FU, 0U, 0xFU, "DPCM sample pitch", "%u");
212-
SetSamplePitch(Octave, Note, Pitch);
213208
SetSampleIndex(Octave, Note, Sample);
209+
210+
char Pitch = pFile->ReadChar();
211+
CModuleException::AssertRangeFmt(Pitch & 0x7F, 0, 0xF, "DPCM sample pitch", "%i");
212+
213+
SetSamplePitch(Octave, Note, Pitch);
214+
214215
SetSampleDeltaValue(Octave, Note, CModuleException::AssertRangeFmt(
215216
static_cast<char>(iVersion >= 24 ? pFile->ReadChar() : -1), -1, 0x7F, "DPCM sample delta value", "%i"));
216217
}
@@ -229,20 +230,24 @@ bool CInstrument2A03::LoadFile(CInstrumentFile *pFile, int iVersion)
229230

230231
unsigned int SampleCount = pFile->ReadInt();
231232
for (unsigned int i = 0; i < SampleCount; ++i) {
233+
232234
int Index = CModuleException::AssertRangeFmt(
233235
pFile->ReadInt(), 0U, static_cast<unsigned>(MAX_DSAMPLES - 1), "DPCM sample index", "%u");
236+
234237
int Len = CModuleException::AssertRangeFmt(
235238
pFile->ReadInt(), 0U, static_cast<unsigned>(CDSample::MAX_NAME_SIZE - 1), "DPCM sample name length", "%u");
236-
pFile->Read(SampleNames[Index], Len);
237-
SampleNames[Index][Len] = 0;
239+
240+
char SampleName[256]{};
241+
pFile->Read(SampleName, Len);
242+
238243
int Size = pFile->ReadInt();
239244
char *SampleData = new char[Size];
240245
pFile->Read(SampleData, Size);
241246
bool Found = false;
242247
for (int j = 0; j < MAX_DSAMPLES; ++j) if (const CDSample *pSample = m_pInstManager->GetDSample(j)) { // // //
243248
// Compare size and name to see if identical sample exists
244249
if (pSample->GetSize() == Size && !memcmp(pSample->GetData(), SampleData, Size) && // // //
245-
!strcmp(pSample->GetName(), SampleNames[Index])) {
250+
!strcmp(pSample->GetName(), SampleName)) {
246251
Found = true;
247252
// Assign sample
248253
for (int o = 0; o < OCTAVE_RANGE; ++o) {
@@ -270,9 +275,9 @@ bool CInstrument2A03::LoadFile(CInstrumentFile *pFile, int iVersion)
270275
e->Raise();
271276
}
272277
CDSample *pSample = new CDSample(); // // //
273-
pSample->SetName(SampleNames[Index]);
278+
pSample->SetName(SampleName);
274279
pSample->SetData(Size, SampleData);
275-
int FreeSample = m_pInstManager->AddDSample(pSample);
280+
int FreeSample = m_pInstManager->AddDSample(pSample); // not off-by-one
276281
if (FreeSample == -1) {
277282
SAFE_RELEASE(pSample);
278283
CModuleException *e = new CModuleException();
@@ -332,6 +337,7 @@ char CInstrument2A03::GetSampleDeltaValue(int Octave, int Note) const
332337

333338
void CInstrument2A03::SetSampleIndex(int Octave, int Note, char Sample)
334339
{
340+
// Sample is off by one; 0 means there is no index assigned to a note
335341
m_cSamples[Octave][Note] = Sample;
336342
InstrumentChanged();
337343
}

Source/InstrumentFDS.cpp

+25-7
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ void CInstrumentFDS::Store(CDocumentFile *pDocFile)
193193

194194
bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
195195
{
196+
const int Version = pDocFile->GetBlockVersion();
196197
for (int i = 0; i < WAVE_SIZE; ++i) {
197198
SetSample(i, pDocFile->GetBlockChar());
198199
}
@@ -205,8 +206,25 @@ bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
205206
SetModulationDepth(pDocFile->GetBlockInt());
206207
SetModulationDelay(pDocFile->GetBlockInt());
207208

208-
// hack to fix earlier saved files (remove this eventually)
209+
for (int i = 0; i < SEQUENCE_COUNT; ++i) {
210+
if (Version > 2)
211+
SetSequence(i, LoadSequence(pDocFile));
212+
else
213+
if (i < SEQ_PITCH)
214+
// version 2 apparently does not have Pitch sequences
215+
SetSequence(i, LoadSequence(pDocFile));
216+
}
217+
218+
// Older files was 0-15, new is 0-31
219+
if (Version <= 3) DoubleVolume();
220+
221+
return true;
222+
223+
// ancient code preserved for analysis
224+
209225
/*
226+
// hack to fix earlier saved files (remove this eventually)
227+
210228
if (pDocFile->GetBlockVersion() > 2) {
211229
LoadSequence(pDocFile, GetSequence(SEQ_VOLUME));
212230
LoadSequence(pDocFile, GetSequence(SEQ_ARPEGGIO));
@@ -215,10 +233,14 @@ bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
215233
}
216234
else {
217235
*/
236+
237+
/*
238+
TODO: investigate Instrument block v2 and FDS
239+
- perhaps an release interstice bug fix?
240+
218241
unsigned int a = pDocFile->GetBlockInt();
219242
unsigned int b = pDocFile->GetBlockInt();
220243
221-
// TODO: investigate why loading FDS instruments uses RollbackPointer()
222244
pDocFile->RollbackPointer(8);
223245
224246
if (a < 256 && (b & 0xFF) != 0x00) {
@@ -234,13 +256,9 @@ bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
234256
if (pDocFile->GetBlockVersion() > 2)
235257
SetSequence(SEQ_PITCH, LoadSequence(pDocFile));
236258
}
259+
*/
237260

238261
// }
239-
240-
// Older files was 0-15, new is 0-31
241-
if (pDocFile->GetBlockVersion() <= 3) DoubleVolume();
242-
243-
return true;
244262
}
245263

246264
void CInstrumentFDS::SaveFile(CInstrumentFile *pFile)

Source/InstrumentN163.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ void CInstrumentN163::Store(CDocumentFile *pDocFile)
7878
// Store wave
7979
pDocFile->WriteBlockInt(m_iWaveSize);
8080
pDocFile->WriteBlockInt(m_iWavePos);
81-
//pDocFile->WriteBlockInt(m_bAutoWavePos ? 1 : 0);
81+
// if (pDocFile->GetBlockVersion() >= 8) // // // 050B
82+
// pDocFile->WriteBlockInt(m_bAutoWavePos ? 1 : 0);
8283
pDocFile->WriteBlockInt(m_iWaveCount);
8384

8485
for (int i = 0; i < m_iWaveCount; ++i) {
@@ -95,7 +96,7 @@ bool CInstrumentN163::Load(CDocumentFile *pDocFile)
9596
m_iWaveSize = CModuleException::AssertRangeFmt(pDocFile->GetBlockInt(), 4, MAX_WAVE_SIZE, "N163 wave size", "%i");
9697
m_iWavePos = CModuleException::AssertRangeFmt(pDocFile->GetBlockInt(), 0, MAX_WAVE_SIZE - 1, "N163 wave position", "%i");
9798
if (pDocFile->GetBlockVersion() >= 8) { // // // 050B
98-
bool AutoPosition = pDocFile->GetBlockInt() != 0;
99+
m_bAutoWavePos = pDocFile->GetBlockInt() != 0;
99100
}
100101
m_iWaveCount = CModuleException::AssertRangeFmt(pDocFile->GetBlockInt(), 1, MAX_WAVE_COUNT, "N163 wave count", "%i");
101102

Source/InstrumentVRC7.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ void CInstrumentVRC7::SaveFile(CInstrumentFile *pFile)
8787

8888
bool CInstrumentVRC7::LoadFile(CInstrumentFile *pFile, int iVersion)
8989
{
90-
m_iPatch = pFile->ReadInt();
90+
m_iPatch = CModuleException::AssertRangeFmt(pFile->ReadInt(), 0U, 0xFU, "VRC7 patch number", "%i");
9191

9292
for (int i = 0; i < 8; ++i)
9393
SetCustomReg(i, pFile->ReadChar());

0 commit comments

Comments
 (0)