Skip to content

Commit

Permalink
BugFix Implementation of Audio in Source
Browse files Browse the repository at this point in the history
Generalized audio support into Source class, instead of MediaPlayer.
  • Loading branch information
brunoherbelin committed Apr 21, 2024
1 parent 3e45ec7 commit 7b5bc6d
Show file tree
Hide file tree
Showing 13 changed files with 248 additions and 156 deletions.
48 changes: 0 additions & 48 deletions src/ImGuiVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -740,54 +740,6 @@ void ImGuiVisitor::visit (MediaSource& s)
ImGui::TextDisabled("Hardware decoding disabled");
}

// enable / disable audio if available
if (mp->audioAvailable()) {

ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if (ImGui::BeginCombo("Audio", mp->audioEnabled() ? ICON_FA_VOLUME_UP " Enabled" : ICON_FA_VOLUME_MUTE " Disabled" ) )
{
if (ImGui::Selectable( ICON_FA_VOLUME_UP " Enable", mp->audioEnabled() ))
mp->setAudioEnabled(true);
if (ImGui::IsItemHovered() && !mp->audioEnabled())
ImGuiToolkit::ToolTip( "Changing audio will\nre-open the media" );

if (ImGui::Selectable( ICON_FA_VOLUME_MUTE " Disable", !mp->audioEnabled() ))
mp->setAudioEnabled(false);
if (ImGui::IsItemHovered() && mp->audioEnabled())
ImGuiToolkit::ToolTip( "Changing audio will\nre-open the media" );
ImGui::EndCombo();
}

if (mp->audioEnabled()) {

ImGuiIO& io = ImGui::GetIO();
///
/// AUDIO VOLUME
///
int vol = mp->audioVolume();
ImGui::SetNextItemWidth(IMGUI_RIGHT_ALIGN);
if ( ImGui::SliderInt("##Volume", &vol, 0, 100, "%d%%") )
mp->setAudioVolume(vol);
if (ImGui::IsItemHovered() && io.MouseWheel != 0.f ){
vol = CLAMP(vol + int(10.f * io.MouseWheel), 0, 100);
mp->setAudioVolume(vol);
}
ImGui::SameLine(0, IMGUI_SAME_LINE);
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 );
}
}
}
}
else
ImGui::SetCursorPos(botom);
Expand Down
66 changes: 10 additions & 56 deletions src/MediaPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ MediaPlayer::MediaPlayer()
opened_ = false;
enabled_ = true;
desired_state_ = GST_STATE_PAUSED;
audio_enabled_ = false;

failed_ = false;
pending_ = false;
Expand All @@ -77,13 +78,6 @@ MediaPlayer::MediaPlayer()
loop_ = LoopMode::LOOP_REWIND;
fading_mode_ = FadingMode::FADING_COLOR;

// default audio disabled
audio_enabled_ = false;
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;
last_index_ = 0;
Expand Down Expand Up @@ -517,8 +511,6 @@ void MediaPlayer::execute_open()

if (media_.hasaudio) {
Log::Info("MediaPlayer %s Audio track %s", std::to_string(id_).c_str(), audio_enabled_ ? "enabled" : "disabled");
if (audio_enabled_)
setAudioVolume();
}

opened_ = true;
Expand Down Expand Up @@ -1727,14 +1719,12 @@ void MediaPlayer::TimeCounter::tic ()
}
}


void MediaPlayer::setAudioEnabled(bool on)
{
// in case of change
if (audio_enabled_ != on) {
// toggle
audio_enabled_ = on;

// if openned
if (media_.hasaudio ) {
// apply
Expand All @@ -1743,55 +1733,19 @@ void MediaPlayer::setAudioEnabled(bool on)
}
}

void MediaPlayer::setAudioVolume(int vol)
{
// set value
if ( !(vol < 0) )
audio_volume_[0] = CLAMP( (float)(vol) * 0.01f, 0.f, 1.f);

// apply value
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]);


g_object_set ( G_OBJECT (pipeline_), "volume", new_vol, NULL);
// gst_stream_volume_set_volume (GST_STREAM_VOLUME (pipeline_), GST_STREAM_VOLUME_FORMAT_LINEAR, new_vol);
}
}

void MediaPlayer::setAudioVolumeMix(VolumeFactorsMix m)
void MediaPlayer::setAudioVolume(float vol)
{
audio_volume_mix_ = m;
setAudioVolume();
if (pipeline_ && media_.hasaudio)
g_object_set(G_OBJECT(pipeline_), "volume", vol, NULL);
// gst_stream_volume_set_volume (GST_STREAM_VOLUME (pipeline_), GST_STREAM_VOLUME_FORMAT_LINEAR, vol);
}

void MediaPlayer::setAudioVolumeFactor(uint index, float value)
float MediaPlayer::audioVolume() const
{
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();
}
}
float vol = 0.f;
if (pipeline_ && media_.hasaudio)
g_object_get(G_OBJECT(pipeline_), "volume", &vol, NULL);
return vol;
}

//static void audio_changed_callback (GstElement *pipeline, MediaPlayer *mp)
Expand Down
25 changes: 5 additions & 20 deletions src/MediaPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,23 +277,12 @@ class MediaPlayer {
inline std::string videoEffect() { return video_filter_; }
inline bool videoEffectAvailable() { return video_filter_available_; }
/**
* Enables or disables audio
* NB: setAudioEnabled reopens the video
* audio implementation
* */
void setAudioEnabled(bool on);
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 (int) (audio_volume_[0] * 100.f); }
inline bool audioAvailable() const { return media_.hasaudio; }
void setAudioEnabled(bool on);
void setAudioVolume(float v);
float audioVolume() const;

/**
* Accept visitors
Expand Down Expand Up @@ -326,6 +315,7 @@ class MediaPlayer {
Timeline timeline_;
FadingMode fading_mode_;
std::future<MediaInfo> discoverer_;
bool audio_enabled_;

// GST & Play status
GstClockTime position_;
Expand All @@ -345,11 +335,6 @@ class MediaPlayer {
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 {
Expand Down
45 changes: 37 additions & 8 deletions src/MediaSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include <glm/gtc/matrix_transform.hpp>

#include "defines.h"
#include "Resource.h"
#include "Decorations.h"
#include "MediaPlayer.h"
Expand Down Expand Up @@ -121,6 +122,10 @@ void MediaSource::init()
// deep update to reorder (two frames to give time to insert)
View::need_deep_update_ += 2;

// test audio is available
if (mediaplayer_->audioAvailable())
audio_flags_ |= Source::Audio_available;

// done init
Log::Info("Source '%s' linked to MediaPlayer %s.", name().c_str(), std::to_string(mediaplayer_->id()).c_str());
}
Expand Down Expand Up @@ -178,13 +183,31 @@ void MediaSource::update(float dt)

// update video
mediaplayer_->update();
}

void MediaSource::updateAudio()
{
// update enable/ disable status of audio of media player (do nothing if no change)
mediaplayer_->setAudioEnabled( audio_flags_ & Source::Audio_enabled );

// update audio volume if enabled
if (audio_flags_ & Source::Audio_enabled) {

// 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());
// base volume
gdouble new_vol = (gdouble) (audio_volume_[VOLUME_BASE]);

// apply factors
if (audio_volume_mix_ & Source::Volume_mult_alpha)
new_vol *= (gdouble) (alpha());
if (audio_volume_mix_ & Source::Volume_mult_opacity)
new_vol *= (gdouble) (mediaplayer_->currentTimelineFading());
if (audio_volume_mix_ & Source::Volume_mult_parent)
new_vol *= (gdouble) (audio_volume_[VOLUME_PARENT]);
if (audio_volume_mix_ & Source::Volume_mult_session)
new_vol *= (gdouble) (audio_volume_[VOLUME_SESSION]);

// implementation for media player gstreamer pipeline
mediaplayer_->setAudioVolume(new_vol);
}
}

Expand All @@ -197,10 +220,16 @@ void MediaSource::render()
// NB: this also applies the color correction shader
renderbuffer_->begin();
// apply fading
if (mediaplayer_->timelineFadingMode() != MediaPlayer::FADING_ALPHA)
float __f = mediaplayer_->currentTimelineFading();
setAudioVolumeFactor(Source::VOLUME_OPACITY, __f);
if (mediaplayer_->timelineFadingMode() != MediaPlayer::FADING_ALPHA) {
// color fading
texturesurface_->shader()->color = glm::vec4( glm::vec3(mediaplayer_->currentTimelineFading()), 1.f);
else
}
else {
// alpha fading
texturesurface_->shader()->color = glm::vec4( glm::vec3(1.f), mediaplayer_->currentTimelineFading());
}
texturesurface_->draw(glm::identity<glm::mat4>(), renderbuffer_->projection());
renderbuffer_->end();
ready_ = true;
Expand Down
1 change: 1 addition & 0 deletions src/MediaSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class MediaSource : public Source
Failure failed() const override;
uint texture() const override;
void accept (Visitor& v) override;
void updateAudio() override;

// Media specific interface
void setPath(const std::string &p);
Expand Down
3 changes: 3 additions & 0 deletions src/Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,9 @@ void Session::update(float dt)
// render the source
(*it)->render();
}

// apply session fading to audio
(*it)->setAudioVolumeFactor(Source::VOLUME_SESSION, 1.f - render_.fading());
}

// update session's mixing groups
Expand Down
21 changes: 10 additions & 11 deletions src/SessionCreator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,17 +919,6 @@ void SessionLoader::visit(MediaPlayer &n)
n.setTimeline(tl);
}

// audio
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);

// change play rate: will be activated in SessionLoader::visit (MediaSource& s)
double speed = 1.0;
mediaplayerNode->QueryDoubleAttribute("speed", &speed);
Expand Down Expand Up @@ -1113,6 +1102,16 @@ void SessionLoader::visit (Source& s)
groups_sources_id_.push_back(idlist);
}

xmlCurrent_ = sourceNode->FirstChildElement("Audio");
if (xmlCurrent_) {
bool on = xmlCurrent_->BoolAttribute("enabled", false);
s.setAudioEnabled(on);
float volume = xmlCurrent_->FloatAttribute("volume", 1.f);
s.setAudioVolumeFactor(Source::VOLUME_BASE, volume);
int mix = xmlCurrent_->IntAttribute("volume_mix", 0);
s.setAudioVolumeMix( Source::Volume_mult_parent | mix);
}

// restore current
xmlCurrent_ = sourceNode;

Expand Down
5 changes: 5 additions & 0 deletions src/SessionSource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ void SessionSource::update(float dt)
timer_ += guint64(dt * 1000.f) * GST_USECOND;
}

// update audio
for (auto it = session_->begin(); it != session_->end(); ++it) {
(*it)->setAudioVolumeFactor(Source::VOLUME_PARENT, blendingshader_->color.a);
}

// manage sources which failed
if ( !session_->failedSources().empty() ) {

Expand Down
12 changes: 6 additions & 6 deletions src/SessionVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,6 @@ void SessionVisitor::visit(MediaPlayer &n)
XMLElement *newelement = xmlDoc_->NewElement("MediaPlayer");
newelement->SetAttribute("id", n.id());

if (n.audioAvailable()) {
newelement->SetAttribute("audio", n.audioEnabled());
newelement->SetAttribute("audio_volume", n.audioVolume());
newelement->SetAttribute("audio_mix", (int) n.audioVolumeMix());
}

if (!n.singleFrame()) {
newelement->SetAttribute("loop", (int) n.loop());
newelement->SetAttribute("speed", n.playSpeed());
Expand Down Expand Up @@ -661,6 +655,12 @@ void SessionVisitor::visit (Source& s)
s.mixingGroup()->accept(*this);
}

xmlCurrent_ = xmlDoc_->NewElement( "Audio" );
xmlCurrent_->SetAttribute("enabled", (bool) (s.audioFlags() & Source::Audio_enabled) );
xmlCurrent_->SetAttribute("volume", s.audioVolumeFactor(Source::VOLUME_BASE) );
xmlCurrent_->SetAttribute("volume_mix", (int) s.audioVolumeMix() );
sourceNode->InsertEndChild(xmlCurrent_);

xmlCurrent_ = sourceNode; // parent for next visits (other subtypes of Source)
}

Expand Down
Loading

0 comments on commit 7b5bc6d

Please sign in to comment.