Skip to content

Commit

Permalink
Refactor instrument loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Gumball2415 committed Feb 7, 2025
1 parent c580ff3 commit 5be1e7a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 39 deletions.
6 changes: 4 additions & 2 deletions Source/FamiTrackerDoc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1812,7 +1812,7 @@ void CFamiTrackerDoc::ReadBlock_Parameters(CDocumentFile *pDocFile, const int Ve
switch (m_iPlaybackRateType) {
case 1:
// workaround for now
m_iEngineSpeed = static_cast<int>(1000000. / m_iPlaybackRate + .5);
m_iEngineSpeed = static_cast<unsigned int>(1000000. / m_iPlaybackRate + .5);
break;
case 0: case 2:
default:
Expand Down Expand Up @@ -1949,7 +1949,9 @@ void CFamiTrackerDoc::ReadBlock_Header(CDocumentFile *pDocFile, const int Versio
for (unsigned int i = 0; i < m_iTrackCount; ++i) {
int First = static_cast<unsigned char>(pDocFile->GetBlockChar());
int Second = static_cast<unsigned char>(pDocFile->GetBlockChar());
if (!i) {

// we don't have per-track row highlights yet, just use the first track
if (i == 0) {
m_vHighlight.First = First;
m_vHighlight.Second = Second;
}
Expand Down
60 changes: 33 additions & 27 deletions Source/Instrument2A03.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void CInstrument2A03::Store(CDocumentFile *pDocFile)
{
CSeqInstrument::Store(pDocFile); // // //

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

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

const auto ReadAssignment = [&] (int Octave, int Note) {
try {
int Index = CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(
char Sample = CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(
pDocFile->GetBlockChar(), 0, MAX_DSAMPLES, "DPCM sample assignment index", "%i");
if (Index > MAX_DSAMPLES)
Index = 0;
SetSampleIndex(Octave, Note, Index);
if (Sample > MAX_DSAMPLES)
Sample = 0;

SetSampleIndex(Octave, Note, Sample);
char Pitch = pDocFile->GetBlockChar();
CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(Pitch & 0x7F, 0, 0xF, "DPCM sample pitch", "%i");
SetSamplePitch(Octave, Note, Pitch & 0x8F);
Expand All @@ -122,7 +123,7 @@ bool CInstrument2A03::Load(CDocumentFile *pDocFile)
for (int i = 0; i < Count; ++i) {
int Note = CModuleException::AssertRangeFmt<MODULE_ERROR_STRICT>(
pDocFile->GetBlockChar(), 0, NOTE_COUNT - 1, "DPCM sample assignment note index", "%i");
ReadAssignment(GET_OCTAVE(Note), GET_NOTE(Note) - 1);
ReadAssignment(GET_OCTAVE(Note - 1), GET_NOTE(Note - 1));
}
}
else
Expand Down Expand Up @@ -155,10 +156,10 @@ void CInstrument2A03::SaveFile(CInstrumentFile *pFile)
memset(UsedSamples, 0, sizeof(bool) * MAX_DSAMPLES);

int UsedCount = 0;
for (int i = 0; i < OCTAVE_RANGE; ++i) { // octaves
for (int j = 0; j < NOTE_RANGE; ++j) { // notes
for (int i = 0; i < OCTAVE_RANGE; ++i) {
for (int j = 0; j < NOTE_RANGE; ++j) {
if (unsigned char Sample = GetSampleIndex(i, j)) {
unsigned char Index = i * NOTE_RANGE + j;
unsigned char Index = MIDI_NOTE(i, j) + 1;
pFile->WriteChar(Index);
pFile->WriteChar(Sample);
pFile->WriteChar(GetSamplePitch(i, j));
Expand Down Expand Up @@ -189,28 +190,28 @@ void CInstrument2A03::SaveFile(CInstrumentFile *pFile)

bool CInstrument2A03::LoadFile(CInstrumentFile *pFile, int iVersion)
{
char SampleNames[MAX_DSAMPLES][256];

if (!CSeqInstrument::LoadFile(pFile, iVersion)) // // //
return false;

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

// DPCM instruments
for (unsigned int i = 0; i < Count; ++i) {
unsigned char InstNote = pFile->ReadChar();
int Octave = InstNote / NOTE_RANGE;
int Note = InstNote % NOTE_RANGE;
unsigned char InstNote = CModuleException::AssertRangeFmt(
pFile->ReadChar(), 0, NOTE_COUNT - 1, "DPCM sample assignment note index", "%i");
int Octave = GET_OCTAVE(InstNote - 1);
int Note = GET_NOTE(InstNote - 1);
try {
unsigned char Sample = CModuleException::AssertRangeFmt(pFile->ReadChar(), 0U, 0x7FU, "DPCM sample assignment index", "%u");
char Sample = CModuleException::AssertRangeFmt(pFile->ReadChar(), 0, MAX_DSAMPLES, "DPCM sample assignment index", "%u");
if (Sample > MAX_DSAMPLES)
Sample = 0;
unsigned char Pitch = pFile->ReadChar();
CModuleException::AssertRangeFmt(Pitch & 0x7FU, 0U, 0xFU, "DPCM sample pitch", "%u");
SetSamplePitch(Octave, Note, Pitch);
SetSampleIndex(Octave, Note, Sample);

char Pitch = pFile->ReadChar();
CModuleException::AssertRangeFmt(Pitch & 0x7F, 0, 0xF, "DPCM sample pitch", "%i");

SetSamplePitch(Octave, Note, Pitch);

SetSampleDeltaValue(Octave, Note, CModuleException::AssertRangeFmt(
static_cast<char>(iVersion >= 24 ? pFile->ReadChar() : -1), -1, 0x7F, "DPCM sample delta value", "%i"));
}
Expand All @@ -229,20 +230,24 @@ bool CInstrument2A03::LoadFile(CInstrumentFile *pFile, int iVersion)

unsigned int SampleCount = pFile->ReadInt();
for (unsigned int i = 0; i < SampleCount; ++i) {

int Index = CModuleException::AssertRangeFmt(
pFile->ReadInt(), 0U, static_cast<unsigned>(MAX_DSAMPLES - 1), "DPCM sample index", "%u");

int Len = CModuleException::AssertRangeFmt(
pFile->ReadInt(), 0U, static_cast<unsigned>(CDSample::MAX_NAME_SIZE - 1), "DPCM sample name length", "%u");
pFile->Read(SampleNames[Index], Len);
SampleNames[Index][Len] = 0;

char SampleName[256]{};
pFile->Read(SampleName, Len);

int Size = pFile->ReadInt();
char *SampleData = new char[Size];
pFile->Read(SampleData, Size);
bool Found = false;
for (int j = 0; j < MAX_DSAMPLES; ++j) if (const CDSample *pSample = m_pInstManager->GetDSample(j)) { // // //
// Compare size and name to see if identical sample exists
if (pSample->GetSize() == Size && !memcmp(pSample->GetData(), SampleData, Size) && // // //
!strcmp(pSample->GetName(), SampleNames[Index])) {
!strcmp(pSample->GetName(), SampleName)) {
Found = true;
// Assign sample
for (int o = 0; o < OCTAVE_RANGE; ++o) {
Expand Down Expand Up @@ -270,9 +275,9 @@ bool CInstrument2A03::LoadFile(CInstrumentFile *pFile, int iVersion)
e->Raise();
}
CDSample *pSample = new CDSample(); // // //
pSample->SetName(SampleNames[Index]);
pSample->SetName(SampleName);
pSample->SetData(Size, SampleData);
int FreeSample = m_pInstManager->AddDSample(pSample);
int FreeSample = m_pInstManager->AddDSample(pSample); // not off-by-one
if (FreeSample == -1) {
SAFE_RELEASE(pSample);
CModuleException *e = new CModuleException();
Expand Down Expand Up @@ -332,6 +337,7 @@ char CInstrument2A03::GetSampleDeltaValue(int Octave, int Note) const

void CInstrument2A03::SetSampleIndex(int Octave, int Note, char Sample)
{
// Sample is off by one; 0 means there is no index assigned to a note
m_cSamples[Octave][Note] = Sample;
InstrumentChanged();
}
Expand Down
32 changes: 25 additions & 7 deletions Source/InstrumentFDS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ void CInstrumentFDS::Store(CDocumentFile *pDocFile)

bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
{
const int Version = pDocFile->GetBlockVersion();
for (int i = 0; i < WAVE_SIZE; ++i) {
SetSample(i, pDocFile->GetBlockChar());
}
Expand All @@ -205,8 +206,25 @@ bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
SetModulationDepth(pDocFile->GetBlockInt());
SetModulationDelay(pDocFile->GetBlockInt());

// hack to fix earlier saved files (remove this eventually)
for (int i = 0; i < SEQUENCE_COUNT; ++i) {
if (Version > 2)
SetSequence(i, LoadSequence(pDocFile));
else
if (i < SEQ_PITCH)
// version 2 apparently does not have Pitch sequences
SetSequence(i, LoadSequence(pDocFile));
}

// Older files was 0-15, new is 0-31
if (Version <= 3) DoubleVolume();

return true;

// ancient code preserved for analysis

/*
// hack to fix earlier saved files (remove this eventually)
if (pDocFile->GetBlockVersion() > 2) {
LoadSequence(pDocFile, GetSequence(SEQ_VOLUME));
LoadSequence(pDocFile, GetSequence(SEQ_ARPEGGIO));
Expand All @@ -215,10 +233,14 @@ bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
}
else {
*/

/*
TODO: investigate Instrument block v2 and FDS
- perhaps an release interstice bug fix?
unsigned int a = pDocFile->GetBlockInt();
unsigned int b = pDocFile->GetBlockInt();
// TODO: investigate why loading FDS instruments uses RollbackPointer()
pDocFile->RollbackPointer(8);
if (a < 256 && (b & 0xFF) != 0x00) {
Expand All @@ -234,13 +256,9 @@ bool CInstrumentFDS::Load(CDocumentFile *pDocFile)
if (pDocFile->GetBlockVersion() > 2)
SetSequence(SEQ_PITCH, LoadSequence(pDocFile));
}
*/

// }

// Older files was 0-15, new is 0-31
if (pDocFile->GetBlockVersion() <= 3) DoubleVolume();

return true;
}

void CInstrumentFDS::SaveFile(CInstrumentFile *pFile)
Expand Down
5 changes: 3 additions & 2 deletions Source/InstrumentN163.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ void CInstrumentN163::Store(CDocumentFile *pDocFile)
// Store wave
pDocFile->WriteBlockInt(m_iWaveSize);
pDocFile->WriteBlockInt(m_iWavePos);
//pDocFile->WriteBlockInt(m_bAutoWavePos ? 1 : 0);
// if (pDocFile->GetBlockVersion() >= 8) // // // 050B
// pDocFile->WriteBlockInt(m_bAutoWavePos ? 1 : 0);
pDocFile->WriteBlockInt(m_iWaveCount);

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

Expand Down
2 changes: 1 addition & 1 deletion Source/InstrumentVRC7.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void CInstrumentVRC7::SaveFile(CInstrumentFile *pFile)

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

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

0 comments on commit 5be1e7a

Please sign in to comment.