diff --git a/src/models/multitrackmodel.cpp b/src/models/multitrackmodel.cpp index f3271993e7..67c52c6bac 100644 --- a/src/models/multitrackmodel.cpp +++ b/src/models/multitrackmodel.cpp @@ -48,6 +48,11 @@ static QByteArray trackAudioLevelPrefix(int mltTrackIndex) return QStringLiteral("meta.track.%1.audio_level.").arg(mltTrackIndex).toLatin1(); } +static QByteArray trackDuckLevelPrefix(int mltTrackIndex) +{ + return QStringLiteral("meta.track.%1.").arg(mltTrackIndex).toLatin1(); +} + static double audioLevelDbFromFilter(Mlt::Filter *filter) { static const char *kAudioLevelLeft = "_audio_level.0"; @@ -744,7 +749,13 @@ void MultitrackModel::updateTrackAudioLevels(const SharedFrame &frame) = QStringLiteral("meta.track.%1.audio_level.1").arg(mltTrackIndex).toLatin1(); const double left = frame.get_double(leftKey.constData()); const double right = frame.get_double(rightKey.constData()); - const double audioLevel = audioLevelDbFromLinear(left, right); + double audioLevel = audioLevelDbFromLinear(left, right); + + // audiolevel measures before the mix transition applies ducking, so subtract it here. + const QByteArray duckKey = trackDuckLevelPrefix(mltTrackIndex) + "duck_level"; + const double duckReduction = frame.get_double(duckKey.constData()); + if (duckReduction > 0.0) + audioLevel = qMax(audioLevel - duckReduction, -100.0); setTrackAudioLevel(row, audioLevel); } @@ -812,6 +823,10 @@ void MultitrackModel::syncTrackAudioLevelFilterPrefixes() std::unique_ptr levelFilter( ensureTrackAudioLevelFilter(track.data(), mltTrackIndex)); Q_UNUSED(levelFilter) + + QScopedPointer mix(getTransition("mix", mltTrackIndex)); + if (mix && mix->is_valid()) + mix->set("prefix", trackDuckLevelPrefix(mltTrackIndex).constData()); } } diff --git a/src/widgets/trackpropertieswidget.cpp b/src/widgets/trackpropertieswidget.cpp index 66733f6ff0..07b708c6db 100644 --- a/src/widgets/trackpropertieswidget.cpp +++ b/src/widgets/trackpropertieswidget.cpp @@ -20,12 +20,14 @@ #include "commands/timelinecommands.h" #include "mainwindow.h" +#include "sharedframe.h" #include "shotcut_mlt_properties.h" #include "util.h" #include +#include #include -#include +#include static const char *BLEND_PROPERTY_CAIROBLEND = "1"; static const char *BLEND_PROPERTY_QTBLEND = "compositing"; @@ -42,7 +44,7 @@ TrackPropertiesWidget::TrackPropertiesWidget(Mlt::Producer &track, : QWidget(parent) , ui(new Ui::TrackPropertiesWidget) , m_track(track) - , m_duckStatusTimer(new QTimer(this)) + , m_trackIndex(-1) { ui->setupUi(this); Util::setColorsToHighlight(ui->nameLabel); @@ -63,15 +65,6 @@ TrackPropertiesWidget::TrackPropertiesWidget(Mlt::Producer &track, } } - m_duckStatusTimer->setInterval(100); - if (showDucking) { - connect(m_duckStatusTimer, - &QTimer::timeout, - this, - &TrackPropertiesWidget::refreshDuckStatus); - m_duckStatusTimer->start(); - } - if (showBlend) { QScopedPointer transition(getTransition("qtblend")); if (!transition) @@ -165,7 +158,6 @@ TrackPropertiesWidget::TrackPropertiesWidget(Mlt::Producer &track, TrackPropertiesWidget::~TrackPropertiesWidget() { - m_duckStatusTimer->stop(); delete ui; } @@ -192,6 +184,36 @@ void TrackPropertiesWidget::updateDuckStatus(double value) ui->duckStatusValueLabel->setFormat(QString::number(clamped, 'f', 1) + tr(" dB")); } +void TrackPropertiesWidget::showEvent(QShowEvent *event) +{ + QWidget::showEvent(event); + if (!ui->duckingHeadingLabel->isVisible()) + return; + connect(MLT.videoWidget(), + SIGNAL(frameDisplayed(const SharedFrame &)), + this, + SLOT(onShowFrame(const SharedFrame &))); +} + +void TrackPropertiesWidget::hideEvent(QHideEvent *event) +{ + QWidget::hideEvent(event); + if (!ui->duckingHeadingLabel->isVisible()) + return; + disconnect(MLT.videoWidget(), + SIGNAL(frameDisplayed(const SharedFrame &)), + this, + SLOT(onShowFrame(const SharedFrame &))); +} + +void TrackPropertiesWidget::onShowFrame(const SharedFrame &frame) +{ + if (m_trackIndex < 0 || !frame.is_valid()) + return; + const QByteArray key = QStringLiteral("meta.track.%1.duck_level").arg(m_trackIndex).toLatin1(); + updateDuckStatus(frame.get_double(key.constData())); +} + Mlt::Transition *TrackPropertiesWidget::getTransition(const QString &name) { // track.consumer() is the multitrack @@ -206,6 +228,7 @@ Mlt::Transition *TrackPropertiesWidget::getTransition(const QString &name) if (producer->get_producer() == m_track.get_producer()) break; } + m_trackIndex = trackIndex; // Iterate the consumers until found transition by mlt_service and track_b index. while (service && service->is_valid() && mlt_service_tractor_type != service->type()) { @@ -344,11 +367,3 @@ void TrackPropertiesWidget::onDuckFadeOutChanged(double value) ui->duckFadeOutSpinBox->setValue(value); ui->duckFadeOutSpinBox->blockSignals(false); } - -void TrackPropertiesWidget::refreshDuckStatus() -{ - QScopedPointer transition(getTransition("mix")); - if (transition && transition->is_valid()) { - updateDuckStatus(transition->get_double(MIX_PROPERTY_DUCK_LEVEL)); - } -} diff --git a/src/widgets/trackpropertieswidget.h b/src/widgets/trackpropertieswidget.h index 101de09cc5..417331af69 100644 --- a/src/widgets/trackpropertieswidget.h +++ b/src/widgets/trackpropertieswidget.h @@ -22,14 +22,15 @@ #include #include -class QTimer; - namespace Ui { class TrackPropertiesWidget; } namespace Mlt { class Transition; } +class SharedFrame; +class QShowEvent; +class QHideEvent; class TrackPropertiesWidget : public QWidget { @@ -53,7 +54,11 @@ private slots: void onDuckAttenuationChanged(double value); void onDuckFadeInChanged(double value); void onDuckFadeOutChanged(double value); - void refreshDuckStatus(); + void onShowFrame(const SharedFrame &frame); + +protected: + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; private: Mlt::Transition *getTransition(const QString &name); @@ -62,7 +67,7 @@ private slots: Ui::TrackPropertiesWidget *ui; Mlt::Producer m_track; - QTimer *m_duckStatusTimer; + int m_trackIndex; }; #endif // TRACKPROPERTIESWIDGET_H