aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/adlmidi_midiplay.cpp43
-rw-r--r--src/adlmidi_midiplay.hpp28
2 files changed, 36 insertions, 35 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index e092fa2..9ed7ee0 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -673,7 +673,8 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(c < 0)
continue;
uint16_t chipChan = static_cast<uint16_t>(adlchannel[ccount]);
- ni.phys_ensure_find_or_create(chipChan)->assign(voices[ccount]);
+ MIDIchannel::NoteInfo::Phys* p = ni.phys_ensure_find_or_create(chipChan);
+ p->assign(voices[ccount]);
}
noteUpdate(channel, ir, Upd_All | Upd_Patch);
@@ -1565,29 +1566,11 @@ bool MIDIplay::killSecondVoicesIfOverflow(int32_t &new_chan)
{
AdlChannel::users_iterator j = &m_chipChannels[new_chan].users.front();
AdlChannel::LocationData &jd = j->value;
- MIDIchannel::notes_iterator it = m_midiChannels[jd.loc.MidCh].find_activenote(jd.loc.note);
- assert(m_chipChannels[new_chan].users.size() <= 1);
-
- if(it.is_end()) /* Invalid user of channel */
- {
- m_chipChannels[new_chan].users.clear();
- m_chipChannels[new_chan].koff_time_until_neglible_us = 0;
- synth.noteOff(new_chan);
- ret = true;
- return ret;
- }
-
- MIDIchannel::NoteInfo &info = it->value;
-
- if(info.chip_channels_count == 2)
- {
- m_chipChannels[new_chan].users.clear();
- m_chipChannels[new_chan].koff_time_until_neglible_us = 0;
- info.phys_erase_at(&info.chip_channels[1]);
- synth.noteOff(new_chan);
- ret = true;
- }
+ m_midiChannels[jd.loc.MidCh].clear_all_phys_users(new_chan);
+ m_chipChannels[new_chan].users.clear();
+ m_chipChannels[new_chan].koff_time_until_neglible_us = 0;
+ ret = true;
}
return ret;
@@ -1608,20 +1591,12 @@ void MIDIplay::prepareChipChannelForNewNote(size_t c, const MIDIchannel::NoteInf
AdlChannel::LocationData &jd = j->value;
++jnext;
- if(jd.sustained == AdlChannel::LocationData::Sustain_None)
- {
- MIDIchannel::notes_iterator i = m_midiChannels[jd.loc.MidCh].find_activenote(jd.loc.note);
- if(i.is_end())
- m_chipChannels[c].users.erase(j);
- else
- noteUpdate(j->value.loc.MidCh, i, Upd_Off, static_cast<int32_t>(c));
- }
- else
- m_chipChannels[c].users.erase(j);
+ m_midiChannels[jd.loc.MidCh].clear_all_phys_users(c);
+ m_chipChannels[c].users.erase(j);
}
synth.noteOff(c);
- m_chipChannels[c].users.clear();
+ assert(m_chipChannels[c].users.empty()); // No users should remain!
return;
}
diff --git a/src/adlmidi_midiplay.hpp b/src/adlmidi_midiplay.hpp
index e5058b9..bcd76a1 100644
--- a/src/adlmidi_midiplay.hpp
+++ b/src/adlmidi_midiplay.hpp
@@ -235,11 +235,16 @@ public:
Phys *phys_find(unsigned chip_chan)
{
Phys *ph = NULL;
+
for(unsigned i = 0; i < chip_channels_count && !ph; ++i)
+ {
if(chip_channels[i].chip_chan == chip_chan)
ph = &chip_channels[i];
+ }
+
return ph;
}
+
Phys *phys_find_or_create(uint16_t chip_chan)
{
Phys *ph = phys_find(chip_chan);
@@ -251,20 +256,23 @@ public:
}
return ph;
}
+
Phys *phys_ensure_find_or_create(uint16_t chip_chan)
{
Phys *ph = phys_find_or_create(chip_chan);
assert(ph);
return ph;
}
+
void phys_erase_at(const Phys *ph)
{
intptr_t pos = ph - chip_channels;
- assert(pos < static_cast<intptr_t>(chip_channels_count));
+ assert(pos >= 0 && pos < static_cast<intptr_t>(chip_channels_count));
for(intptr_t i = pos + 1; i < static_cast<intptr_t>(chip_channels_count); ++i)
chip_channels[i - 1] = chip_channels[i];
--chip_channels_count;
}
+
void phys_erase(unsigned chip_chan)
{
Phys *ph = phys_find(chip_chan);
@@ -285,6 +293,24 @@ public:
typedef pl_list<NoteInfo>::iterator notes_iterator;
typedef pl_list<NoteInfo>::const_iterator const_notes_iterator;
+ void clear_all_phys_users(unsigned chip_chan)
+ {
+ for(pl_list<NoteInfo>::iterator it = activenotes.begin(); it != activenotes.end(); )
+ {
+ NoteInfo::Phys *p = it->value.phys_find(chip_chan);
+ if(p)
+ {
+ it->value.phys_erase_at(p);
+ if(it->value.chip_channels_count == 0)
+ it = activenotes.erase(it);
+ else
+ ++it;
+ }
+ else
+ ++it;
+ }
+ }
+
notes_iterator find_activenote(unsigned note)
{
return activenotes.find_if(NoteInfo::FindPredicate(note));