mixerwidget.cpp 19.7 KB
Newer Older
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/***************************************************************************
 *   Copyright (C) 2019 by Jean-Baptiste Mardelle                          *
 *   This file is part of Kdenlive. See www.kdenlive.org.                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) version 3 or any later version accepted by the       *
 *   membership of KDE e.V. (or its successor approved  by the membership  *
 *   of KDE e.V.), which shall act as a proxy defined in Section 14 of     *
 *   version 3 of the license.                                             *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "mixerwidget.hpp"

#include "mlt++/MltFilter.h"
#include "mlt++/MltTractor.h"
26
#include "mlt++/MltEvent.h"
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
27
#include "mlt++/MltProfile.h"
28
29
#include "core.h"
#include "kdenlivesettings.h"
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
30
31
#include "mixermanager.hpp"
#include "audiolevelwidget.hpp"
32
#include "capture/mediacapture.h"
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
33
34

#include <KDualAction>
35
#include <KSqueezedTextLabel>
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
36
#include <QCheckBox>
37
#include <QDial>
38
#include <QDoubleSpinBox>
39
40
#include <QFontDatabase>
#include <QGridLayout>
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
41
#include <QLabel>
Antonio Rojas's avatar
Antonio Rojas committed
42
#include <QMouseEvent>
43
44
#include <QSlider>
#include <QSpinBox>
45
#include <QStyle>
46
47
48
#include <QToolButton>
#include <klocalizedstring.h>
#include <utility>
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
49

50
51
52
static inline double IEC_Scale(double dB)
{
    dB = log10(dB) * 20.0;
53
54
55
56
57
58
59
60
    double fScale = 1.0;

    if (dB < -70.0)
        fScale = 0.0;
    else if (dB < -60.0)
        fScale = (dB + 70.0) * 0.0025;
    else if (dB < -50.0)
        fScale = (dB + 60.0) * 0.005 + 0.025;
61
    else if (dB < -40.0)
62
63
64
65
66
67
68
        fScale = (dB + 50.0) * 0.0075 + 0.075;
    else if (dB < -30.0)
        fScale = (dB + 40.0) * 0.015 + 0.15;
    else if (dB < -20.0)
        fScale = (dB + 30.0) * 0.02 + 0.3;
    else if (dB < -0.001 || dB > 0.001)  /* if (dB < 0.0f) */
        fScale = (dB + 20.0) * 0.025 + 0.5;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
69

70
71
72
73
    return fScale;
}

static inline int fromDB(double level)
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
74
{
75
    int value = 60;
76
77
    if (level > 0.) {
        // increase volume
78
        value = 100 - int((pow(10, 1. - level/24) - 1) / .225);
79
    } else if (level < 0.) {
80
        value = int((10 - pow(10, 1. - level/-50)) / -0.11395) + 59;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
81
    }
82
    return value;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
83
84
}

85
void MixerWidget::property_changed( mlt_service , MixerWidget *widget, mlt_event_data data )
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
86
{
87
    if (widget && !strcmp(Mlt::EventData(data).to_string(), "_position")) {
88
89
90
        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)) {
91
92
93
94
95
96
            QVector<double> levels;
            for (int i = 0; i < widget->m_channels; i++) {
                levels << IEC_Scale(mlt_properties_get_double(filter_props, QString("_audio_level.%1").arg(i).toUtf8().constData()));
            }
            widget->m_levels[pos] = std::move(levels);
            //{IEC_Scale(mlt_properties_get_double(filter_props, "_audio_level.0")), IEC_Scale(mlt_properties_get_double(filter_props, "_audio_level.1"))};
97
            if (widget->m_levels.size() > widget->m_maxLevels) {
98
                widget->m_levels.erase(widget->m_levels.begin());
99
            }
100
        }
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
101
102
103
    }
}

104
MixerWidget::MixerWidget(int tid, std::shared_ptr<Mlt::Tractor> service, QString trackTag, const QString &trackName, MixerManager *parent)
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
105
106
107
108
109
110
: QWidget(parent)
    , m_manager(parent)
    , m_tid(tid)
    , m_levelFilter(nullptr)
    , m_monitorFilter(nullptr)
    , m_balanceFilter(nullptr)
111
    , m_channels(pCore->audioChannels())
112
    , m_balanceSlider(nullptr)
113
    , m_maxLevels(qMax(30, int(service->get_fps() * 1.5)))
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
114
    , m_solo(nullptr)
115
    , m_record(nullptr)
116
    , m_collapse(nullptr)
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
117
    , m_lastVolume(0)
118
    , m_listener(nullptr)
119
    , m_recording(false)
120
    , m_trackTag(std::move(trackTag))
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
121
{
Julius Künzel's avatar
Julius Künzel committed
122
    buildUI(service.get(), trackName);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
123
124
}

125
MixerWidget::MixerWidget(int tid, Mlt::Tractor *service, QString trackTag, const QString &trackName, MixerManager *parent)
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
126
127
128
129
130
131
    : QWidget(parent)
    , m_manager(parent)
    , m_tid(tid)
    , m_levelFilter(nullptr)
    , m_monitorFilter(nullptr)
    , m_balanceFilter(nullptr)
132
    , m_channels(pCore->audioChannels())
133
    , m_balanceSpin(nullptr)
134
    , m_balanceSlider(nullptr)
Vincent Pinon's avatar
Vincent Pinon committed
135
    , m_maxLevels(qMax(30, int(service->get_fps() * 1.5)))
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
136
    , m_solo(nullptr)
137
    , m_record(nullptr)
138
    , m_collapse(nullptr)
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
139
    , m_lastVolume(0)
140
    , m_listener(nullptr)
141
    , m_recording(false)
142
    , m_trackTag(std::move(trackTag))
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
143
{
Julius Künzel's avatar
Julius Künzel committed
144
    buildUI(service, trackName);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
145
146
}

147
148
149
150
151
152
153
MixerWidget::~MixerWidget()
{
    if (m_listener) {
        delete m_listener;
    }
}

Julius Künzel's avatar
Julius Künzel committed
154
void MixerWidget::buildUI(Mlt::Tractor *service, const QString &trackName)
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
155
156
157
158
{
    setFont(QFontDatabase::systemFont(QFontDatabase::SmallestReadableFont));
    // Build audio meter widget
    m_audioMeterWidget.reset(new AudioLevelWidget(width(), this));
Yuri Chornoivan's avatar
Yuri Chornoivan committed
159
    // initialize for stereo display
160
161
162
163
    for (int i = 0; i < m_channels; i++) {
        m_audioData << -100;
    }
    m_audioMeterWidget->setAudioValues(m_audioData);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
164
165
166

    // Build volume widget
    m_volumeSlider = new QSlider(Qt::Vertical, this);
167
    m_volumeSlider->setRange(0, 100);
168
    m_volumeSlider->setValue(60);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
169
    m_volumeSlider->setToolTip(i18n("Volume"));
170
171
    m_volumeSpin = new QDoubleSpinBox(this);
    m_volumeSpin->setRange(-50, 24);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
172
173
    m_volumeSpin->setSuffix(i18n("dB"));
    m_volumeSpin->setFrame(false);
174

Vincent Pinon's avatar
Vincent Pinon committed
175
    connect(m_volumeSpin, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, [&](double val) {
176
        m_volumeSlider->setValue(fromDB(val));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
177
178
    });

179
180
181
182
183
184
185
186
187
    QLabel *labelLeft = nullptr;
    QLabel *labelRight = nullptr;
    if (m_channels == 2) {
        m_balanceSlider = new QSlider(Qt::Horizontal,this);
        m_balanceSlider->setRange(-50, 50);
        m_balanceSlider->setValue(0);
        m_balanceSlider->setTickPosition(QSlider::TicksBelow);
        m_balanceSlider->setTickInterval(50);
        m_balanceSlider->setToolTip(i18n("Balance"));
Julius Künzel's avatar
Julius Künzel committed
188

189
190
191
192
        labelLeft = new QLabel(i18nc("Left", "L"), this);
        labelLeft->setAlignment(Qt::AlignHCenter);
        labelRight = new QLabel(i18nc("Right", "R"), this);
        labelRight->setAlignment(Qt::AlignHCenter);
193

194
195
196
197
198
199
        m_balanceSpin = new QSpinBox(this);
        m_balanceSpin->setRange(-50, 50);
        m_balanceSpin->setValue(0);
        m_balanceSpin->setFrame(false);
        m_balanceSpin->setToolTip(i18n("Balance"));
    }
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
200
201
202
203
204
205
206
207
208
209
210

    // Check if we already have build-in filters for this tractor
    int max = service->filter_count();
    for (int i = 0; i < max; i++) {
        std::shared_ptr<Mlt::Filter> fl(service->filter(i));
        if (!fl->is_valid()) {
            continue;
        }
        const QString filterService = fl->get("mlt_service");
        if (filterService == QLatin1String("audiolevel")) {
            m_monitorFilter = fl;
211
            m_monitorFilter->set("disable", 0);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
212
213
        } else if (filterService == QLatin1String("volume")) {
            m_levelFilter = fl;
214
            double volume = m_levelFilter->get_double("level");
215
            m_volumeSpin->setValue(volume);
216
            m_volumeSlider->setValue(fromDB(volume));
217
        } else if (m_channels == 2 && filterService == QLatin1String("panner")) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
218
            m_balanceFilter = fl;
219
            int val = int(m_balanceFilter->get_double("start") * 100) - 50;
220
            m_balanceSpin->setValue(val);
Julius Künzel's avatar
Julius Künzel committed
221
            m_balanceSlider->setValue(val);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
222
223
224
225
226
227
        }
    }
    // Build default filters if not found
    if (m_levelFilter == nullptr) {
        m_levelFilter.reset(new Mlt::Filter(service->get_profile(), "volume"));
        if (m_levelFilter->is_valid()) {
228
            m_levelFilter->set("internal_added", 237);
229
            m_levelFilter->set("disable", 1);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
230
231
232
            service->attach(*m_levelFilter.get());
        }
    }
233
    if (m_balanceFilter == nullptr && m_channels == 2) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
234
235
        m_balanceFilter.reset(new Mlt::Filter(service->get_profile(), "panner"));
        if (m_balanceFilter->is_valid()) {
236
            m_balanceFilter->set("internal_added", 237);
237
            m_balanceFilter->set("start", 0.5);
238
            m_balanceFilter->set("disable", 1);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
239
240
241
242
243
244
245
246
247
248
249
250
            service->attach(*m_balanceFilter.get());
        }
    }
    // Monitoring should be appended last so that other effects are reflected in audio monitor
    if (m_monitorFilter == nullptr) {
        m_monitorFilter.reset(new Mlt::Filter(service->get_profile(), "audiolevel"));
        if (m_monitorFilter->is_valid()) {
            m_monitorFilter->set("iec_scale", 0);
            service->attach(*m_monitorFilter.get());
        }
    }

Julius Künzel's avatar
Julius Künzel committed
251
    m_trackLabel = new KSqueezedTextLabel(this);
252
253
254
    m_trackLabel->setAutoFillBackground(true);
    m_trackLabel->setAlignment(Qt::AlignHCenter);
    m_trackLabel->setFrameStyle(QFrame::Panel | QFrame::Sunken);
Julius Künzel's avatar
Julius Künzel committed
255
256
    m_trackLabel->setTextElideMode(Qt::ElideRight);
    setTrackName(trackName);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
257
258
259
260
    m_muteAction = new KDualAction(i18n("Mute track"), i18n("Unmute track"), this);
    m_muteAction->setActiveIcon(QIcon::fromTheme(QStringLiteral("kdenlive-hide-audio")));
    m_muteAction->setInactiveIcon(QIcon::fromTheme(QStringLiteral("kdenlive-show-audio")));

261
262
263
    if (m_balanceSlider) {
        connect(m_balanceSlider, &QSlider::valueChanged, m_balanceSpin, &QSpinBox::setValue);
    }
264

Vincent Pinon's avatar
Vincent Pinon committed
265
    connect(m_muteAction, &KDualAction::activeChangedByUser, this, [&](bool active) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
266
267
268
269
        if (m_tid == -1) {
            // Muting master, special case
            if (m_levelFilter) {
                if (active) {
270
                    m_lastVolume = m_levelFilter->get_double("level");
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
271
                    m_levelFilter->set("level", -1000);
272
                    m_levelFilter->set("disable", 0);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
273
274
                } else {
                    m_levelFilter->set("level", m_lastVolume);
275
                    m_levelFilter->set("disable", qFuzzyIsNull(m_lastVolume) ? 1 : 0);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
276
277
278
279
                }
            }
        } else {
            emit muteTrack(m_tid, !active);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
280
            reset();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
281
        }
282
        pCore->setDocumentModified();
283
        updateLabel();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
284
285
    });

286
    auto *mute = new QToolButton(this);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
287
288
    mute->setDefaultAction(m_muteAction);
    mute->setAutoRaise(true);
289

290
    // Setup default width
291
    setFixedWidth(3 * mute->sizeHint().width());
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
292
293

    if (m_tid > -1) {
294
        // No solo / rec button on master
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
295
296
297
        m_solo = new QToolButton(this);
        m_solo->setCheckable(true);
        m_solo->setIcon(QIcon::fromTheme("headphones"));
298
        m_solo->setToolTip(i18n("Solo mode"));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
299
        m_solo->setAutoRaise(true);
Vincent Pinon's avatar
Vincent Pinon committed
300
        connect(m_solo, &QToolButton::toggled, this, [&](bool toggled) {
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
301
            emit toggleSolo(m_tid, toggled);
302
            updateLabel();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
303
        });
304
305
        m_record = new QToolButton(this);
        m_record->setIcon(QIcon::fromTheme("media-record"));
306
        m_record->setToolTip(i18n("Record"));
307
        m_record->setCheckable(true);
308
        m_record->setAutoRaise(true);
Vincent Pinon's avatar
Vincent Pinon committed
309
310
        connect(m_record, &QToolButton::clicked, this, [&]() {
            emit m_manager->recordAudio(m_tid);
311
        });
312
313
    } else {
        m_collapse = new QToolButton(this);
314
        m_collapse->setIcon(KdenliveSettings::mixerCollapse() ? QIcon::fromTheme("arrow-left") : QIcon::fromTheme("arrow-right"));
315
316
317
        m_collapse->setToolTip(i18n("Show Channels"));
        m_collapse->setCheckable(true);
        m_collapse->setAutoRaise(true);
318
        m_collapse->setChecked(KdenliveSettings::mixerCollapse() );
Vincent Pinon's avatar
Vincent Pinon committed
319
        connect(m_collapse, &QToolButton::clicked, this, [&]() {
320
            KdenliveSettings::setMixerCollapse(m_collapse->isChecked());
321
            m_collapse->setIcon(m_collapse->isChecked() ? QIcon::fromTheme("arrow-left") : QIcon::fromTheme("arrow-right"));
322
            m_manager->collapseMixers();
323
        });
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
324
325
    }

326
    auto *showEffects = new QToolButton(this);
Julius Künzel's avatar
Julius Künzel committed
327
328
329
330
331
332
333
    showEffects->setIcon(QIcon::fromTheme("autocorrection"));
    showEffects->setToolTip(i18n("Open Effect Stack"));
    showEffects->setAutoRaise(true);
    connect(showEffects, &QToolButton::clicked, this,  [&]() {
        emit m_manager->showEffectStack(m_tid);
    });

Vincent Pinon's avatar
Vincent Pinon committed
334
    connect(m_volumeSlider, &QSlider::valueChanged, this, [&](int value) {
335
        QSignalBlocker bk(m_volumeSpin);
336
        if (m_recording) {
337
            m_volumeSpin->setValue(value);
338
            KdenliveSettings::setAudiocapturevolume(value);
Vincent Pinon's avatar
Vincent Pinon committed
339
            emit m_manager->updateRecVolume();
340
341
            //TODO update capture volume
        } else if (m_levelFilter != nullptr) {
342
            double dbValue = 0;
343
            if (value > 60) {
344
                // increase volume
345
346
347
                dbValue = 24 * (1 - log10((100 - value)*0.225 + 1));
            } else if (value < 60) {
                dbValue = -50 * (1 - log10(10 - (value - 59)*(-0.11395)));
348
349
350
            }
            m_volumeSpin->setValue(dbValue);
            m_levelFilter->set("level", dbValue);
351
            m_levelFilter->set("disable", value == 60 ? 1 : 0);
352
            m_levels.clear();
Vincent Pinon's avatar
Vincent Pinon committed
353
            emit m_manager->purgeCache();
354
            pCore->setDocumentModified();
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
355
356
        }
    });
357
358
359
360
361
362
363
364
365
366
367
368
369
    if (m_balanceSlider) {
        connect(m_balanceSpin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, [&](int value) {
            QSignalBlocker bk(m_balanceSlider);
            m_balanceSlider->setValue(value);
            if (m_balanceFilter != nullptr) {
                m_balanceFilter->set("start", (value + 50) / 100.);
                m_balanceFilter->set("disable", value == 0 ? 1 : 0);
                m_levels.clear();
                emit m_manager->purgeCache();
                pCore->setDocumentModified();
            }
        });
    }
370
    auto *lay = new QVBoxLayout;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
371
    setContentsMargins(0, 0, 0, 0);
Laurent Montel's avatar
Laurent Montel committed
372
    lay->setContentsMargins(0, 0, 0, 0);
373
    lay->addWidget(m_trackLabel);
374
    auto *buttonslay = new QHBoxLayout;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
375
    buttonslay->setSpacing(0);
376
    buttonslay->setContentsMargins(0, 0, 0, 0);
377
378
379
    if (m_collapse) {
        buttonslay->addWidget(m_collapse);
    }
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
380
381
382
383
    buttonslay->addWidget(mute);
    if (m_solo) {
        buttonslay->addWidget(m_solo);
    }
384
385
386
    if (m_record) {
        buttonslay->addWidget(m_record);
    }
Julius Künzel's avatar
Julius Künzel committed
387
    buttonslay->addWidget(showEffects);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
388
    lay->addLayout(buttonslay);
389
    if (m_balanceSlider) {
390
        auto *balancelay = new QGridLayout;
391
392
393
394
395
396
        balancelay->addWidget(m_balanceSlider, 0, 0, 1, 3);
        balancelay->addWidget(labelLeft, 1, 0, 1, 1);
        balancelay->addWidget(m_balanceSpin, 1, 1, 1, 1);
        balancelay->addWidget(labelRight, 1, 2, 1, 1);
        lay->addLayout(balancelay);
    }
397
    auto *hlay = new QHBoxLayout;
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
398
399
400
401
    hlay->addWidget(m_audioMeterWidget.get());
    hlay->addWidget(m_volumeSlider);
    lay->addLayout(hlay);
    lay->addWidget(m_volumeSpin);
402
    lay->setStretch(4, 10);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
403
404
405
406
407
408
    setLayout(lay);
    if (service->get_int("hide") > 1) {
        setMute(true);
    }
}

409
410
411
412
void MixerWidget::mousePressEvent(QMouseEvent *event)
{
    if(event->button() == Qt::RightButton) {
        QWidget *child = childAt(event->pos());
Julius Künzel's avatar
Julius Künzel committed
413
        if (child == m_balanceSlider) {
414
415
            m_balanceSpin->setValue(0);
        } else if (child == m_volumeSlider) {
416
            m_volumeSlider->setValue(60);
417
418
419
420
421
422
        }
    } else {
        QWidget::mousePressEvent(event);
    }
}

Julius Künzel's avatar
Julius Künzel committed
423
424
425
426
427
428
429
430
431
void MixerWidget::setTrackName(const QString &name) {
    // Show only tag on master or if name is empty
    if (name.isEmpty() || m_tid == -1) {
        m_trackLabel->setText(m_trackTag);
    } else {
        m_trackLabel->setText(QString("%1 - %2").arg(m_trackTag).arg(name));
    }
}

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
432
433
434
435
436
437
void MixerWidget::setMute(bool mute)
{
    m_muteAction->setActive(mute);
    m_volumeSlider->setEnabled(!mute);
    m_volumeSpin->setEnabled(!mute);
    m_audioMeterWidget->setEnabled(!mute);
438
439
440
441
    if (m_balanceSlider) {
        m_balanceSpin->setEnabled(!mute);
        m_balanceSlider->setEnabled(!mute);
    }
442
443
444
445
446
447
448
449
450
451
452
    updateLabel();
}

void MixerWidget::updateLabel()
{
    if (m_recording) {
        QPalette pal = m_trackLabel->palette();
        pal.setColor(QPalette::Window, Qt::red);
        m_trackLabel->setPalette(pal);
    } else if (m_muteAction->isActive()) {
        QPalette pal = m_trackLabel->palette();
Vincent Pinon's avatar
Vincent Pinon committed
453
        pal.setColor(QPalette::Window, QColor(0xff8c00));
454
        m_trackLabel->setPalette(pal);
455
    } else if (m_solo && m_solo->isChecked()) {
456
457
458
459
460
461
462
        QPalette pal = m_trackLabel->palette();
        pal.setColor(QPalette::Window, Qt::darkGreen);
        m_trackLabel->setPalette(pal);
    } else {
        QPalette pal = palette();
        m_trackLabel->setPalette(pal);
    }
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
463
464
465
466
467
468
}

void MixerWidget::updateAudioLevel(int pos)
{
    QMutexLocker lk(&m_storeMutex);
    if (m_levels.contains(pos)) {
469
        m_audioMeterWidget->setAudioValues(m_levels.value(pos));
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
470
471
        //m_levels.remove(pos);
    } else {
472
        m_audioMeterWidget->setAudioValues(m_audioData);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
473
474
475
    }
}

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
476
477
478
479
480

void MixerWidget::reset()
{
    QMutexLocker lk(&m_storeMutex);
    m_levels.clear();
481
    m_audioMeterWidget->setAudioValues(m_audioData);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
482
483
484
}

void MixerWidget::clear()
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
485
{
486
    QMutexLocker lk(&m_storeMutex);
Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
487
488
489
    m_levels.clear();
}

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
490

Jean-Baptiste Mardelle's avatar
Jean-Baptiste Mardelle committed
491
492
493
494
495
496
497
498
499
500
501
502
503
bool MixerWidget::isMute() const
{
    return m_muteAction->isActive();
}

void MixerWidget::unSolo()
{
    if (m_solo) {
        QSignalBlocker bl(m_solo);
        m_solo->setChecked(false);
    }
}

504
505
506
507
508
509
510
void MixerWidget::gotRecLevels(QVector<qreal>levels)
{
    switch (levels.size()) {
        case 0:
            m_audioMeterWidget->setAudioValues({-100, -100});
            break;
        case 1:
511
            m_audioMeterWidget->setAudioValues({IEC_Scale(levels[0]), -100});
512
513
            break;
        default:
514
            m_audioMeterWidget->setAudioValues({IEC_Scale(levels[0]), IEC_Scale(levels[1])});
515
516
517
518
519
520
521
            break;
    }
}

void MixerWidget::setRecordState(bool recording)
{
    m_recording = recording;
522
    m_record->setChecked(m_recording);
523
524
525
526
    QSignalBlocker bk(m_volumeSpin);
    QSignalBlocker bk2(m_volumeSlider);
    if (m_recording) {
        connect(pCore->getAudioDevice(), &MediaCapture::audioLevels, this, &MixerWidget::gotRecLevels);
527
528
529
530
        if (m_balanceSlider) {
            m_balanceSlider->setEnabled(false);
            m_balanceSpin->setEnabled(false);
        }
531
532
533
534
535
        m_volumeSpin->setRange(0, 100);
        m_volumeSpin->setSuffix(QStringLiteral("%"));
        m_volumeSpin->setValue(KdenliveSettings::audiocapturevolume());
        m_volumeSlider->setValue(KdenliveSettings::audiocapturevolume());
    } else {
536
537
538
539
        if (m_balanceSlider) {
            m_balanceSlider->setEnabled(true);
            m_balanceSpin->setEnabled(true);
        }
540
541
542
543
544
        int level = m_levelFilter->get_int("level");
        disconnect(pCore->getAudioDevice(), &MediaCapture::audioLevels, this, &MixerWidget::gotRecLevels);
        m_volumeSpin->setRange(-100, 60);
        m_volumeSpin->setSuffix(i18n("dB"));
        m_volumeSpin->setValue(level);
545
        m_volumeSlider->setValue(fromDB(level));
546
    }
547
    updateLabel();
548
}
549

550
void MixerWidget::connectMixer(bool doConnect)
551
{
552
    if (doConnect) {
553
        if (m_listener == nullptr) {
554
            m_listener = m_monitorFilter->listen("property-changed", this, reinterpret_cast<mlt_listener>(property_changed));
555
556
557
558
559
560
        }
    } else {
        delete m_listener;
        m_listener = nullptr;
    }
}
561
562
563
564
565
566
567

void MixerWidget::pauseMonitoring(bool pause)
{
    if (m_monitorFilter) {
        m_monitorFilter->set("disable", pause ? 1 : 0);
    }
}