aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_midiplay.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/adlmidi_midiplay.hpp')
-rw-r--r--src/adlmidi_midiplay.hpp164
1 files changed, 65 insertions, 99 deletions
diff --git a/src/adlmidi_midiplay.hpp b/src/adlmidi_midiplay.hpp
index 02a45a9..f4f0060 100644
--- a/src/adlmidi_midiplay.hpp
+++ b/src/adlmidi_midiplay.hpp
@@ -27,6 +27,7 @@
#include "adldata.hh"
#include "adlmidi_private.hpp"
#include "adlmidi_ptr.hpp"
+#include "structures/pl_list.hpp"
/**
* @brief Hooks of the internal events
@@ -139,8 +140,6 @@ public:
{
//! Note number
uint8_t note;
- //! Is note active
- bool active;
//! Current pressure
uint8_t vol;
//! Note vibrato (a part of Note Aftertouch feature)
@@ -165,6 +164,15 @@ public:
MaxNumPhysItemCount = MaxNumPhysChans
};
+ struct FindPredicate
+ {
+ explicit FindPredicate(unsigned note)
+ : note(note) {}
+ bool operator()(const NoteInfo &ni) const
+ { return ni.note == note; }
+ unsigned note;
+ };
+
/**
* @brief Reference to currently using chip channel
*/
@@ -244,87 +252,38 @@ public:
unsigned gliding_note_count;
//! Active notes in the channel
- NoteInfo activenotes[128];
-
- struct activenoteiterator
- {
- explicit activenoteiterator(NoteInfo *info = NULL)
- : ptr(info) {}
- activenoteiterator &operator++()
- {
- if(ptr->note == 127)
- ptr = NULL;
- else
- for(++ptr; ptr && !ptr->active;)
- ptr = (ptr->note == 127) ? NULL : (ptr + 1);
- return *this;
- }
- activenoteiterator operator++(int)
- {
- activenoteiterator pos = *this;
- ++*this;
- return pos;
- }
- NoteInfo &operator*() const
- { return *ptr; }
- NoteInfo *operator->() const
- { return ptr; }
- bool operator==(activenoteiterator other) const
- { return ptr == other.ptr; }
- bool operator!=(activenoteiterator other) const
- { return ptr != other.ptr; }
- operator NoteInfo *() const
- { return ptr; }
- private:
- NoteInfo *ptr;
- };
+ pl_list<NoteInfo> activenotes;
+ typedef typename pl_list<NoteInfo>::iterator notes_iterator;
+ typedef typename pl_list<NoteInfo>::const_iterator const_notes_iterator;
- activenoteiterator activenotes_begin()
+ notes_iterator find_activenote(unsigned note)
{
- activenoteiterator it(activenotes);
- return (it->active) ? it : ++it;
+ return activenotes.find_if(NoteInfo::FindPredicate(note));
}
- activenoteiterator activenotes_find(uint8_t note)
+ notes_iterator ensure_find_activenote(unsigned note)
{
- assert(note < 128);
- return activenoteiterator(
- activenotes[note].active ? &activenotes[note] : NULL);
- }
-
- activenoteiterator activenotes_ensure_find(uint8_t note)
- {
- activenoteiterator it = activenotes_find(note);
- assert(it);
+ notes_iterator it = find_activenote(note);
+ assert(!it.is_end());
return it;
}
- std::pair<activenoteiterator, bool> activenotes_insert(uint8_t note)
- {
- assert(note < 128);
- NoteInfo &info = activenotes[note];
- bool inserted = !info.active;
- if(inserted) info.active = true;
- return std::pair<activenoteiterator, bool>(activenoteiterator(&info), inserted);
- }
-
- void activenotes_erase(activenoteiterator pos)
- {
- if(pos)
- pos->active = false;
- }
-
- bool activenotes_empty()
+ notes_iterator find_or_create_activenote(unsigned note)
{
- return !activenotes_begin();
+ notes_iterator it = find_activenote(note);
+ if(it.is_end()) {
+ NoteInfo ni;
+ ni.note = note;
+ it = activenotes.insert(activenotes.end(), ni);
+ }
+ return it;
}
- void activenotes_clear()
+ notes_iterator ensure_find_or_create_activenote(unsigned note)
{
- for(uint8_t i = 0; i < 128; ++i) {
- activenotes[i].note = i;
- activenotes[i].active = false;
- }
+ notes_iterator it = find_or_create_activenote(note);
+ assert(!it.is_end());
+ return it;
}
/**
@@ -390,8 +349,8 @@ public:
}
MIDIchannel()
+ : activenotes(128)
{
- activenotes_clear();
gliding_note_count = 0;
reset();
}
@@ -413,7 +372,6 @@ public:
};
struct LocationData
{
- LocationData *prev, *next;
Location loc;
enum {
Sustain_None = 0x00,
@@ -429,6 +387,15 @@ public:
//! Timeout until note will be allowed to be killed by channel manager while it is on
int64_t kon_time_until_neglible_us;
int64_t vibdelay_us;
+
+ struct FindPredicate
+ {
+ explicit FindPredicate(Location loc)
+ : loc(loc) {}
+ bool operator()(const LocationData &ld) const
+ { return ld.loc == loc; }
+ Location loc;
+ };
};
//! Time left until sounding will be muted after key off
@@ -437,42 +404,41 @@ public:
//! Recently passed instrument, improves a goodness of released but busy channel when matching
MIDIchannel::NoteInfo::Phys recent_ins;
- enum { users_max = 128 };
- LocationData *users_first, *users_free_cells;
- LocationData users_cells[users_max];
- unsigned users_size;
+ pl_list<LocationData> users;
+ typedef typename pl_list<LocationData>::iterator users_iterator;
+ typedef typename pl_list<LocationData>::const_iterator const_users_iterator;
+
+ users_iterator find_user(const Location &loc)
+ {
+ return users.find_if(LocationData::FindPredicate(loc));
+ }
- bool users_empty() const;
- LocationData *users_find(Location loc);
- LocationData *users_allocate();
- LocationData *users_find_or_create(Location loc);
- LocationData *users_insert(const LocationData &x);
- void users_erase(LocationData *user);
- void users_clear();
- void users_assign(const LocationData *users, size_t count);
+ users_iterator find_or_create_user(const Location &loc)
+ {
+ users_iterator it = find_user(loc);
+ if(it.is_end() && users.size() != users.capacity())
+ {
+ LocationData ld;
+ ld.loc = loc;
+ it = users.insert(users.end(), ld);
+ }
+ return it;
+ }
// For channel allocation:
- AdlChannel(): koff_time_until_neglible_us(0)
+ AdlChannel(): koff_time_until_neglible_us(0), users(128)
{
- users_clear();
std::memset(&recent_ins, 0, sizeof(MIDIchannel::NoteInfo::Phys));
}
- AdlChannel(const AdlChannel &oth): koff_time_until_neglible_us(oth.koff_time_until_neglible_us)
+ AdlChannel(const AdlChannel &oth): koff_time_until_neglible_us(oth.koff_time_until_neglible_us), users(oth.users)
{
- if(oth.users_first)
- {
- users_first = NULL;
- users_assign(oth.users_first, oth.users_size);
- }
- else
- users_clear();
}
AdlChannel &operator=(const AdlChannel &oth)
{
koff_time_until_neglible_us = oth.koff_time_until_neglible_us;
- users_assign(oth.users_first, oth.users_size);
+ users = oth.users;
return *this;
}
@@ -899,7 +865,7 @@ private:
* @param select_adlchn Specify chip channel, or -1 - all chip channels used by the note
*/
void noteUpdate(size_t midCh,
- MIDIchannel::activenoteiterator i,
+ MIDIchannel::notes_iterator i,
unsigned props_mask,
int32_t select_adlchn = -1);
@@ -934,8 +900,8 @@ private:
*/
void killOrEvacuate(
size_t from_channel,
- AdlChannel::LocationData *j,
- MIDIchannel::activenoteiterator i);
+ AdlChannel::users_iterator j,
+ MIDIchannel::notes_iterator i);
/**
* @brief Off all notes and silence sound