From 4bd993b1e3e8c5ae40fb9639dd9668321aa95abb Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Sun, 9 Jul 2023 22:29:08 +0300 Subject: [PATCH] GstEngine/GstEnginePipeline: support gap-less playback w/ loudness-normalizing gain Ok, it does appear that it is that simple. In principle this (even the non-update case) results in volume jumps, so maybe we'll want gradual gain change... Notably, i thought we'd always seek if the pipeline was already operating on the same URL as the new one, but apparently only for adjacent songs? --- src/engine/gstengine.cpp | 4 ++-- src/engine/gstenginepipeline.cpp | 21 ++++++++++++++++++--- src/engine/gstenginepipeline.h | 2 ++ 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/engine/gstengine.cpp b/src/engine/gstengine.cpp index 813c0172..f84e38b9 100644 --- a/src/engine/gstengine.cpp +++ b/src/engine/gstengine.cpp @@ -190,9 +190,9 @@ bool GstEngine::Load(const QUrl &media_url, const QUrl &stream_url, const Engine crossfade = false; } - if (!crossfade && current_pipeline_ && current_pipeline_->stream_url() == stream_url && current_pipeline_->ebur128_loudness_normalizing_gain_db() == ebur128_loudness_normalizing_gain_db_ && change & EngineBase::TrackChangeType::Auto) { + if (!crossfade && current_pipeline_ && current_pipeline_->stream_url() == stream_url && change & EngineBase::TrackChangeType::Auto) { // We're not crossfading, and the pipeline is already playing the URI we want, so just do nothing. - // FIXME: can we handle changing of loudness-normalizing gain here? + current_pipeline_->SetEBUR128LoudnessNormalizingGain_dB(ebur128_loudness_normalizing_gain_db_); return true; } diff --git a/src/engine/gstenginepipeline.cpp b/src/engine/gstenginepipeline.cpp index b703be8f..117f4216 100644 --- a/src/engine/gstenginepipeline.cpp +++ b/src/engine/gstenginepipeline.cpp @@ -602,9 +602,7 @@ bool GstEnginePipeline::InitAudioBin(QString &error) { return false; } - auto dB_to_mult = [](const double gain_dB) { return std::pow(10., gain_dB / 20.); }; - - g_object_set(G_OBJECT(ebur128_volume_), "volume", dB_to_mult(ebur128_loudness_normalizing_gain_db_), nullptr); + UpdateEBUR128LoudnessNormalizingGaindB(); eventprobe_ = ebur128_volume_; } @@ -1535,6 +1533,23 @@ bool GstEnginePipeline::Seek(const qint64 nanosec) { } +void GstEnginePipeline::SetEBUR128LoudnessNormalizingGain_dB(const double ebur128_loudness_normalizing_gain_db) { + + ebur128_loudness_normalizing_gain_db_ = ebur128_loudness_normalizing_gain_db; + UpdateEBUR128LoudnessNormalizingGaindB(); + +} + +void GstEnginePipeline::UpdateEBUR128LoudnessNormalizingGaindB() { + + if (ebur128_volume_) { + auto dB_to_mult = [](const double gain_dB) { return std::pow(10., gain_dB / 20.); }; + + g_object_set(G_OBJECT(ebur128_volume_), "volume", dB_to_mult(ebur128_loudness_normalizing_gain_db_), nullptr); + } + +} + void GstEnginePipeline::SetVolume(const uint volume_percent) { if (volume_) { diff --git a/src/engine/gstenginepipeline.h b/src/engine/gstenginepipeline.h index fc04e832..b670b7dc 100644 --- a/src/engine/gstenginepipeline.h +++ b/src/engine/gstenginepipeline.h @@ -87,6 +87,7 @@ class GstEnginePipeline : public QObject { // Control the music playback QFuture SetState(const GstState state); Q_INVOKABLE bool Seek(const qint64 nanosec); + void SetEBUR128LoudnessNormalizingGain_dB(const double ebur128_loudness_normalizing_gain_db); void SetVolume(const uint volume_percent); void SetStereoBalance(const float value); void SetEqualizerParams(const int preamp, const QList &band_gains); @@ -175,6 +176,7 @@ class GstEnginePipeline : public QObject { static QString ParseStrTag(GstTagList *list, const char *tag); static guint ParseUIntTag(GstTagList *list, const char *tag); + void UpdateEBUR128LoudnessNormalizingGaindB(); void UpdateStereoBalance(); void UpdateEqualizer();