mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-01 08:31:45 +00:00
ADL&OPL: Added a fallback for a blank instruments in GS/XG banks
This commit is contained in:
parent
7296f8c018
commit
934441f9a2
4 changed files with 78 additions and 35 deletions
|
@ -103,7 +103,8 @@ enum WOPL_InstrumentFlags
|
||||||
{
|
{
|
||||||
WOPL_Flags_NONE = 0,
|
WOPL_Flags_NONE = 0,
|
||||||
WOPL_Flag_Enable4OP = 0x01,
|
WOPL_Flag_Enable4OP = 0x01,
|
||||||
WOPL_Flag_Pseudo4OP = 0x02
|
WOPL_Flag_Pseudo4OP = 0x02,
|
||||||
|
WOPL_Flag_NoSound = 0x04,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct WOPL_Inst
|
struct WOPL_Inst
|
||||||
|
@ -151,6 +152,7 @@ static bool readInstrument(MIDIplay::fileReader &file, WOPL_Inst &ins, uint16_t
|
||||||
|
|
||||||
uint8_t flags = idata[39];
|
uint8_t flags = idata[39];
|
||||||
ins.adlins.flags = (flags & WOPL_Flag_Enable4OP) && (flags & WOPL_Flag_Pseudo4OP) ? adlinsdata::Flag_Pseudo4op : 0;
|
ins.adlins.flags = (flags & WOPL_Flag_Enable4OP) && (flags & WOPL_Flag_Pseudo4OP) ? adlinsdata::Flag_Pseudo4op : 0;
|
||||||
|
ins.adlins.flags|= (flags & WOPL_Flag_NoSound) ? adlinsdata::Flag_NoSound : 0;
|
||||||
ins.fourOps = (flags & WOPL_Flag_Enable4OP) || (flags & WOPL_Flag_Pseudo4OP);
|
ins.fourOps = (flags & WOPL_Flag_Enable4OP) || (flags & WOPL_Flag_Pseudo4OP);
|
||||||
|
|
||||||
ins.op[0].feedconn = (idata[40]);
|
ins.op[0].feedconn = (idata[40]);
|
||||||
|
|
|
@ -319,7 +319,7 @@ bool MIDIplay::buildTrackData()
|
||||||
evtPos.delay = ReadVarLenEx(&trackPtr, end, ok);
|
evtPos.delay = ReadVarLenEx(&trackPtr, end, ok);
|
||||||
if(!ok)
|
if(!ok)
|
||||||
{
|
{
|
||||||
int len = std::sprintf(error, "buildTrackData: Can't read variable-length value at begin of track %d.\n", (int)tk);
|
int len = std::snprintf(error, 150, "buildTrackData: Can't read variable-length value at begin of track %d.\n", (int)tk);
|
||||||
if((len > 0) && (len < 150))
|
if((len > 0) && (len < 150))
|
||||||
errorString += std::string(error, (size_t)len);
|
errorString += std::string(error, (size_t)len);
|
||||||
return false;
|
return false;
|
||||||
|
@ -347,7 +347,7 @@ bool MIDIplay::buildTrackData()
|
||||||
event = parseEvent(&trackPtr, end, status);
|
event = parseEvent(&trackPtr, end, status);
|
||||||
if(!event.isValid)
|
if(!event.isValid)
|
||||||
{
|
{
|
||||||
int len = std::sprintf(error, "buildTrackData: Fail to parse event in the track %d.\n", (int)tk);
|
int len = std::snprintf(error, 150, "buildTrackData: Fail to parse event in the track %d.\n", (int)tk);
|
||||||
if((len > 0) && (len < 150))
|
if((len > 0) && (len < 150))
|
||||||
errorString += std::string(error, (size_t)len);
|
errorString += std::string(error, (size_t)len);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1031,7 +1031,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
||||||
{
|
{
|
||||||
if(!caugh_missing_banks_melodic.count(bank))
|
if(!caugh_missing_banks_melodic.count(bank))
|
||||||
{
|
{
|
||||||
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion bank %i (patch %i)", channel, bank, midiins);
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion MIDI bank %i (patch %i)", channel, bank, midiins);
|
||||||
caugh_missing_banks_melodic.insert(bank);
|
caugh_missing_banks_melodic.insert(bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1046,7 +1046,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
||||||
{
|
{
|
||||||
if(!caugh_missing_banks_percussion.count(bank))
|
if(!caugh_missing_banks_percussion.count(bank))
|
||||||
{
|
{
|
||||||
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic bank %i (patch %i)", channel, bank, midiins);
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic MIDI bank %i (patch %i)", channel, bank, midiins);
|
||||||
caugh_missing_banks_percussion.insert(bank);
|
caugh_missing_banks_percussion.insert(bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1060,29 +1060,48 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
||||||
if(midiins == 48 || midiins == 50) vol /= 4; // HACK
|
if(midiins == 48 || midiins == 50) vol /= 4; // HACK
|
||||||
*/
|
*/
|
||||||
//if(midiins == 56) vol = vol*6/10; // HACK
|
//if(midiins == 56) vol = vol*6/10; // HACK
|
||||||
|
|
||||||
//int meta = banks[opl.AdlBank][midiins];
|
//int meta = banks[opl.AdlBank][midiins];
|
||||||
const size_t meta = opl.GetAdlMetaNumber(midiins);
|
|
||||||
const adlinsdata &ains = opl.GetAdlMetaIns(meta);
|
size_t meta = opl.GetAdlMetaNumber(midiins);
|
||||||
|
const adlinsdata *ains = &opl.GetAdlMetaIns(meta);
|
||||||
int16_t tone = note;
|
int16_t tone = note;
|
||||||
|
|
||||||
if(ains.tone)
|
if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks
|
||||||
|
{
|
||||||
|
if(ains->flags & adlinsdata::Flag_NoSound)
|
||||||
|
{
|
||||||
|
if(hooks.onDebugMessage)
|
||||||
|
{
|
||||||
|
if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)))
|
||||||
|
{
|
||||||
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank);
|
||||||
|
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bank = 0;
|
||||||
|
midiins = Ch[channel].patch;
|
||||||
|
meta = opl.GetAdlMetaNumber(midiins);
|
||||||
|
ains = &opl.GetAdlMetaIns(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ains->tone)
|
||||||
{
|
{
|
||||||
/*if(ains.tone < 20)
|
/*if(ains.tone < 20)
|
||||||
tone += ains.tone;
|
tone += ains.tone;
|
||||||
else*/
|
else*/
|
||||||
if(ains.tone < 128)
|
if(ains->tone < 128)
|
||||||
tone = ains.tone;
|
tone = ains->tone;
|
||||||
else
|
else
|
||||||
tone -= ains.tone - 128;
|
tone -= ains->tone - 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
//uint16_t i[2] = { ains.adlno1, ains.adlno2 };
|
//uint16_t i[2] = { ains.adlno1, ains.adlno2 };
|
||||||
bool pseudo_4op = ains.flags & adlinsdata::Flag_Pseudo4op;
|
bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op;
|
||||||
MIDIchannel::NoteInfo::Phys voices[2] =
|
MIDIchannel::NoteInfo::Phys voices[2] =
|
||||||
{
|
{
|
||||||
{ains.adlno1, false},
|
{ains->adlno1, false},
|
||||||
{ains.adlno2, pseudo_4op}
|
{ains->adlno2, pseudo_4op}
|
||||||
};
|
};
|
||||||
|
|
||||||
if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF])
|
if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF])
|
||||||
|
@ -1090,7 +1109,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
|
||||||
|
|
||||||
if(hooks.onDebugMessage)
|
if(hooks.onDebugMessage)
|
||||||
{
|
{
|
||||||
if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains.flags & adlinsdata::Flag_NoSound))
|
if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains->flags & adlinsdata::Flag_NoSound))
|
||||||
{
|
{
|
||||||
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
|
||||||
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
|
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
|
||||||
|
@ -2624,12 +2643,12 @@ ADLMIDI_EXPORT void AdlInstrumentTester::NextAdl(int offset)
|
||||||
if(ains.tone)
|
if(ains.tone)
|
||||||
{
|
{
|
||||||
/*if(ains.tone < 20)
|
/*if(ains.tone < 20)
|
||||||
std::sprintf(ToneIndication, "+%-2d", ains.tone);
|
std::snprintf(ToneIndication, 8, "+%-2d", ains.tone);
|
||||||
else*/
|
else*/
|
||||||
if(ains.tone < 128)
|
if(ains.tone < 128)
|
||||||
std::sprintf(ToneIndication, "=%-2d", ains.tone);
|
std::snprintf(ToneIndication, 8, "=%-2d", ains.tone);
|
||||||
else
|
else
|
||||||
std::sprintf(ToneIndication, "-%-2d", ains.tone - 128);
|
std::snprintf(ToneIndication, 8, "-%-2d", ains.tone - 128);
|
||||||
}
|
}
|
||||||
std::printf("%s%s%s%u\t",
|
std::printf("%s%s%s%u\t",
|
||||||
ToneIndication,
|
ToneIndication,
|
||||||
|
|
|
@ -280,10 +280,14 @@ bool OPNMIDIplay::LoadBank(OPNMIDIplay::fileReader &fr)
|
||||||
size_t off = 37 + op * 7;
|
size_t off = 37 + op * 7;
|
||||||
std::memcpy(data.OPS[op].data, idata + off, 7);
|
std::memcpy(data.OPS[op].data, idata + off, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meta.flags = 0;
|
||||||
if(version >= 2)
|
if(version >= 2)
|
||||||
{
|
{
|
||||||
meta.ms_sound_kon = toUint16BE(idata + 65);
|
meta.ms_sound_kon = toUint16BE(idata + 65);
|
||||||
meta.ms_sound_koff = toUint16BE(idata + 67);
|
meta.ms_sound_koff = toUint16BE(idata + 67);
|
||||||
|
if((meta.ms_sound_kon == 0) && (meta.ms_sound_koff == 0))
|
||||||
|
meta.flags |= opnInstMeta::Flag_NoSound;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -295,7 +299,6 @@ bool OPNMIDIplay::LoadBank(OPNMIDIplay::fileReader &fr)
|
||||||
meta.opnno2 = uint16_t(opn.dynamic_instruments.size());
|
meta.opnno2 = uint16_t(opn.dynamic_instruments.size());
|
||||||
|
|
||||||
/* Junk, delete later */
|
/* Junk, delete later */
|
||||||
meta.flags = 0;
|
|
||||||
meta.fine_tune = 0.0;
|
meta.fine_tune = 0.0;
|
||||||
/* Junk, delete later */
|
/* Junk, delete later */
|
||||||
|
|
||||||
|
|
|
@ -280,7 +280,7 @@ bool OPNMIDIplay::buildTrackData()
|
||||||
evtPos.delay = ReadVarLenEx(&trackPtr, end, ok);
|
evtPos.delay = ReadVarLenEx(&trackPtr, end, ok);
|
||||||
if(!ok)
|
if(!ok)
|
||||||
{
|
{
|
||||||
int len = std::sprintf(error, "buildTrackData: Can't read variable-length value at begin of track %d.\n", (int)tk);
|
int len = std::snprintf(error, 150, "buildTrackData: Can't read variable-length value at begin of track %d.\n", (int)tk);
|
||||||
if((len > 0) && (len < 150))
|
if((len > 0) && (len < 150))
|
||||||
errorString += std::string(error, (size_t)len);
|
errorString += std::string(error, (size_t)len);
|
||||||
return false;
|
return false;
|
||||||
|
@ -308,7 +308,7 @@ bool OPNMIDIplay::buildTrackData()
|
||||||
event = parseEvent(&trackPtr, end, status);
|
event = parseEvent(&trackPtr, end, status);
|
||||||
if(!event.isValid)
|
if(!event.isValid)
|
||||||
{
|
{
|
||||||
int len = std::sprintf(error, "buildTrackData: Fail to parse event in the track %d.\n", (int)tk);
|
int len = std::snprintf(error, 150, "buildTrackData: Fail to parse event in the track %d.\n", (int)tk);
|
||||||
if((len > 0) && (len < 150))
|
if((len > 0) && (len < 150))
|
||||||
errorString += std::string(error, (size_t)len);
|
errorString += std::string(error, (size_t)len);
|
||||||
return false;
|
return false;
|
||||||
|
@ -981,7 +981,7 @@ bool OPNMIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocit
|
||||||
{
|
{
|
||||||
if(!caugh_missing_banks_melodic.count(bank))
|
if(!caugh_missing_banks_melodic.count(bank))
|
||||||
{
|
{
|
||||||
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion bank %i (patch %i)", channel, bank, midiins);
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing percussion MIDI bank %i (patch %i)", channel, bank, midiins);
|
||||||
caugh_missing_banks_melodic.insert(bank);
|
caugh_missing_banks_melodic.insert(bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,7 +996,7 @@ bool OPNMIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocit
|
||||||
{
|
{
|
||||||
if(!caugh_missing_banks_melodic.count(bank))
|
if(!caugh_missing_banks_melodic.count(bank))
|
||||||
{
|
{
|
||||||
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic bank %i (patch %i)", channel, bank, midiins);
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing melodic MIDI bank %i (patch %i)", channel, bank, midiins);
|
||||||
caugh_missing_banks_melodic.insert(bank);
|
caugh_missing_banks_melodic.insert(bank);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1011,28 +1011,47 @@ bool OPNMIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocit
|
||||||
*/
|
*/
|
||||||
//if(midiins == 56) vol = vol*6/10; // HACK
|
//if(midiins == 56) vol = vol*6/10; // HACK
|
||||||
|
|
||||||
const size_t meta = opn.GetAdlMetaNumber(midiins);
|
size_t meta = opn.GetAdlMetaNumber(midiins);
|
||||||
const opnInstMeta &ains = opn.GetAdlMetaIns(meta);
|
const opnInstMeta *ains = &opn.GetAdlMetaIns(meta);
|
||||||
int16_t tone = note;
|
int16_t tone = note;
|
||||||
|
|
||||||
if(ains.tone)
|
if(!isPercussion && !isXgPercussion && (bank > 0)) // For non-zero banks
|
||||||
|
{
|
||||||
|
if(ains->flags & opnInstMeta::Flag_NoSound)
|
||||||
|
{
|
||||||
|
if(hooks.onDebugMessage)
|
||||||
|
{
|
||||||
|
if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)))
|
||||||
|
{
|
||||||
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Caugh a blank instrument %i (offset %i) in the MIDI bank %u", channel, Ch[channel].patch, midiins, bank);
|
||||||
|
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bank = 0;
|
||||||
|
midiins = Ch[channel].patch;
|
||||||
|
meta = opn.GetAdlMetaNumber(midiins);
|
||||||
|
ains = &opn.GetAdlMetaIns(meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ains->tone)
|
||||||
{
|
{
|
||||||
/*if(ains.tone < 20)
|
/*if(ains.tone < 20)
|
||||||
tone += ains.tone;
|
tone += ains.tone;
|
||||||
else*/
|
else*/
|
||||||
if(ains.tone < 128)
|
if(ains->tone < 128)
|
||||||
tone = ains.tone;
|
tone = ains->tone;
|
||||||
else
|
else
|
||||||
tone -= ains.tone - 128;
|
tone -= ains->tone - 128;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t i[2] = { ains.opnno1, ains.opnno2 };
|
uint16_t i[2] = { ains->opnno1, ains->opnno2 };
|
||||||
//bool pseudo_4op = ains.flags & opnInstMeta::Flag_Pseudo8op;
|
//bool pseudo_4op = ains.flags & opnInstMeta::Flag_Pseudo8op;
|
||||||
//if((opn.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) i[1] = i[0];
|
//if((opn.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) i[1] = i[0];
|
||||||
|
|
||||||
if(hooks.onDebugMessage)
|
if(hooks.onDebugMessage)
|
||||||
{
|
{
|
||||||
if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains.flags & opnInstMeta::Flag_NoSound))
|
if(!caugh_missing_instruments.count(static_cast<uint8_t>(midiins)) && (ains->flags & opnInstMeta::Flag_NoSound))
|
||||||
{
|
{
|
||||||
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
|
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
|
||||||
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
|
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));
|
||||||
|
@ -2548,12 +2567,12 @@ retry_arpeggio:
|
||||||
// if(ains.tone)
|
// if(ains.tone)
|
||||||
// {
|
// {
|
||||||
// /*if(ains.tone < 20)
|
// /*if(ains.tone < 20)
|
||||||
// std::sprintf(ToneIndication, "+%-2d", ains.tone);
|
// std::snprintf(ToneIndication, 8, "+%-2d", ains.tone);
|
||||||
// else*/
|
// else*/
|
||||||
// if(ains.tone < 128)
|
// if(ains.tone < 128)
|
||||||
// std::sprintf(ToneIndication, "=%-2d", ains.tone);
|
// std::snprintf(ToneIndication, 8, "=%-2d", ains.tone);
|
||||||
// else
|
// else
|
||||||
// std::sprintf(ToneIndication, "-%-2d", ains.tone - 128);
|
// std::snprintf(ToneIndication, 8, "-%-2d", ains.tone - 128);
|
||||||
// }
|
// }
|
||||||
// std::printf("%s%s%s%u\t",
|
// std::printf("%s%s%s%u\t",
|
||||||
// ToneIndication,
|
// ToneIndication,
|
||||||
|
|
Loading…
Reference in a new issue