More #79 - Add S3I Adlib instrument support. Also fix SafeReader SEEK_CUR handling (wasn't used at all).

This commit is contained in:
James Alan Nguyen 2022-03-20 17:12:03 +11:00
parent 629049dea0
commit cbe74b26ad
3 changed files with 87 additions and 4 deletions

View file

@ -1223,6 +1223,7 @@ enum DivInsFormats {
DIV_INSFORMAT_VGI,
DIV_INSFORMAT_FTI,
DIV_INSFORMAT_BTI,
DIV_INSFORMAT_S3I,
DIV_INSFORMAT_SBI,
};
@ -1343,6 +1344,8 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
format=DIV_INSFORMAT_FTI;
} else if (extS==String(".bti")) {
format=DIV_INSFORMAT_BTI;
} else if (extS==String(".s3i")) {
format = DIV_INSFORMAT_S3I;
} else if (extS==String(".sbi")) {
format = DIV_INSFORMAT_SBI;
}
@ -1675,6 +1678,85 @@ bool DivEngine::addInstrumentFromFile(const char* path) {
break;
case DIV_INSFORMAT_BTI:
break;
case DIV_INSFORMAT_S3I:
try {
reader.seek(0, SEEK_SET);
uint8_t s3i_type = reader.readC();
if (s3i_type >= 2) {
ins->type = DIV_INS_OPL;
// skip internal filename - we'll use the long name description
reader.seek(12, SEEK_CUR);
// skip reserved bytes
reader.seek(3, SEEK_CUR);
// 12-byte opl value
uint8_t s3i_Mcharacteristics = reader.readC();
uint8_t s3i_Ccharacteristics = reader.readC();
uint8_t s3i_Mscaling_output = reader.readC();
uint8_t s3i_Cscaling_output = reader.readC();
uint8_t s3i_Meg_AD = reader.readC();
uint8_t s3i_Ceg_AD = reader.readC();
uint8_t s3i_Meg_SR = reader.readC();
uint8_t s3i_Ceg_SR = reader.readC();
uint8_t s3i_Mwave = reader.readC();
uint8_t s3i_Cwave = reader.readC();
uint8_t s3i_FeedConnect = reader.readC();
DivInstrumentFM::Operator& opM = ins->fm.op[0];
DivInstrumentFM::Operator& opC = ins->fm.op[1];
ins->fm.ops = 2;
opM.mult = s3i_Mcharacteristics & 0xF;
opM.ksr = ((s3i_Mcharacteristics >> 4) & 0x1);
opM.sus = ((s3i_Mcharacteristics >> 5) & 0x1);
opM.vib = ((s3i_Mcharacteristics >> 6) & 0x1);
opM.am = ((s3i_Mcharacteristics >> 7) & 0x1);
opM.tl = s3i_Mscaling_output & 0x3F;
opM.ksl = ((s3i_Mscaling_output >> 6) & 0x3);
opM.ar = ((s3i_Meg_AD >> 4) & 0xF);
opM.dr = (s3i_Meg_AD & 0xF);
opM.rr = (s3i_Meg_SR & 0xF);
opM.sl = ((s3i_Meg_SR >> 4) & 0xF);
opM.ws = s3i_Mwave;
ins->fm.alg = (s3i_FeedConnect & 0x1);
ins->fm.fb = ((s3i_FeedConnect >> 1) & 0x7);
opC.mult = s3i_Ccharacteristics & 0xF;
opC.ksr = ((s3i_Ccharacteristics >> 4) & 0x1);
opC.sus = ((s3i_Ccharacteristics >> 5) & 0x1);
opC.vib = ((s3i_Ccharacteristics >> 6) & 0x1);
opC.am = ((s3i_Ccharacteristics >> 7) & 0x1);
opC.tl = s3i_Cscaling_output & 0x3F;
opC.ksl = ((s3i_Cscaling_output >> 6) & 0x3);
opC.ar = ((s3i_Ceg_AD >> 4) & 0xF);
opC.dr = (s3i_Ceg_AD & 0xF);
opC.rr = (s3i_Ceg_SR & 0xF);
opC.sl = ((s3i_Ceg_SR >> 4) & 0xF);
opC.ws = s3i_Cwave;
// Skip more stuff we don't need
reader.seek(21, SEEK_CUR);
} else {
logE("S3I PCM samples currently not supported.");
}
ins->name = reader.readString(28);
int s3i_signature = reader.readI();
if (s3i_signature != 0x49524353) {
logW("S3I signature invalid.");
};
}
catch (EndOfFileException& e) {
lastError = "premature end of file";
logE("premature end of file!\n");
delete ins;
delete[] buf;
return false;
}
break;
case DIV_INSFORMAT_SBI:
try {
reader.seek(0, SEEK_SET);