From 0290bbf54742edb824a384e7710f18a6f6878bc0 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Fri, 22 Sep 2023 19:09:35 +0200 Subject: [PATCH 1/3] Midi: Old tempo data was not cleared when the song changed --- src/audio_decoder_midi.cpp | 1 + 1 file changed, 1 insertion(+) mode change 100644 => 100755 src/audio_decoder_midi.cpp diff --git a/src/audio_decoder_midi.cpp b/src/audio_decoder_midi.cpp old mode 100644 new mode 100755 index f683bb800b..54bf99ea83 --- a/src/audio_decoder_midi.cpp +++ b/src/audio_decoder_midi.cpp @@ -117,6 +117,7 @@ bool AudioDecoderMidi::Open(Filesystem_Stream::InputStream stream) { return false; } seq->rewind(); + tempo.clear(); tempo.emplace_back(this, midi_default_tempo); mtime = seq->get_start_skipping_silence(); seq->play(mtime, this); From af1a7b82514dc8e9cda517b2c0d1025027e926d1 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Fri, 22 Sep 2023 19:10:33 +0200 Subject: [PATCH 2/3] Midi: Do not run fade code when fade duration is 0 This sometimes appears to break the volume of Midi on Windows as it is timing sensitive. --- src/audio_decoder_midi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/audio_decoder_midi.cpp b/src/audio_decoder_midi.cpp index 54bf99ea83..b4ee3fb495 100755 --- a/src/audio_decoder_midi.cpp +++ b/src/audio_decoder_midi.cpp @@ -224,7 +224,7 @@ void AudioDecoderMidi::Update(std::chrono::microseconds delta) { if (paused) { return; } - if (fade_steps >= 0 && mtime - last_fade_mtime > 0.1s) { + if (fade_steps > 0 && mtime - last_fade_mtime > 0.1s) { volume = Utils::Clamp(volume + delta_volume_step, 0.0f, 1.0f); if (!mididec->SupportsMidiMessages()) { log_volume = AdjustVolume(volume * 100.0f); From cd0687890f6f9d35335126ce668dac01d1fc2a68 Mon Sep 17 00:00:00 2001 From: Ghabry Date: Fri, 22 Sep 2023 19:13:38 +0200 Subject: [PATCH 3/3] Midi: When changing the song send events closer to how Harmony does it All sound off is never sent. After the GM reset harmony sends Pitch Bend Range 256 to all channels. Resetting the pitch bend fixes the corrupted audio after playing the tracks zerotwo and timetolearn in "Toilet in Wonderland". These songs indeed alter the pitch bend. Fix #2910 --- src/audio_decoder_midi.cpp | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/audio_decoder_midi.cpp b/src/audio_decoder_midi.cpp index b4ee3fb495..6874c48e3d 100755 --- a/src/audio_decoder_midi.cpp +++ b/src/audio_decoder_midi.cpp @@ -37,11 +37,15 @@ constexpr int sample_divider = 1; #endif constexpr int samples_per_play = 64 / sample_divider; -static const uint8_t midi_event_control_change = 0b1011; -static const uint8_t midi_control_volume = 7; -static const uint8_t midi_control_all_sound_off = 120; -//static const uint8_t midi_control_all_note_off = 123; -static const uint8_t midi_control_reset_all_controller = 121; +static const uint8_t midi_set_reg_param_upper = 0x6; +static const uint8_t midi_control_volume = 0x7; +static const uint8_t midi_event_control_change = 0xB; +static const uint8_t midi_set_reg_param_lower = 0x26; +//static const uint8_t midi_control_all_sound_off = 0x78; +static const uint8_t midi_control_reset_all_controller = 0x79; +//static const uint8_t midi_control_all_note_off = 0x7B; +static const uint8_t midi_set_reg_param_number_lower = 0x64; +static const uint8_t midi_set_reg_param_number_upper = 0x65; static uint32_t midimsg_make(uint8_t event_type, uint8_t channel, uint8_t value1, uint8_t value2) { uint32_t msg = 0; @@ -53,11 +57,11 @@ static uint32_t midimsg_make(uint8_t event_type, uint8_t channel, uint8_t value1 /*static uint32_t midimsg_all_note_off(uint8_t channel) { return midimsg_make(midi_event_control_change, channel, midi_control_all_note_off, 0); -}*/ +} static uint32_t midimsg_all_sound_off(uint8_t channel) { return midimsg_make(midi_event_control_change, channel, midi_control_all_sound_off, 0); -} +}*/ static uint32_t midimsg_volume(uint8_t channel, uint8_t volume) { return midimsg_make(midi_event_control_change, channel, midi_control_volume, volume); @@ -374,12 +378,26 @@ void AudioDecoderMidi::meta_event(int event, const void* data, std::size_t size) void AudioDecoderMidi::reset() { // MIDI reset event - SendMessageToAllChannels(midimsg_all_sound_off(0)); SendMessageToAllChannels(midimsg_reset_all_controller(0)); // GM system on (resets most parameters) - const unsigned char gm_reset[] = {0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7}; + const unsigned char gm_reset[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7 }; mididec->SendSysExMessage(gm_reset, sizeof(gm_reset)); + + // Set the Pitch bend range to 256 + for (int channel = 0; channel < 16; channel++) { + auto midi_msg = midimsg_make(midi_event_control_change, channel, midi_set_reg_param_number_upper, 0); + mididec->SendMidiMessage(midi_msg); + + midi_msg = midimsg_make(midi_event_control_change, channel, midi_set_reg_param_number_lower, 0); + mididec->SendMidiMessage(midi_msg); + + midi_msg = midimsg_make(midi_event_control_change, channel, midi_set_reg_param_upper, 2); + mididec->SendMidiMessage(midi_msg); + + midi_msg = midimsg_make(midi_event_control_change, channel, midi_set_reg_param_lower, 0); + mididec->SendMidiMessage(midi_msg); + } } void AudioDecoderMidi::reset_tempos_after_loop() {