aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJP Cimalando <jpcima@users.noreply.github.com>2018-04-18 16:18:37 +0200
committerJP Cimalando <jpcima@users.noreply.github.com>2018-04-18 17:17:28 +0200
commit26388a7cd07a365e4256b0308c3aa87772accd41 (patch)
tree92de37a1755d6de96853835269221ae2d5f656f5
parentf87aa4d29c638d77501ec9474d213262238b9d1d (diff)
downloadlibADLMIDI-26388a7cd07a365e4256b0308c3aa87772accd41.tar.gz
libADLMIDI-26388a7cd07a365e4256b0308c3aa87772accd41.tar.bz2
libADLMIDI-26388a7cd07a365e4256b0308c3aa87772accd41.zip
reformulated phys code into original map semantics
-rw-r--r--src/adlmidi_midiplay.cpp50
-rw-r--r--src/adlmidi_private.hpp67
2 files changed, 86 insertions, 31 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 965dc3c..ea40d50 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -1093,10 +1093,10 @@ 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;
- MIDIchannel::NoteInfo::Phys voices[2] =
+ MIDIchannel::NoteInfo::Phys voices[MIDIchannel::NoteInfo::MaxNumPhysChans] =
{
- {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 +1112,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 +1201,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_count = 0;
- for(unsigned ccount = 0; ccount < 2; ++ccount)
+ for(unsigned 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];
+ ir.first->phys_ensure_find_or_create(chipChan)->assign(voices[ccount]);
}
NoteUpdate(channel, ir.first, Upd_All | Upd_Patch);
return true;
@@ -1444,14 +1445,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(unsigned ccount = 0, ctotal = info.chip_channels_count; ccount < ctotal; 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 +1463,10 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
}
}
- for(MIDIchannel::NoteInfo::PhysMap::iterator
- jnext = info.phys.begin();
- jnext != info.phys.end();
- )
+ for(unsigned ccount = 0; ccount < info.chip_channels_count; 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 +1505,8 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
hooks.onNote(hooks.onNote_userData, c, tone, midiins, -1, 0.0);
}
- info.phys.erase(j);
+ info.phys_erase_at(&ins); // decrements channel count
+ --ccount; // adjusts index accordingly
continue;
}
@@ -1637,7 +1631,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh,
}
}
- if(info.phys.empty())
+ if(info.chip_channels_count == 0)
Ch[MidCh].activenotes_erase(i);
}
@@ -2223,7 +2217,7 @@ void MIDIplay::PrepareAdlChannelForNewNote(size_t c, const MIDIchannel::NoteInfo
// Collision: Kill old note,
// UNLESS we're going to do arpeggio
MIDIchannel::activenoteiterator i
- (Ch[j->first.MidCh].activenotes_find(j->first.note));
+ (Ch[j->first.MidCh].activenotes_ensure_find(j->first.note));
// Check if we can do arpeggio.
if((j->second.vibdelay < 70
@@ -2291,8 +2285,8 @@ 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;
+ i->phys_erase(static_cast<uint16_t>(from_channel));
+ i->phys_ensure_find_or_create(cs)->assign(j->second.ins);
ch[cs].users.insert(*j);
ch[from_channel].users.erase(j);
return;
@@ -2510,7 +2504,7 @@ retry_arpeggio:
{
NoteUpdate(
i->first.MidCh,
- Ch[ i->first.MidCh ].activenotes_find(i->first.note),
+ Ch[ i->first.MidCh ].activenotes_ensure_find(i->first.note),
Upd_Off,
static_cast<int32_t>(c));
goto retry_arpeggio;
@@ -2518,7 +2512,7 @@ retry_arpeggio:
NoteUpdate(
i->first.MidCh,
- Ch[ i->first.MidCh ].activenotes_find(i->first.note),
+ Ch[ i->first.MidCh ].activenotes_ensure_find(i->first.note),
Upd_Pitch | Upd_Volume | Upd_Pan,
static_cast<int32_t>(c));
}
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 08c22c0..69a833c 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -87,6 +87,7 @@ typedef int32_t ssize_t;
#include <cmath>
#include <cstdarg>
#include <cstdio>
+#include <cassert>
#if !(defined(__APPLE__) && defined(__GLIBCXX__))
#include <cinttypes> //PRId32, PRIu32, etc.
#else
@@ -618,13 +619,25 @@ public:
size_t midiins;
// Index to physical adlib data structure, adlins[]
size_t insmeta;
+ enum
+ {
+ MaxNumPhysChans = 2,
+ MaxNumPhysItemCount = MaxNumPhysChans,
+ };
struct Phys
{
+ //! Destination chip channel
+ uint16_t chip_chan;
//! ins, inde to adl[]
size_t insId;
//! Is this voice must be detunable?
bool pseudo4op;
+ void assign(const Phys &oth)
+ {
+ insId = oth.insId;
+ pseudo4op = oth.pseudo4op;
+ }
bool operator==(const Phys &oth) const
{
return (insId == oth.insId) && (pseudo4op == oth.pseudo4op);
@@ -634,9 +647,50 @@ 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[MaxNumPhysItemCount];
+ //! Count of used channels.
+ unsigned chip_channels_count;
+ //
+ 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(unsigned chip_chan)
+ {
+ Phys *ph = phys_find(chip_chan);
+ if(!ph) {
+ if(chip_channels_count < MaxNumPhysItemCount) {
+ ph = &chip_channels[chip_channels_count++];
+ ph->chip_chan = chip_chan;
+ }
+ }
+ return ph;
+ }
+ Phys *phys_ensure_find_or_create(unsigned chip_chan)
+ {
+ Phys *ph = phys_find_or_create(chip_chan);
+ assert(ph);
+ return ph;
+ }
+ void phys_erase_at(const Phys *ph)
+ {
+ unsigned pos = ph - chip_channels;
+ assert(pos < chip_channels_count);
+ for(unsigned i = pos + 1; i < 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);
+ if(ph)
+ phys_erase_at(ph);
+ }
};
char ____padding2[5];
NoteInfo activenotes[128];
@@ -686,6 +740,13 @@ public:
activenotes[note].active ? &activenotes[note] : 0);
}
+ activenoteiterator activenotes_ensure_find(uint8_t note)
+ {
+ activenoteiterator it = activenotes_find(note);
+ assert(it);
+ return it;
+ }
+
std::pair<activenoteiterator, bool> activenotes_insert(uint8_t note)
{
NoteInfo &info = activenotes[note];