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..be5198a81ea 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: + + static Int calculateMovieAudioVolume( Real volume ); + Bool m_volumeApplied; 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/Include/VideoDevice/FFmpeg/FFmpegVideoPlayer.h b/Core/GameEngineDevice/Include/VideoDevice/FFmpeg/FFmpegVideoPlayer.h index 2d6e55d7053..71ec8046905 100644 --- a/Core/GameEngineDevice/Include/VideoDevice/FFmpeg/FFmpegVideoPlayer.h +++ b/Core/GameEngineDevice/Include/VideoDevice/FFmpeg/FFmpegVideoPlayer.h @@ -121,6 +121,7 @@ class FFmpegVideoPlayer : public VideoPlayer virtual VideoStreamInterface* load( AsciiString movieTitle ); ///< Load video file in to memory for playback virtual void notifyVideoPlayerOfNewProvider( Bool nowHasValid ); + virtual void setVolume( Real volume ); virtual void initializeBinkWithMiles(); }; diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index 23a2cfef6ee..e261d101ba8 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -2269,6 +2269,11 @@ void MilesAudioManager::processPlayingList() if (m_volumeHasChanged) { m_volumeHasChanged = false; + + // Push speech volume changes because Bink movie audio bypasses the Miles mixer. + 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..5afb42e4063 100644 --- a/Core/GameEngineDevice/Source/VideoDevice/Bink/BinkVideoPlayer.cpp +++ b/Core/GameEngineDevice/Source/VideoDevice/Bink/BinkVideoPlayer.cpp @@ -108,6 +108,7 @@ //============================================================================ BinkVideoPlayer::BinkVideoPlayer() +: m_volumeApplied(FALSE) { } @@ -160,6 +161,12 @@ void BinkVideoPlayer::update() { VideoPlayer::update(); + // createStream() is too early; apply once a live stream exists. + if ( !m_volumeApplied && firstStream() != nullptr ) + { + setVolume( TheAudio->getVolume(AudioAffect_Speech) ); + m_volumeApplied = TRUE; + } } //============================================================================ @@ -201,19 +208,37 @@ VideoStreamInterface* BinkVideoPlayer::createStream( HBINK handle ) stream->m_next = m_firstStream; 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")); + m_volumeApplied = FALSE; } return stream; } +//============================================================================ +// BinkVideoPlayer::calculateMovieAudioVolume +//============================================================================ + +Int BinkVideoPlayer::calculateMovieAudioVolume( Real volume ) +{ + // Never let volume go to 0, as Bink will interpret that as "play at full volume". + Int mod = (Int) ((volume * 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 //============================================================================ diff --git a/Core/GameEngineDevice/Source/VideoDevice/FFmpeg/FFmpegVideoPlayer.cpp b/Core/GameEngineDevice/Source/VideoDevice/FFmpeg/FFmpegVideoPlayer.cpp index a8a1e6ec83e..15400f88357 100644 --- a/Core/GameEngineDevice/Source/VideoDevice/FFmpeg/FFmpegVideoPlayer.cpp +++ b/Core/GameEngineDevice/Source/VideoDevice/FFmpeg/FFmpegVideoPlayer.cpp @@ -208,13 +208,7 @@ VideoStreamInterface* FFmpegVideoPlayer::createStream( File* file ) 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; - [[maybe_unused]] Int volume = (32768 * mod) / 100; - DEBUG_LOG(("FFmpegVideoPlayer::createStream() - About to set volume (%g -> %d -> %d", - TheAudio->getVolume(AudioAffect_Speech), mod, volume)); - //BinkSetVolume( stream->m_handle,0, volume); - DEBUG_LOG(("FFmpegVideoPlayer::createStream() - set volume")); + setVolume( TheAudio->getVolume(AudioAffect_Speech) ); } return stream; @@ -272,6 +266,26 @@ VideoStreamInterface* FFmpegVideoPlayer::load( AsciiString movieTitle ) return open(movieTitle); // load() used to have the same body as open(), so I'm combining them. Munkee. } +//============================================================================ +// FFmpegVideoPlayer::setVolume +//============================================================================ + +void FFmpegVideoPlayer::setVolume( [[maybe_unused]] Real volume ) +{ +#ifdef RTS_USE_OPENAL + if ( firstStream() == nullptr ) + { + return; + } + + OpenALAudioStream* audioStream = (OpenALAudioStream*)TheAudio->getHandleForBink(); + if ( audioStream ) + { + audioStream->setVolume( volume ); + } +#endif +} + //============================================================================ //============================================================================ void FFmpegVideoPlayer::notifyVideoPlayerOfNewProvider( Bool nowHasValid ) @@ -315,6 +329,7 @@ FFmpegVideoStream::FFmpegVideoStream(FFmpegFile* file) // Release the audio handle if it's already in use OpenALAudioStream* audioStream = (OpenALAudioStream*)TheAudio->getHandleForBink(); audioStream->reset(); + audioStream->setVolume(TheAudio->getVolume(AudioAffect_Speech)); #endif // Decode until we have our first video frame