From 05aaf430227460fcb7beabecd8ee9252808af846 Mon Sep 17 00:00:00 2001 From: mnabil Date: Tue, 7 Jul 2020 01:00:36 +0200 Subject: [PATCH] Player volume fix for issue #276 midiplayer.cpp -> volumechanged event is treated separately in order to include the maxVolume threshold midievent.cpp -> added a check isVolumeChange() --- source/audio/midiplayer.cpp | 43 ++++++++++++++++++++++++++++++++++++- source/audio/midiplayer.h | 3 +++ source/midi/midievent.cpp | 5 +++++ source/midi/midievent.h | 1 + 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/source/audio/midiplayer.cpp b/source/audio/midiplayer.cpp index aba3b69aa..d96aa3380 100644 --- a/source/audio/midiplayer.cpp +++ b/source/audio/midiplayer.cpp @@ -185,11 +185,29 @@ void MidiPlayer::run() if (!(event->isNoteOnOff() && event->getChannel() == METRONOME_CHANNEL && !myMetronomeEnabled) && - !event->isTempoChange() && !event->isTrackEnd()) + !event->isTempoChange() && + !event->isTrackEnd() && + !event->isVolumeChange()) { device.sendMessage(event->getData()); } + // get the channel and the correspondin player + int channel = event->getChannel(); + int player = getPlayerFromChannel(channel); + // if the channel corresponds to a valid player, set its maximum volume + if(player != -1) + { + device.setChannelMaxVolume(channel, myScore.getPlayers()[player].getMaxVolume()); + } + // handle volume change events + // using device.setVolume() ensures that the maximum volume threshold + // is taken into consideration + if(event -> isVolumeChange()) + { + device.setVolume(channel, event->getData()[2]); + } + // Notify listeners of the current playback position. if (event->getLocation() != current_location) { @@ -279,3 +297,26 @@ bool MidiPlayer::isPlaying() const { return myIsPlaying; } + +int MidiPlayer::getPlayerFromChannel(const int channel) +{ + int player; + + //check for invalid channel + if (METRONOME_CHANNEL == channel || 15 == channel) + { + player = -1; + } + else if (channel < METRONOME_CHANNEL) + { + player = channel; + } + else if (channel > METRONOME_CHANNEL) + { + player = channel - 1; + } + + return player; + +} + diff --git a/source/audio/midiplayer.h b/source/audio/midiplayer.h index 75ba4e0ba..d61c5e921 100644 --- a/source/audio/midiplayer.h +++ b/source/audio/midiplayer.h @@ -59,6 +59,9 @@ class MidiPlayer : public QThread void setIsPlaying(bool set); bool isPlaying() const; + // gets the player index for a specific channel + static int getPlayerFromChannel(const int channel); + SettingsManager &mySettingsManager; const Score &myScore; ScoreLocation myStartLocation; diff --git a/source/midi/midievent.cpp b/source/midi/midievent.cpp index 02c7c18cd..83589ea20 100644 --- a/source/midi/midievent.cpp +++ b/source/midi/midievent.cpp @@ -63,6 +63,11 @@ bool MidiEvent::isTempoChange() const myData[1] == MetaType::SetTempo; } +bool MidiEvent::isVolumeChange() const +{ + return myData[1] == Controller::ChannelVolume; +} + bool MidiEvent::isTrackEnd() const { return getStatusByte() == StatusByte::MetaMessage && diff --git a/source/midi/midievent.h b/source/midi/midievent.h index 6b9ea5c04..5a8152469 100644 --- a/source/midi/midievent.h +++ b/source/midi/midievent.h @@ -58,6 +58,7 @@ class MidiEvent const SystemLocation &getLocation() const { return myLocation; } bool isTempoChange() const; + bool isVolumeChange() const; bool isTrackEnd() const; Midi::Tempo getTempo() const; bool isProgramChange() const;