aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWohlstand <admin@wohlnet.ru>2025-05-23 01:21:06 +0300
committerWohlstand <admin@wohlnet.ru>2025-05-23 01:26:03 +0300
commitc09823a10cd31fc12764bb5406f0a43ed38a1a3d (patch)
tree48e6a6df819d23a3f44c59ce0b4522dd27f28c50
parent3520c0d82863cdafafc0cff26f7909dea4840ad9 (diff)
downloadlibADLMIDI-c09823a10cd31fc12764bb5406f0a43ed38a1a3d.tar.gz
libADLMIDI-c09823a10cd31fc12764bb5406f0a43ed38a1a3d.tar.bz2
libADLMIDI-c09823a10cd31fc12764bb5406f0a43ed38a1a3d.zip
Experiment: Allow multiple note dupes on same channel
Should fix the problem of some of Heretic songs
-rw-r--r--src/adlmidi_midiplay.cpp10
-rw-r--r--src/adlmidi_midiplay.hpp15
2 files changed, 22 insertions, 3 deletions
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index 22019c8..b27ed13 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -331,14 +331,18 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(static_cast<size_t>(channel) > m_midiChannels.size())
channel = channel % 16;
- noteOff(channel, note, velocity != 0);
+
+ //noteOff(channel, note, velocity != 0);
// On Note on, Keyoff the note first, just in case keyoff
// was omitted; this fixes Dance of sugar-plum fairy
// by Microsoft. Now that we've done a Keyoff,
// check if we still need to do a Keyon.
// vol=0 and event 8x are both Keyoff-only.
if(velocity == 0)
+ {
+ noteOff(channel, note, false);
return false;
+ }
MIDIchannel &midiChan = m_midiChannels[channel];
@@ -492,7 +496,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
if(isBlankNote)
{
// Don't even try to play the blank instrument! But, insert the dummy note.
- MIDIchannel::notes_iterator i = midiChan.ensure_find_or_create_activenote(note);
+ MIDIchannel::notes_iterator i = midiChan.ensure_create_activenote(note);
MIDIchannel::NoteInfo &dummy = i->value;
dummy.isBlank = true;
dummy.isOnExtendedLifeTime = false;
@@ -613,7 +617,7 @@ bool MIDIplay::realTime_NoteOn(uint8_t channel, uint8_t note, uint8_t velocity)
velocity = static_cast<uint8_t>(std::floor(static_cast<float>(velocity) * 0.8f));
// Allocate active note for MIDI channel
- MIDIchannel::notes_iterator ir = midiChan.ensure_find_or_create_activenote(note);
+ MIDIchannel::notes_iterator ir = midiChan.ensure_create_activenote(note);
MIDIchannel::NoteInfo &ni = ir->value;
ni.vol = velocity;
ni.vibrato = midiChan.noteAftertouch[note];
diff --git a/src/adlmidi_midiplay.hpp b/src/adlmidi_midiplay.hpp
index dd5b34e..6ab0915 100644
--- a/src/adlmidi_midiplay.hpp
+++ b/src/adlmidi_midiplay.hpp
@@ -311,6 +311,14 @@ public:
return it;
}
+ notes_iterator create_activenote(unsigned note)
+ {
+ NoteInfo ni;
+ ni.note = note;
+ notes_iterator it = activenotes.insert(activenotes.end(), ni);
+ return it;
+ }
+
notes_iterator ensure_find_or_create_activenote(unsigned note)
{
notes_iterator it = find_or_create_activenote(note);
@@ -318,6 +326,13 @@ public:
return it;
}
+ notes_iterator ensure_create_activenote(unsigned note)
+ {
+ notes_iterator it = create_activenote(note);
+ assert(!it.is_end());
+ return it;
+ }
+
/**
* @brief Reset channel into initial state
*/