diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/adlmidi_midiplay.cpp | 132 | ||||
-rw-r--r-- | src/adlmidi_private.hpp | 108 |
2 files changed, 153 insertions, 87 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 702ebea..7c40fa0 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1618,7 +1618,7 @@ void MIDIplay::NoteUpdate(uint16_t MidCh, phase = ains.voice2_fine_tune;//0.125; // Detune the note slightly (this is what Doom does) } - if(Ch[MidCh].vibrato && d->vibdelay >= Ch[MidCh].vibdelay) + if(Ch[MidCh].vibrato && (!d || d->vibdelay >= Ch[MidCh].vibdelay)) bend += Ch[MidCh].vibrato * Ch[MidCh].vibdepth * std::sin(Ch[MidCh].vibpos); #ifdef ADLMIDI_USE_DOSBOX_OPL @@ -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); +} diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp index 3532126..0fabf35 100644 --- a/src/adlmidi_private.hpp +++ b/src/adlmidi_private.hpp @@ -736,6 +736,7 @@ public: activenoteiterator activenotes_find(uint8_t note) { + assert(note < 128); return activenoteiterator( activenotes[note].active ? &activenotes[note] : 0); } @@ -749,6 +750,7 @@ public: 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; @@ -766,6 +768,14 @@ public: return !activenotes_begin(); } + void activenotes_clear() + { + for(unsigned i = 0; i < 128; ++i) { + activenotes[i].note = i; + activenotes[i].active = false; + } + } + void reset() { resetAllControllers(); @@ -794,8 +804,8 @@ public: brightness = 127; } MIDIchannel() - : activenotes() { + activenotes_clear(); reset(); } }; @@ -831,85 +841,33 @@ public: LocationData users_cells[users_max]; unsigned users_size; - bool users_empty() const - { return !users_first; } - LocationData *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; - } - LocationData *users_allocate() - { - // remove free cells front - LocationData *user = users_free_cells; - if(!user) - return NULL; - users_free_cells = user->next; - 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; - } - LocationData *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; - } - LocationData *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 users_erase(LocationData *user) + 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); + + // For channel allocation: + AdlChannel(): koff_time_until_neglible(0) { - 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; + users_clear(); } - // For channel allocation: - AdlChannel(): koff_time_until_neglible(0), users_first(NULL), users_size(0) + AdlChannel(const AdlChannel &oth): koff_time_until_neglible(oth.koff_time_until_neglible) { - users_free_cells = users_cells; - 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; - } + users_assign(oth.users_first, oth.users_size); } + + AdlChannel &operator=(const AdlChannel &oth) + { + koff_time_until_neglible = oth.koff_time_until_neglible; + users_assign(oth.users_first, oth.users_size); + return *this; + } + void AddAge(int64_t ms); }; |