From a6f211d0fdf4b849459c44e66131e54f4d7bfda2 Mon Sep 17 00:00:00 2001 From: JP Cimalando Date: Sun, 22 Apr 2018 18:39:23 +0200 Subject: implement copy for OplChannel, and move implementations in .cpp --- src/adlmidi_midiplay.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 119 insertions(+), 11 deletions(-) (limited to 'src/adlmidi_midiplay.cpp') 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); +} -- cgit v1.2.3