diff --git a/Core/GameEngine/Include/GameClient/VideoPlayer.h b/Core/GameEngine/Include/GameClient/VideoPlayer.h index 98a7d4c8d67..4ac77a4b9dd 100644 --- a/Core/GameEngine/Include/GameClient/VideoPlayer.h +++ b/Core/GameEngine/Include/GameClient/VideoPlayer.h @@ -245,6 +245,8 @@ class VideoPlayerInterface : public SubsystemInterface virtual const FieldParse *getFieldParse() const = 0; ///< Return the field parse info virtual void notifyVideoPlayerOfNewProvider( Bool nowHasValid ) = 0; ///< Notify the video player that they can now ask for an audio handle, or they need to give theirs up. + + virtual void setVolume( Real volume ) = 0; ///< Push a new speech volume to the video player's audio output }; @@ -294,6 +296,8 @@ class VideoPlayer : public VideoPlayerInterface virtual void notifyVideoPlayerOfNewProvider( Bool nowHasValid ) override { } + virtual void setVolume( Real volume ) override { } + // Implementation specific void remove( VideoStream *stream ); ///< remove stream from active list diff --git a/Core/GameEngineDevice/Include/VideoDevice/Bink/BinkVideoPlayer.h b/Core/GameEngineDevice/Include/VideoDevice/Bink/BinkVideoPlayer.h index 38047636245..fff5709d993 100644 --- a/Core/GameEngineDevice/Include/VideoDevice/Bink/BinkVideoPlayer.h +++ b/Core/GameEngineDevice/Include/VideoDevice/Bink/BinkVideoPlayer.h @@ -101,6 +101,10 @@ class BinkVideoStream : public VideoStream class BinkVideoPlayer : public VideoPlayer { + private: + + // TheSuperHackers @bugfix Compute the Bink volume for a given speech volume. + static Int calculateMovieAudioVolume( Real speechVolume ); protected: @@ -127,6 +131,7 @@ class BinkVideoPlayer : public VideoPlayer virtual VideoStreamInterface* load( AsciiString movieTitle ) override; ///< Load video file in to memory for playback virtual void notifyVideoPlayerOfNewProvider( Bool nowHasValid ) override; + virtual void setVolume( Real volume ) override; virtual void initializeBinkWithMiles(); }; diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index 23a2cfef6ee..4f302dca1f4 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -2269,6 +2269,12 @@ void MilesAudioManager::processPlayingList() if (m_volumeHasChanged) { m_volumeHasChanged = false; + + // Push the new speech volume to any playing movie's audio output, which + // bypasses the Miles mixer and so does not see volume changes on its own. + if (TheVideoPlayer) { + TheVideoPlayer->setVolume(getVolume(AudioAffect_Speech)); + } } } diff --git a/Core/GameEngineDevice/Source/VideoDevice/Bink/BinkVideoPlayer.cpp b/Core/GameEngineDevice/Source/VideoDevice/Bink/BinkVideoPlayer.cpp index ebbc91179c1..3aaeec376f2 100644 --- a/Core/GameEngineDevice/Source/VideoDevice/Bink/BinkVideoPlayer.cpp +++ b/Core/GameEngineDevice/Source/VideoDevice/Bink/BinkVideoPlayer.cpp @@ -159,7 +159,6 @@ void BinkVideoPlayer::reset() void BinkVideoPlayer::update() { VideoPlayer::update(); - } //============================================================================ @@ -202,18 +201,38 @@ VideoStreamInterface* BinkVideoPlayer::createStream( HBINK handle ) stream->m_player = this; m_firstStream = stream; - // never let volume go to 0, as Bink will interpret that as "play at full volume". - Int mod = (Int) ((TheAudio->getVolume(AudioAffect_Speech) * 0.8f) * 100) + 1; - Int volume = (32768*mod)/100; - DEBUG_LOG(("BinkVideoPlayer::createStream() - About to set volume (%g -> %d -> %d", - TheAudio->getVolume(AudioAffect_Speech), mod, volume)); - BinkSetVolume( stream->m_handle,0, volume); - DEBUG_LOG(("BinkVideoPlayer::createStream() - set volume")); + BinkSetVolume( stream->m_handle, 0, calculateMovieAudioVolume(TheAudio->getVolume(AudioAffect_Speech)) ); } return stream; } +//============================================================================ +// BinkVideoPlayer::calculateMovieAudioVolume +//============================================================================ + +Int BinkVideoPlayer::calculateMovieAudioVolume( Real speechVolume ) +{ + // Never let volume go to 0, as Bink will interpret that as "play at full + // volume". + Int mod = (Int) ((speechVolume * 0.8f) * 100) + 1; + return (32768*mod)/100; +} + +//============================================================================ +// BinkVideoPlayer::setVolume +//============================================================================ + +void BinkVideoPlayer::setVolume( Real volume ) +{ + // Push the new volume to every open stream's audio output. + Int binkVolume = calculateMovieAudioVolume( volume ); + for ( VideoStreamInterface *stream = firstStream(); stream != nullptr; stream = stream->next() ) + { + BinkSetVolume( static_cast( stream )->m_handle, 0, binkVolume ); + } +} + //============================================================================ // BinkVideoPlayer::open //============================================================================