aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVitaly Novichkov <admin@wohlnet.ru>2018-03-27 02:32:16 +0300
committerVitaly Novichkov <admin@wohlnet.ru>2018-03-27 02:32:16 +0300
commitab3a2fc025197749a74a6f7cdeb10d93819f2863 (patch)
tree36e6f964818cdd84dc554df370bc0df3e427d34f
parent04ab4c1bcf65870cbe34b405a181a4246bcd91e8 (diff)
downloadlibADLMIDI-ab3a2fc025197749a74a6f7cdeb10d93819f2863.tar.gz
libADLMIDI-ab3a2fc025197749a74a6f7cdeb10d93819f2863.tar.bz2
libADLMIDI-ab3a2fc025197749a74a6f7cdeb10d93819f2863.zip
Fixed blank instruments fallback in multi-bank support
-rw-r--r--README.md1
-rw-r--r--src/adlmidi_load.cpp4
-rw-r--r--src/adlmidi_midiplay.cpp45
3 files changed, 36 insertions, 14 deletions
diff --git a/README.md b/README.md
index 6aa209d..378de33 100644
--- a/README.md
+++ b/README.md
@@ -135,6 +135,7 @@ To build that example you will need to have installed SDL2 library.
## 1.3.2 dev
* Added ability to disable MUS and XMI converters
* Added ability to disable embedded MIDI sequencer to use library as RealTime synthesizer only or use any custom MIDI sequencer plugins.
+ * Fixed blank instruments fallback in multi-bank support. When using non-zero bank, if instrument is blank, then, instrument will be taken from a root (I.e. zero bank).
## 1.3.1 2017-12-16
* Added Real-Time MIDI API (MIDI event functions and adl_generate() to generate PCM between of event rows) which allows you to implement plugin for media players or even a real time MIDI playing driver.
diff --git a/src/adlmidi_load.cpp b/src/adlmidi_load.cpp
index 03206bc..00a4ce3 100644
--- a/src/adlmidi_load.cpp
+++ b/src/adlmidi_load.cpp
@@ -103,7 +103,8 @@ enum WOPL_InstrumentFlags
{
WOPL_Flags_NONE = 0,
WOPL_Flag_Enable4OP = 0x01,
- WOPL_Flag_Pseudo4OP = 0x02
+ WOPL_Flag_Pseudo4OP = 0x02,
+ WOPL_Flag_NoSound = 0x04,
};
struct WOPL_Inst
@@ -151,6 +152,7 @@ static bool readInstrument(MIDIplay::fileReader &file, WOPL_Inst &ins, uint16_t
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_NoSound) ? adlinsdata::Flag_NoSound : 0;
ins.fourOps = (flags & WOPL_Flag_Enable4OP) || (flags & WOPL_Flag_Pseudo4OP);
ins.op[0].feedconn = (idata[40]);
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 65e7af5..a89b1cd 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -1031,7 +1031,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
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);
}
}
@@ -1046,7 +1046,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
{
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);
}
}
@@ -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 == 56) vol = vol*6/10; // HACK
-
//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;
- 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)
tone += ains.tone;
else*/
- if(ains.tone < 128)
- tone = ains.tone;
+ if(ains->tone < 128)
+ tone = ains->tone;
else
- tone -= ains.tone - 128;
+ tone -= ains->tone - 128;
}
//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] =
{
- {ains.adlno1, false},
- {ains.adlno2, pseudo_4op}
+ {ains->adlno1, false},
+ {ains->adlno2, pseudo_4op}
};
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(!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);
caugh_missing_instruments.insert(static_cast<uint8_t>(midiins));