aboutsummaryrefslogtreecommitdiff
path: root/src/adlmidi_midiplay.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/adlmidi_midiplay.cpp')
-rw-r--r--src/adlmidi_midiplay.cpp132
1 files changed, 120 insertions, 12 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);
+}