aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md1
-rw-r--r--src/adlmidi_midiplay.cpp26
-rw-r--r--src/adlmidi_private.hpp2
3 files changed, 27 insertions, 2 deletions
diff --git a/README.md b/README.md
index 96d2956..54cab0d 100644
--- a/README.md
+++ b/README.md
@@ -161,6 +161,7 @@ To build that example you will need to have installed SDL2 library.
* Added support for CC66-Sostenuto controller (Pedal hold of currently-pressed notes only while CC64 holds also all next notes)
* Added support for CC67-SoftPedal controller (SoftPedal lowers the volume of notes played)
* Fixed correctness of CMF files playing
+ * Fixed unnecessary overuse of chip channels by blank notes
## 1.3.3 2018-06-19
* Fixed an inability to load another custom bank without of library re-initialization
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 4f57374..9841f73 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -397,13 +397,27 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if((m_synth.m_rhythmMode == 1) && PercussionMap[midiins & 0xFF])
voices[1] = voices[0];//i[1] = i[0];
+ bool isBlankNote = (ains->flags & adlinsdata::Flag_NoSound);
+
if(hooks.onDebugMessage)
{
- if((ains->flags & adlinsdata::Flag_NoSound) &&
- caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second)
+ if(isBlankNote && caugh_missing_instruments.insert(static_cast<uint8_t>(midiins)).second)
hooks.onDebugMessage(hooks.onDebugMessage_userData, "[%i] Playing missing instrument %i", channel, midiins);
}
+ if(isBlankNote)
+ {
+ // Don't even try to play the blank instrument! But, insert the dummy note.
+ std::pair<MIDIchannel::activenoteiterator, bool>
+ dummy = midiChan.activenotes_insert(note);
+ dummy.first->isBlank = true;
+ dummy.first->ains = NULL;
+ dummy.first->chip_channels_count = 0;
+ // Record the last note on MIDI channel as source of portamento
+ midiChan.portamentoSource = static_cast<int8_t>(note);
+ return false;
+ }
+
// Allocate AdLib channel (the physical sound channel for the note)
int32_t adlchannel[MIDIchannel::NoteInfo::MaxNumPhysChans] = { -1, -1 };
@@ -500,6 +514,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
ir.first->glideRate = HUGE_VAL;
ir.first->midiins = midiins;
ir.first->isPercussion = isPercussion;
+ ir.first->isBlank = isBlankNote;
ir.first->ains = ains;
ir.first->chip_channels_count = 0;
@@ -1045,6 +1060,13 @@ void MIDIplay::noteUpdate(size_t midCh,
my_loc.MidCh = static_cast<uint16_t>(midCh);
my_loc.note = info.note;
+ if(info.isBlank)
+ {
+ if(props_mask & Upd_Off)
+ m_midiChannels[midCh].activenotes_erase(i);
+ return;
+ }
+
for(unsigned ccount = 0, ctotal = info.chip_channels_count; ccount < ctotal; ccount++)
{
const MIDIchannel::NoteInfo::Phys &ins = info.chip_channels[ccount];
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 8e08077..7b59003 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -584,6 +584,8 @@ public:
size_t midiins;
//! Is note the percussion instrument
bool isPercussion;
+ //! Note that plays missing instrument. Doesn't using any chip channels
+ bool isBlank;
//! Patch selected
const adlinsdata2 *ains;
enum