Fix 2x2op WOPL load

This commit is contained in:
James Alan Nguyen 2022-05-09 21:20:14 +10:00
parent 87ffcf2b27
commit da6a6f514c

View file

@ -525,7 +525,7 @@ void DivEngine::loadS3I(SafeReader& reader, std::vector<DivInstrument*>& ret, St
}
void DivEngine::loadSBI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
std::vector<DivInstrument*> insList;
std::vector<DivInstrument*> insList; // in case 2x2op
DivInstrument* ins=new DivInstrument;
try {
reader.seek(0, SEEK_SET);
@ -654,29 +654,9 @@ void DivEngine::loadSBI(SafeReader& reader, std::vector<DivInstrument*>& ret, St
}
void DivEngine::loadOPLI(SafeReader& reader, std::vector<DivInstrument*>& ret, String& stripPath) {
std::vector<DivInstrument*> insList;
std::vector<DivInstrument*> insList; // in case 2x2op
DivInstrument* ins = new DivInstrument;
try {
reader.seek(0, SEEK_SET);
String header = reader.readString(11);
if (header == "WOPL3-INST") {
uint16_t version = reader.readS();
reader.readC(); // skip isPerc field
ins->type = DIV_INS_OPL;
String insName = reader.readString(32);
insName = stringNotBlank(insName) ? insName : stripPath;
ins->name = insName;
// TODO adapt MIDI key offset to transpose?
reader.seek(7, SEEK_CUR); // skip MIDI params
uint8_t instTypeFlags = reader.readC(); // [0EEEDCBA] - see WOPL/OPLI spec
bool is_4op = ((instTypeFlags & 0x1) == 1);
bool is_2x2op = (((instTypeFlags>>1) & 0x1) == 1);
bool is_rhythm = (((instTypeFlags>>4) & 0x7) > 0);
auto readOpliOp = [](SafeReader& reader, DivInstrumentFM::Operator& op) {
uint8_t characteristics = reader.readC();
uint8_t keyScaleLevel = reader.readC();
@ -698,6 +678,26 @@ void DivEngine::loadOPLI(SafeReader& reader, std::vector<DivInstrument*>& ret, S
op.ws = waveSelect;
};
try {
reader.seek(0, SEEK_SET);
String header = reader.readString(11);
if (header == "WOPL3-INST") {
uint16_t version = reader.readS();
reader.readC(); // skip isPerc field
ins->type = DIV_INS_OPL;
String insName = reader.readString(32);
insName = stringNotBlank(insName) ? insName : stripPath;
ins->name = insName;
// TODO adapt MIDI key offset to transpose?
reader.seek(7, SEEK_CUR); // skip MIDI params
uint8_t instTypeFlags = reader.readC(); // [0EEEDCBA] - see WOPL/OPLI spec
bool is_4op = ((instTypeFlags & 0x1) == 1);
bool is_2x2op = (((instTypeFlags>>1) & 0x1) == 1);
bool is_rhythm = (((instTypeFlags>>4) & 0x7) > 0);
uint8_t feedConnect = reader.readC();
uint8_t feedConnect2nd = reader.readC();
@ -1439,7 +1439,6 @@ void DivEngine::loadWOPL(SafeReader& reader, std::vector<DivInstrument*>& ret, S
auto doParseWoplInstrument = [&](bool isPerc, midibank_t*& metadata, int patchNum) {
DivInstrument* ins = new DivInstrument;
DivInstrument* insPair = NULL;
try {
long patchSum = 0;
ins->type = DIV_INS_OPL;
@ -1483,9 +1482,9 @@ void DivEngine::loadWOPL(SafeReader& reader, std::vector<DivInstrument*>& ret, S
stripPath, metadata->name, (isPerc) ? "Drum" : "Melodic", patchNum);
insList.push_back(ins);
patchSum = 0;
insPair = new DivInstrument;
insPair->type = DIV_INS_OPL;
insPair->name = fmt::sprintf("%s (2)", insName);
ins = new DivInstrument;
ins->type = DIV_INS_OPL;
ins->name = fmt::sprintf("%s (2)", insName);
for (int i : {1,0}) {
patchSum += readWoplOp(reader, ins->fm.op[i]);
}