aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_midiplay.cpp
diff options
context:
space:
mode:
authorJP Cimalando <jpcima@users.noreply.github.com>2018-04-22 18:39:23 +0200
committerJP Cimalando <jpcima@users.noreply.github.com>2018-04-22 19:02:54 +0200
commita6f211d0fdf4b849459c44e66131e54f4d7bfda2 (patch)
treed0dbc81595d1c8eb865fa0053cfbcf4f8541f8b7 /src/adlmidi_midiplay.cpp
parentc8a9c7490e4f056ee572489b0ab73cef2a96b04f (diff)
downloadlibADLMIDI-a6f211d0fdf4b849459c44e66131e54f4d7bfda2.tar.gz
libADLMIDI-a6f211d0fdf4b849459c44e66131e54f4d7bfda2.tar.bz2
libADLMIDI-a6f211d0fdf4b849459c44e66131e54f4d7bfda2.zip
implement copy for OplChannel, and move implementations in .cpp
Diffstat (limited to 'src/adlmidi_midiplay.cpp')
-rw-r--r--src/adlmidi_midiplay.cpp130
1 files changed, 119 insertions, 11 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 88c1b39..7c40fa0 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -2434,17 +2434,7 @@ uint64_t MIDIplay::ChooseDevice(const std::string &name)
size_t n = devices.size() * 16;
devices.insert(std::make_pair(name, n));
-
- size_t channelsBefore = Ch.size();
- size_t channels = n + 16;
- Ch.resize(channels);
-
- for(size_t ch = channelsBefore; ch < channels; ++ch) {
- for(unsigned i = 0; i < 128; ++i) {
- Ch[ch].activenotes[i].note = i;
- Ch[ch].activenotes[i].active = false;
- }
- }
+ Ch.resize(n + 16);
return n;
}
@@ -2708,3 +2698,121 @@ ADLMIDI_EXPORT bool AdlInstrumentTester::HandleInputChar(char ch)
}
#endif//ADLMIDI_DISABLE_CPP_EXTRAS
+
+// Implement the user map data structure.
+
+bool MIDIplay::AdlChannel::users_empty() const
+{
+ return !users_first;
+}
+
+MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_find(Location loc)
+{
+ LocationData *user = NULL;
+ for(LocationData *curr = users_first; !user && curr; curr = curr->next)
+ if(curr->loc == loc)
+ user = curr;
+ return user;
+}
+
+MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_allocate()
+{
+ // remove free cells front
+ LocationData *user = users_free_cells;
+ if(!user)
+ return NULL;
+ users_free_cells = user->next;
+ if(users_free_cells)
+ users_free_cells->prev = NULL;
+ // add to users front
+ if(users_first)
+ users_first->prev = user;
+ user->prev = NULL;
+ user->next = users_first;
+ users_first = user;
+ ++users_size;
+ return user;
+}
+
+MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_find_or_create(Location loc)
+{
+ LocationData *user = users_find(loc);
+ if(!user) {
+ user = users_allocate();
+ if(!user)
+ return NULL;
+ LocationData *prev = user->prev, *next = user->next;
+ *user = LocationData();
+ user->prev = prev; user->next = next;
+ user->loc = loc;
+ }
+ return user;
+}
+
+MIDIplay::AdlChannel::LocationData *MIDIplay::AdlChannel::users_insert(const LocationData &x)
+{
+ LocationData *user = users_find(x.loc);
+ if(!user)
+ {
+ user = users_allocate();
+ if(!user)
+ return NULL;
+ LocationData *prev = user->prev, *next = user->next;
+ *user = x;
+ user->prev = prev; user->next = next;
+ }
+ return user;
+}
+
+void MIDIplay::AdlChannel::users_erase(LocationData *user)
+{
+ if(user->prev)
+ user->prev->next = user->next;
+ if(user->next)
+ user->next->prev = user->prev;
+ if(user == users_first)
+ users_first = user->next;
+ user->prev = NULL;
+ user->next = users_free_cells;
+ users_free_cells = user;
+ --users_size;
+}
+
+void MIDIplay::AdlChannel::users_clear()
+{
+ users_first = NULL;
+ users_free_cells = users_cells;
+ users_size = 0;
+ for(size_t i = 0; i < users_max; ++i)
+ {
+ users_cells[i].prev = (i > 0) ? &users_cells[i - 1] : NULL;
+ users_cells[i].next = (i + 1 < users_max) ? &users_cells[i + 1] : NULL;
+ }
+}
+
+void MIDIplay::AdlChannel::users_assign(const LocationData *users, size_t count)
+{
+ assert(count <= users_max);
+ if(users == users_first && users) {
+ // self assignment
+ assert(users_size == count);
+ return;
+ }
+ users_clear();
+ const LocationData *src_cell = users;
+ // move to the last
+ if(src_cell) {
+ while(src_cell->next)
+ src_cell = src_cell->next;
+ }
+ // push cell copies in reverse order
+ while(src_cell) {
+ LocationData *dst_cell = users_allocate();
+ assert(dst_cell);
+ LocationData *prev = dst_cell->prev, *next = dst_cell->next;
+ *dst_cell = *src_cell;
+ dst_cell->prev = prev; dst_cell->next = next;
+ src_cell = src_cell->prev;
+ }
+ assert(users_size == count);
+}