Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Audio mixer: various fixes (crash, incorrect balance value, add dial for balance)

parent 09c5f795
Pipeline #8959 passed with stage
in 28 minutes and 19 seconds
......@@ -50,13 +50,6 @@ MixerManager::MixerManager(QWidget *parent)
m_box->addStretch(10);
m_box->addLayout(m_masterBox);
setLayout(m_box);
m_timer.setSingleShot(true);
m_timer.setInterval(100);
connect(&m_timer, &QTimer::timeout, [&] () {
for (auto w : m_mixers) {
w.second->updateAudioLevel(m_lastFrame);
}
});
}
void MixerManager::registerTrack(int tid, std::shared_ptr<Mlt::Tractor> service, const QString &trackTag)
......@@ -90,7 +83,7 @@ void MixerManager::registerTrack(int tid, std::shared_ptr<Mlt::Tractor> service,
m_soloMuted.clear();
}
for (auto item : m_mixers) {
if (item.first > -1 && item.first != trid && !item.second->isMute()) {
if (item.first != trid && !item.second->isMute()) {
m_model->setTrackProperty(item.first, "hide", QStringLiteral("3"));
m_soloMuted << item.first;
item.second->unSolo();
......@@ -114,26 +107,26 @@ void MixerManager::resetAudioValues()
for (auto item : m_mixers) {
item.second.get()->clear();
}
if (m_masterMixer) {
m_masterMixer->clear();
}
}
void MixerManager::cleanup()
{
for (auto item : m_mixers) {
if (item.first > -1) {
m_box->removeWidget(item.second.get());
}
}
while (!m_masterBox->isEmpty()) {
m_masterBox->takeAt(0);
m_box->removeWidget(item.second.get());
}
m_mixers.clear();
if (m_masterMixer) {
m_masterMixer->clear(true);
}
m_connectedWidgets = 0;
}
void MixerManager::setModel(std::shared_ptr<TimelineItemModel> model)
{
// Insert master mixer
int tid = -1;
m_model = model;
connect(m_model.get(), &TimelineItemModel::dataChanged, [&](const QModelIndex &topLeft, const QModelIndex &bottomRight, const QVector<int> &roles) {
if (roles.contains(TimelineModel::IsDisabledRole)) {
......@@ -147,18 +140,16 @@ void MixerManager::setModel(std::shared_ptr<TimelineItemModel> model)
});
Mlt::Tractor *service = model->tractor();
if (m_mixers.count(tid) > 0) {
if (m_masterMixer != nullptr) {
// delete previous master mixer
m_masterBox->removeWidget(m_mixers[tid].get());
m_mixers.erase(tid);
m_masterBox->removeWidget(m_masterMixer.get());
}
std::shared_ptr<MixerWidget> mixer(new MixerWidget(tid, service, i18n("Master"), this));
connect(mixer.get(), &MixerWidget::muteTrack, [&](int /*id*/, bool mute) {
m_masterMixer.reset(new MixerWidget(-1, service, i18n("Master"), this));
connect(m_masterMixer.get(), &MixerWidget::muteTrack, [&](int /*id*/, bool mute) {
qDebug()<<"=== SETTING MUITE";
m_model->tractor()->set("hide", mute ? 3 : 1);
});
connect(this, &MixerManager::updateLevels, mixer.get(), &MixerWidget::updateAudioLevel);
m_mixers[tid] = mixer;
m_masterBox->addWidget(mixer.get());
connect(this, &MixerManager::updateLevels, m_masterMixer.get(), &MixerWidget::updateAudioLevel);
m_masterBox->addWidget(m_masterMixer.get());
}
......@@ -27,7 +27,6 @@
#include <unordered_map>
#include <QWidget>
#include <QTimer>
namespace Mlt {
class Tractor;
......@@ -62,13 +61,13 @@ public:
protected:
std::unordered_map<int, std::shared_ptr<MixerWidget>> m_mixers;
std::shared_ptr<MixerWidget> m_masterMixer;
private:
std::shared_ptr<Mlt::Tractor> m_masterService;
std::shared_ptr<TimelineItemModel> m_model;
QHBoxLayout *m_box;
QHBoxLayout *m_masterBox;
QTimer m_timer;
int m_lastFrame;
int m_connectedWidgets;
QVector <int> m_soloMuted;
......
......@@ -23,6 +23,7 @@
#include "mlt++/MltFilter.h"
#include "mlt++/MltTractor.h"
#include "mlt++/MltEvent.h"
#include "mlt++/MltProfile.h"
#include "mixerwidget.hpp"
#include "mixermanager.hpp"
......@@ -34,6 +35,7 @@
#include <QToolButton>
#include <QCheckBox>
#include <QSlider>
#include <QDial>
#include <QSpinBox>
#include <QDial>
#include <QLabel>
......@@ -52,7 +54,7 @@ static inline int levelToDB(double level)
void MixerWidget::property_changed( mlt_service , MixerWidget *widget, char *name )
{
//if (!widget->m_levels.contains(widget->m_manager->renderPosition)) {
if (!strcmp(name, "_position")) {
if (widget && !strcmp(name, "_position")) {
mlt_properties filter_props = MLT_FILTER_PROPERTIES( widget->m_monitorFilter->get_filter());
int pos = mlt_properties_get_int(filter_props, "_position");
if (!widget->m_levels.contains(pos)) {
......@@ -72,6 +74,7 @@ MixerWidget::MixerWidget(int tid, std::shared_ptr<Mlt::Tractor> service, const Q
, m_balanceFilter(nullptr)
, m_solo(nullptr)
, m_lastVolume(0)
, m_listener(nullptr)
{
buildUI(service.get(), trackTag);
}
......@@ -85,10 +88,18 @@ MixerWidget::MixerWidget(int tid, Mlt::Tractor *service, const QString &trackTag
, m_balanceFilter(nullptr)
, m_solo(nullptr)
, m_lastVolume(0)
, m_listener(nullptr)
{
buildUI(service, trackTag);
}
MixerWidget::~MixerWidget()
{
if (m_listener) {
delete m_listener;
}
}
void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
{
setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
......@@ -111,6 +122,10 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
m_volumeSlider->setValue(val);
});
m_balanceDial = new QDial(this);
m_balanceDial->setRange(-50, 50);
m_balanceDial->setValue(0);
m_balanceSpin = new QSpinBox(this);
m_balanceSpin->setRange(-50, 50);
m_balanceSpin->setValue(0);
......@@ -134,7 +149,9 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
m_volumeSlider->setValue(volume);
} else if (filterService == QLatin1String("panner")) {
m_balanceFilter = fl;
m_balanceSpin->setValue(m_balanceFilter->get_double("start") * 100 + 50);
int val = m_balanceFilter->get_double("start") * 100 - 50;
m_balanceSpin->setValue(val);
m_balanceDial->setValue(val);
}
}
// Build default filters if not found
......@@ -149,6 +166,7 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
m_balanceFilter.reset(new Mlt::Filter(service->get_profile(), "panner"));
if (m_balanceFilter->is_valid()) {
m_balanceFilter->set("internal_added", 237);
m_balanceFilter->set("start", 0.5);
service->attach(*m_balanceFilter.get());
}
}
......@@ -166,6 +184,8 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
m_muteAction->setActiveIcon(QIcon::fromTheme(QStringLiteral("kdenlive-hide-audio")));
m_muteAction->setInactiveIcon(QIcon::fromTheme(QStringLiteral("kdenlive-show-audio")));
connect(m_balanceDial, &QDial::valueChanged, m_balanceSpin, &QSpinBox::setValue);
connect(m_muteAction, &KDualAction::activeChangedByUser, [&](bool active) {
if (m_tid == -1) {
// Muting master, special case
......@@ -207,6 +227,8 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
}
});
connect(m_balanceSpin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), [&](int value) {
QSignalBlocker bk(m_balanceDial);
m_balanceDial->setValue(value);
if (m_balanceFilter != nullptr) {
m_balanceFilter->set("start", (value + 50) / 100.);
}
......@@ -222,6 +244,7 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
buttonslay->addWidget(m_solo);
}
lay->addLayout(buttonslay);
lay->addWidget(m_balanceDial);
lay->addWidget(m_balanceSpin);
QHBoxLayout *hlay = new QHBoxLayout;
hlay->addWidget(m_audioMeterWidget.get());
......@@ -233,7 +256,7 @@ void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackTag)
if (service->get_int("hide") > 1) {
setMute(true);
}
m_monitorFilter->listen("property-changed", this, (mlt_listener)property_changed);
m_listener = m_monitorFilter->listen("property-changed", this, (mlt_listener)property_changed);
}
void MixerWidget::setMute(bool mute)
......
......@@ -23,7 +23,6 @@
#define MIXERWIDGET_H
#include "definitions.h"
#include "mlt++/MltService.h"
#include <memory>
......@@ -34,12 +33,14 @@
class KDualAction;
class AudioLevelWidget;
class QSlider;
class QDial;
class QSpinBox;
class QToolButton;
class MixerManager;
namespace Mlt {
class Tractor;
class Event;
}
class MixerWidget : public QWidget
......@@ -49,6 +50,7 @@ class MixerWidget : public QWidget
public:
MixerWidget(int tid, std::shared_ptr<Mlt::Tractor> service, const QString &trackTag, MixerManager *parent = nullptr);
MixerWidget(int tid, Mlt::Tractor *service, const QString &trackTag, MixerManager *parent = nullptr);
virtual ~MixerWidget();
void buildUI(Mlt::Tractor *service, const QString &trackTag);
/** @brief discard stored audio values and reset vu-meter to 0 if requested */
void clear(bool reset = false);
......@@ -74,6 +76,7 @@ protected:
QMap<int, QPair<int, int>> m_levels;
KDualAction *m_muteAction;
QSpinBox *m_balanceSpin;
QDial *m_balanceDial;
QSpinBox *m_volumeSpin;
private:
......@@ -82,6 +85,7 @@ private:
QToolButton *m_solo;
QMutex m_storeMutex;
int m_lastVolume;
Mlt::Event *m_listener;
signals:
void gotLevels(QPair <double, double>);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment