diff options
-rw-r--r-- | src/adlmidi_midiplay.cpp | 57 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 13 |
2 files changed, 41 insertions, 29 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 965dc3c..0636921 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1093,10 +1093,11 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) //uint16_t i[2] = { ains.adlno1, ains.adlno2 }; bool pseudo_4op = ains->flags & adlinsdata::Flag_Pseudo4op; + size_t chans_count = (pseudo_4op || (ains->adlno1 != ains->adlno2)) ? 2 : 1; MIDIchannel::NoteInfo::Phys voices[2] = { - {ains->adlno1, false}, - {ains->adlno2, pseudo_4op} + {0, ains->adlno1, false}, + {0, ains->adlno2, pseudo_4op} }; if((opl.AdlPercussionMode == 1) && PercussionMap[midiins & 0xFF]) @@ -1112,9 +1113,9 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) } // Allocate AdLib channel (the physical sound channel for the note) - int32_t adlchannel[2] = { -1, -1 }; + int32_t adlchannel[MIDIchannel::NoteInfo::MaxNumPhysChans] = { -1, -1 }; - for(uint32_t ccount = 0; ccount < 2; ++ccount) + for(uint32_t ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount) { if(ccount == 1) { @@ -1201,14 +1202,15 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity) ir.first->tone = tone; ir.first->midiins = midiins; ir.first->insmeta = meta; + ir.first->chip_channels_max = chans_count; - for(unsigned ccount = 0; ccount < 2; ++ccount) + for(size_t ccount = 0; ccount < MIDIchannel::NoteInfo::MaxNumPhysChans; ++ccount) { int32_t c = adlchannel[ccount]; if(c < 0) continue; - uint16_t chipChan = static_cast<uint16_t>(adlchannel[ccount]); - ir.first->phys[chipChan] = voices[ccount]; + voices[ccount].chip_chan = static_cast<uint16_t>(c); + ir.first->chip_channels[ccount] = voices[ccount]; } NoteUpdate(channel, ir.first, Upd_All | Upd_Patch); return true; @@ -1444,14 +1446,10 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, my_loc.MidCh = MidCh; my_loc.note = info.note; - for(MIDIchannel::NoteInfo::PhysMap::iterator - jnext = info.phys.begin(); - jnext != info.phys.end(); - ) + for(size_t ccount = 0; ccount < info.chip_channels_max; ccount++) { - MIDIchannel::NoteInfo::PhysMap::iterator j(jnext++); - uint16_t c = j->first; - const MIDIchannel::NoteInfo::Phys &ins = j->second; + const MIDIchannel::NoteInfo::Phys &ins = info.chip_channels[ccount]; + uint16_t c = ins.chip_chan; if(select_adlchn >= 0 && c != select_adlchn) continue; @@ -1466,14 +1464,10 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, } } - for(MIDIchannel::NoteInfo::PhysMap::iterator - jnext = info.phys.begin(); - jnext != info.phys.end(); - ) + for(size_t ccount = 0; ccount < info.chip_channels_max; ccount++) { - MIDIchannel::NoteInfo::PhysMap::iterator j(jnext++); - uint16_t c = j->first; - const MIDIchannel::NoteInfo::Phys &ins = j->second; + const MIDIchannel::NoteInfo::Phys &ins = info.chip_channels[ccount]; + uint16_t c = ins.chip_chan; if(select_adlchn >= 0 && c != select_adlchn) continue; @@ -1512,7 +1506,9 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, hooks.onNote(hooks.onNote_userData, c, tone, midiins, -1, 0.0); } - info.phys.erase(j); + //info.phys.erase(j); + if(ccount == (info.chip_channels_max - 1)) + info.chip_channels_max = 0; continue; } @@ -1637,7 +1633,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, } } - if(info.phys.empty()) + if(info.chip_channels_max == 0) Ch[MidCh].activenotes_erase(i); } @@ -2251,7 +2247,9 @@ void MIDIplay::PrepareAdlChannelForNewNote(size_t c, const MIDIchannel::NoteInfo opl.NoteOff(c); } -void MIDIplay::KillOrEvacuate(size_t from_channel, AdlChannel::users_t::iterator j, MIDIplay::MIDIchannel::activenoteiterator i) +void MIDIplay::KillOrEvacuate(size_t from_channel, + AdlChannel::users_t::iterator j, + MIDIplay::MIDIchannel::activenoteiterator i) { // Before killing the note, check if it can be // evacuated to another channel as an arpeggio @@ -2291,8 +2289,15 @@ void MIDIplay::KillOrEvacuate(size_t from_channel, AdlChannel::users_t::iterator i->vol, 0.0); } - i->phys.erase(static_cast<uint16_t>(from_channel)); - i->phys[cs] = j->second.ins; + for(size_t cchan = 0; cchan < i->chip_channels_max; cchan++) + { + MIDIchannel::NoteInfo::Phys &chan = i->chip_channels[cchan]; + if(chan.chip_chan == static_cast<uint16_t>(from_channel)) + { + chan = j->second.ins; + chan.chip_chan = cs; + } + } ch[cs].users.insert(*j); ch[from_channel].users.erase(j); return; diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 08c22c0..6391f2a 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -618,8 +618,14 @@ public: size_t midiins; // Index to physical adlib data structure, adlins[] size_t insmeta; + enum + { + MaxNumPhysChans = 2 + }; struct Phys { + //! Destinition chip channel + uint16_t chip_chan; //! ins, inde to adl[] size_t insId; //! Is this voice must be detunable? @@ -634,9 +640,10 @@ public: return !operator==(oth); } }; - typedef std::map<uint16_t, Phys> PhysMap; - // List of OPL3 channels it is currently occupying. - std::map<uint16_t /*adlchn*/, Phys> phys; + //! List of OPL3 channels it is currently occupying. + Phys chip_channels[MaxNumPhysChans]; + //! Count of used channels. + size_t chip_channels_max; }; char ____padding2[5]; NoteInfo activenotes[128]; |