diff --git a/src/ImGuiVisitor.cpp b/src/ImGuiVisitor.cpp index 5fa8551..9636d9a 100644 --- a/src/ImGuiVisitor.cpp +++ b/src/ImGuiVisitor.cpp @@ -796,11 +796,18 @@ void ImGuiVisitor::visit (MediaSource& s) if (ImGuiToolkit::TextButton("Volume")) { mp->setAudioVolume(100); } + + ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN); + int m = mp->audioVolumeMix(); + if ( ImGui::Combo("##Multiplier", &m, "None\0Alpha\0Opacity\0Alpha * Opacity\0") ) { + mp->setAudioVolumeMix( (MediaPlayer::VolumeFactorsMix) m ); + } + ImGui::SameLine(0, IMGUI_SAME_LINE); + if (ImGuiToolkit::TextButton("Multiplier")) { + mp->setAudioVolumeMix( MediaPlayer::VOLUME_ONLY ); + } } - } - - } } diff --git a/src/MediaPlayer.cpp b/src/MediaPlayer.cpp index c5cf159..f3bbb97 100644 --- a/src/MediaPlayer.cpp +++ b/src/MediaPlayer.cpp @@ -75,7 +75,10 @@ MediaPlayer::MediaPlayer() // default audio disabled audio_enabled_ = false; - audio_volume_ = 100; + audio_volume_[0] = 1.f; + audio_volume_[1] = 1.f; + audio_volume_[2] = 1.f; + audio_volume_mix_ = VOLUME_ONLY; // start index in frame_ stack write_index_ = 0; @@ -484,6 +487,9 @@ void MediaPlayer::execute_open() opened_ = true; + // set volume + setAudioVolume(); + // register media player MediaPlayer::registered_.push_back(this); } @@ -1686,8 +1692,6 @@ void MediaPlayer::setAudioEnabled(bool on) if (media_.hasaudio ) { // apply reopen(); - // reset volume - setAudioVolume(audio_volume_); } } } @@ -1695,12 +1699,50 @@ void MediaPlayer::setAudioEnabled(bool on) void MediaPlayer::setAudioVolume(int vol) { // set value - audio_volume_ = CLAMP(vol, 0, 100); + if ( !(vol < 0) ) + audio_volume_[0] = CLAMP( (float)(vol) * 0.01f, 0.f, 1.f); // apply value - if (pipeline_ && media_.hasaudio) - gst_stream_volume_set_volume (GST_STREAM_VOLUME (pipeline_), GST_STREAM_VOLUME_FORMAT_LINEAR, gdouble(audio_volume_) * 0.01); + if (pipeline_ && media_.hasaudio) { + // base volume + gdouble new_vol = (gdouble) (audio_volume_[0]); + + // apply factors + if ( audio_volume_mix_ == MediaPlayer::VOLUME_MULT_BOTH ) + new_vol *= (gdouble) (audio_volume_[1] * audio_volume_[2]); + else if ( audio_volume_mix_ == MediaPlayer::VOLUME_MULT_2 ) + new_vol *= (gdouble) (audio_volume_[2]); + else if ( audio_volume_mix_ == MediaPlayer::VOLUME_MULT_1 ) + new_vol *= (gdouble) (audio_volume_[1]); + + gst_stream_volume_set_volume (GST_STREAM_VOLUME (pipeline_), GST_STREAM_VOLUME_FORMAT_LINEAR, new_vol); + } +} + +void MediaPlayer::setAudioVolumeMix(VolumeFactorsMix m) +{ + audio_volume_mix_ = m; + setAudioVolume(); +} + +void MediaPlayer::setAudioVolumeFactor(uint index, float value) +{ + if (index > 2) + return; + + if ( ABS_DIFF( audio_volume_[index], value ) > EPSILON ) { + + // set value + audio_volume_[index] = CLAMP(value, 0.f, 1.f); + + // apply value + if ( audio_volume_mix_ == MediaPlayer::VOLUME_MULT_BOTH || + (index == 1 && audio_volume_mix_ == MediaPlayer::VOLUME_MULT_1) || + (index == 2 && audio_volume_mix_ == MediaPlayer::VOLUME_MULT_2) ) { + setAudioVolume(); + } + } } //static void audio_changed_callback (GstElement *pipeline, MediaPlayer *mp) diff --git a/src/MediaPlayer.h b/src/MediaPlayer.h index d9e0f6d..02b0ca8 100644 --- a/src/MediaPlayer.h +++ b/src/MediaPlayer.h @@ -271,10 +271,20 @@ public: * NB: setAudioEnabled reopens the video * */ void setAudioEnabled(bool on); - void setAudioVolume(int vol); + void setAudioVolume(int vol = -1); + void setAudioVolumeFactor(uint index, float value); + typedef enum { + VOLUME_ONLY = 0, + VOLUME_MULT_1 = 1, + VOLUME_MULT_2 = 2, + VOLUME_MULT_BOTH = 3 + } VolumeFactorsMix; + void setAudioVolumeMix(VolumeFactorsMix m); + inline VolumeFactorsMix audioVolumeMix() const { return audio_volume_mix_; } inline bool audioEnabled() const { return audio_enabled_; } - inline int audioVolume() const { return audio_volume_; } + inline int audioVolume() const { return (int) (audio_volume_[0] * 100.f); } inline bool audioAvailable() const { return media_.hasaudio; } + /** * Accept visitors * */ @@ -320,12 +330,15 @@ private: bool enabled_; bool rewind_on_disable_; bool force_software_decoding_; - bool audio_enabled_; - int audio_volume_; std::string decoder_name_; bool video_filter_available_; std::string video_filter_; + // audio + bool audio_enabled_; + float audio_volume_[3]; + VolumeFactorsMix audio_volume_mix_; + // Play speed gdouble rate_; typedef enum { diff --git a/src/MediaSource.cpp b/src/MediaSource.cpp index d3ab9cb..c50aab4 100644 --- a/src/MediaSource.cpp +++ b/src/MediaSource.cpp @@ -173,6 +173,14 @@ void MediaSource::update(float dt) // update video mediaplayer_->update(); + + // update audio + if (mediaplayer_->audioEnabled() ) { + // apply alpha as volume factor 1 + mediaplayer_->setAudioVolumeFactor(1, alpha()); + // apply opacity as volume factor 2 + mediaplayer_->setAudioVolumeFactor(2, mediaplayer_->currentTimelineFading()); + } } void MediaSource::render() diff --git a/src/SessionCreator.cpp b/src/SessionCreator.cpp index 3ebbbca..03a3350 100644 --- a/src/SessionCreator.cpp +++ b/src/SessionCreator.cpp @@ -898,6 +898,9 @@ void SessionLoader::visit(MediaPlayer &n) int audiovolume = 100; mediaplayerNode->QueryIntAttribute("audio_volume", &audiovolume); n.setAudioVolume(audiovolume); + int audiomix = 0; + mediaplayerNode->QueryIntAttribute("audio_mix", &audiomix); + n.setAudioVolumeMix( (MediaPlayer::VolumeFactorsMix) audiomix); bool audioenabled = false; mediaplayerNode->QueryBoolAttribute("audio", &audioenabled); n.setAudioEnabled(audioenabled); diff --git a/src/SessionVisitor.cpp b/src/SessionVisitor.cpp index 44a75d1..e3d768c 100644 --- a/src/SessionVisitor.cpp +++ b/src/SessionVisitor.cpp @@ -426,6 +426,7 @@ void SessionVisitor::visit(MediaPlayer &n) if (n.audioAvailable()) { newelement->SetAttribute("audio", n.audioEnabled()); newelement->SetAttribute("audio_volume", n.audioVolume()); + newelement->SetAttribute("audio_mix", (int) n.audioVolumeMix()); } if (!n.singleFrame()) {