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.
brunoherbelin committed Apr 21, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 3e45ec7 commit 7b5bc6d
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
@@ -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);
66 changes: 10 additions & 56 deletions src/MediaPlayer.cpp
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ MediaPlayer::MediaPlayer()
opened_ = false;
enabled_ = true;
desired_state_ = GST_STATE_PAUSED;
audio_enabled_ = false;

failed_ = false;
pending_ = false;
@@ -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;
@@ -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;
@@ -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
@@ -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)
25 changes: 5 additions & 20 deletions src/MediaPlayer.h
Original file line number Diff line number Diff line change
@@ -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
@@ -326,6 +315,7 @@ class MediaPlayer {
Timeline timeline_;
FadingMode fading_mode_;
std::future<MediaInfo> discoverer_;
bool audio_enabled_;

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

#include <glm/gtc/matrix_transform.hpp>

#include "defines.h"
#include "Resource.h"
#include "Decorations.h"
#include "MediaPlayer.h"
@@ -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());
}
@@ -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);
}
}

@@ -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;
1 change: 1 addition & 0 deletions src/MediaSource.h
Original file line number Diff line number Diff line change
@@ -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);
3 changes: 3 additions & 0 deletions src/Session.cpp
Original file line number Diff line number Diff line change
@@ -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
21 changes: 10 additions & 11 deletions src/SessionCreator.cpp
Original file line number Diff line number Diff line change
@@ -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);
@@ -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;

5 changes: 5 additions & 0 deletions src/SessionSource.cpp
Original file line number Diff line number Diff line change
@@ -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() ) {

12 changes: 6 additions & 6 deletions src/SessionVisitor.cpp
Original file line number Diff line number Diff line change
@@ -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());
@@ -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)
}

Loading

0 comments on commit 7b5bc6d

Please sign in to comment.