2016-02-23 23:16:51 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <obs.hpp>
|
|
|
|
#include <QWidget>
|
2018-12-16 16:14:58 +00:00
|
|
|
#include <QPaintEvent>
|
2017-04-19 19:54:15 +00:00
|
|
|
#include <QSharedPointer>
|
|
|
|
#include <QTimer>
|
|
|
|
#include <QMutex>
|
|
|
|
#include <QList>
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
class QPushButton;
|
2017-04-19 19:54:15 +00:00
|
|
|
class VolumeMeterTimer;
|
2016-02-23 23:16:51 +00:00
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
class VolumeMeter : public QWidget {
|
2016-02-23 23:16:51 +00:00
|
|
|
Q_OBJECT
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_PROPERTY(QColor backgroundNominalColor READ getBackgroundNominalColor
|
|
|
|
WRITE setBackgroundNominalColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor backgroundWarningColor READ getBackgroundWarningColor
|
|
|
|
WRITE setBackgroundWarningColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor backgroundErrorColor READ getBackgroundErrorColor
|
|
|
|
WRITE setBackgroundErrorColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor foregroundNominalColor READ getForegroundNominalColor
|
|
|
|
WRITE setForegroundNominalColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor foregroundWarningColor READ getForegroundWarningColor
|
|
|
|
WRITE setForegroundWarningColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor foregroundErrorColor READ getForegroundErrorColor
|
|
|
|
WRITE setForegroundErrorColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor clipColor READ getClipColor WRITE setClipColor
|
|
|
|
DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor magnitudeColor READ getMagnitudeColor WRITE
|
|
|
|
setMagnitudeColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor majorTickColor READ getMajorTickColor WRITE
|
|
|
|
setMajorTickColor DESIGNABLE true)
|
|
|
|
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE
|
|
|
|
setMinorTickColor DESIGNABLE true)
|
2018-02-19 19:54:37 +00:00
|
|
|
|
|
|
|
// Levels are denoted in dBFS.
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel
|
|
|
|
DESIGNABLE true)
|
|
|
|
Q_PROPERTY(qreal warningLevel READ getWarningLevel WRITE setWarningLevel
|
|
|
|
DESIGNABLE true)
|
|
|
|
Q_PROPERTY(qreal errorLevel READ getErrorLevel WRITE setErrorLevel
|
|
|
|
DESIGNABLE true)
|
|
|
|
Q_PROPERTY(qreal clipLevel READ getClipLevel WRITE setClipLevel
|
|
|
|
DESIGNABLE true)
|
|
|
|
Q_PROPERTY(qreal minimumInputLevel READ getMinimumInputLevel WRITE
|
|
|
|
setMinimumInputLevel DESIGNABLE true)
|
2018-02-19 19:54:37 +00:00
|
|
|
|
|
|
|
// Rates are denoted in dB/second.
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_PROPERTY(qreal peakDecayRate READ getPeakDecayRate WRITE
|
|
|
|
setPeakDecayRate DESIGNABLE true)
|
2018-02-19 19:54:37 +00:00
|
|
|
|
|
|
|
// Time in seconds for the VU meter to integrate over.
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_PROPERTY(
|
|
|
|
qreal magnitudeIntegrationTime READ getMagnitudeIntegrationTime
|
|
|
|
WRITE setMagnitudeIntegrationTime DESIGNABLE true)
|
2018-02-19 19:54:37 +00:00
|
|
|
|
|
|
|
// Duration is denoted in seconds.
|
2019-09-22 21:19:10 +00:00
|
|
|
Q_PROPERTY(qreal peakHoldDuration READ getPeakHoldDuration WRITE
|
|
|
|
setPeakHoldDuration DESIGNABLE true)
|
|
|
|
Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration
|
|
|
|
WRITE setInputPeakHoldDuration DESIGNABLE true)
|
2016-02-23 23:16:51 +00:00
|
|
|
|
2018-12-16 16:14:58 +00:00
|
|
|
private slots:
|
|
|
|
void ClipEnding();
|
|
|
|
|
2016-02-23 23:16:51 +00:00
|
|
|
private:
|
2018-02-19 19:54:37 +00:00
|
|
|
obs_volmeter_t *obs_volmeter;
|
2017-04-19 19:54:15 +00:00
|
|
|
static QWeakPointer<VolumeMeterTimer> updateTimer;
|
|
|
|
QSharedPointer<VolumeMeterTimer> updateTimerRef;
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
inline void resetLevels();
|
|
|
|
inline void handleChannelCofigurationChange();
|
|
|
|
inline bool detectIdle(uint64_t ts);
|
|
|
|
inline void calculateBallistics(uint64_t ts,
|
2019-09-22 21:19:10 +00:00
|
|
|
qreal timeSinceLastRedraw = 0.0);
|
|
|
|
inline void calculateBallisticsForChannel(int channelNr, uint64_t ts,
|
|
|
|
qreal timeSinceLastRedraw);
|
2018-02-19 19:54:37 +00:00
|
|
|
|
2018-12-16 16:14:58 +00:00
|
|
|
void paintInputMeter(QPainter &painter, int x, int y, int width,
|
2019-09-22 21:19:10 +00:00
|
|
|
int height, float peakHold);
|
2018-12-16 16:14:58 +00:00
|
|
|
void paintHMeter(QPainter &painter, int x, int y, int width, int height,
|
2019-09-22 21:19:10 +00:00
|
|
|
float magnitude, float peak, float peakHold);
|
2018-12-16 16:14:58 +00:00
|
|
|
void paintHTicks(QPainter &painter, int x, int y, int width,
|
2019-09-22 21:19:10 +00:00
|
|
|
int height);
|
2018-12-16 16:14:58 +00:00
|
|
|
void paintVMeter(QPainter &painter, int x, int y, int width, int height,
|
2019-09-22 21:19:10 +00:00
|
|
|
float magnitude, float peak, float peakHold);
|
2018-12-16 16:14:58 +00:00
|
|
|
void paintVTicks(QPainter &painter, int x, int y, int height);
|
2017-04-19 19:54:15 +00:00
|
|
|
|
|
|
|
QMutex dataMutex;
|
|
|
|
|
2018-02-19 19:54:37 +00:00
|
|
|
uint64_t currentLastUpdateTime = 0;
|
|
|
|
float currentMagnitude[MAX_AUDIO_CHANNELS];
|
|
|
|
float currentPeak[MAX_AUDIO_CHANNELS];
|
|
|
|
float currentInputPeak[MAX_AUDIO_CHANNELS];
|
|
|
|
|
2018-12-16 16:14:58 +00:00
|
|
|
QPixmap *tickPaintCache = nullptr;
|
2018-02-19 19:54:37 +00:00
|
|
|
int displayNrAudioChannels = 0;
|
|
|
|
float displayMagnitude[MAX_AUDIO_CHANNELS];
|
|
|
|
float displayPeak[MAX_AUDIO_CHANNELS];
|
|
|
|
float displayPeakHold[MAX_AUDIO_CHANNELS];
|
|
|
|
uint64_t displayPeakHoldLastUpdateTime[MAX_AUDIO_CHANNELS];
|
|
|
|
float displayInputPeakHold[MAX_AUDIO_CHANNELS];
|
|
|
|
uint64_t displayInputPeakHoldLastUpdateTime[MAX_AUDIO_CHANNELS];
|
|
|
|
|
|
|
|
QFont tickFont;
|
|
|
|
QColor backgroundNominalColor;
|
|
|
|
QColor backgroundWarningColor;
|
|
|
|
QColor backgroundErrorColor;
|
|
|
|
QColor foregroundNominalColor;
|
|
|
|
QColor foregroundWarningColor;
|
|
|
|
QColor foregroundErrorColor;
|
|
|
|
QColor clipColor;
|
|
|
|
QColor magnitudeColor;
|
|
|
|
QColor majorTickColor;
|
|
|
|
QColor minorTickColor;
|
|
|
|
qreal minimumLevel;
|
|
|
|
qreal warningLevel;
|
|
|
|
qreal errorLevel;
|
|
|
|
qreal clipLevel;
|
|
|
|
qreal minimumInputLevel;
|
|
|
|
qreal peakDecayRate;
|
|
|
|
qreal magnitudeIntegrationTime;
|
|
|
|
qreal peakHoldDuration;
|
|
|
|
qreal inputPeakHoldDuration;
|
|
|
|
|
|
|
|
uint64_t lastRedrawTime = 0;
|
2019-07-27 12:47:10 +00:00
|
|
|
int channels = 0;
|
2018-12-16 16:14:58 +00:00
|
|
|
bool clipping = false;
|
|
|
|
bool vertical;
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
public:
|
2018-12-16 16:14:58 +00:00
|
|
|
explicit VolumeMeter(QWidget *parent = nullptr,
|
2019-09-22 21:19:10 +00:00
|
|
|
obs_volmeter_t *obs_volmeter = nullptr,
|
|
|
|
bool vertical = false);
|
2017-04-19 19:54:15 +00:00
|
|
|
~VolumeMeter();
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
|
|
|
|
const float peak[MAX_AUDIO_CHANNELS],
|
|
|
|
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
2018-02-19 19:54:37 +00:00
|
|
|
|
|
|
|
QColor getBackgroundNominalColor() const;
|
|
|
|
void setBackgroundNominalColor(QColor c);
|
|
|
|
QColor getBackgroundWarningColor() const;
|
|
|
|
void setBackgroundWarningColor(QColor c);
|
|
|
|
QColor getBackgroundErrorColor() const;
|
|
|
|
void setBackgroundErrorColor(QColor c);
|
|
|
|
QColor getForegroundNominalColor() const;
|
|
|
|
void setForegroundNominalColor(QColor c);
|
|
|
|
QColor getForegroundWarningColor() const;
|
|
|
|
void setForegroundWarningColor(QColor c);
|
|
|
|
QColor getForegroundErrorColor() const;
|
|
|
|
void setForegroundErrorColor(QColor c);
|
|
|
|
QColor getClipColor() const;
|
|
|
|
void setClipColor(QColor c);
|
|
|
|
QColor getMagnitudeColor() const;
|
|
|
|
void setMagnitudeColor(QColor c);
|
|
|
|
QColor getMajorTickColor() const;
|
|
|
|
void setMajorTickColor(QColor c);
|
|
|
|
QColor getMinorTickColor() const;
|
|
|
|
void setMinorTickColor(QColor c);
|
|
|
|
qreal getMinimumLevel() const;
|
|
|
|
void setMinimumLevel(qreal v);
|
|
|
|
qreal getWarningLevel() const;
|
|
|
|
void setWarningLevel(qreal v);
|
|
|
|
qreal getErrorLevel() const;
|
|
|
|
void setErrorLevel(qreal v);
|
|
|
|
qreal getClipLevel() const;
|
|
|
|
void setClipLevel(qreal v);
|
|
|
|
qreal getMinimumInputLevel() const;
|
|
|
|
void setMinimumInputLevel(qreal v);
|
|
|
|
qreal getPeakDecayRate() const;
|
|
|
|
void setPeakDecayRate(qreal v);
|
|
|
|
qreal getMagnitudeIntegrationTime() const;
|
|
|
|
void setMagnitudeIntegrationTime(qreal v);
|
|
|
|
qreal getPeakHoldDuration() const;
|
|
|
|
void setPeakHoldDuration(qreal v);
|
|
|
|
qreal getInputPeakHoldDuration() const;
|
|
|
|
void setInputPeakHoldDuration(qreal v);
|
2018-12-16 16:14:58 +00:00
|
|
|
void setPeakMeterType(enum obs_peak_meter_type peakMeterType);
|
2019-07-27 12:47:10 +00:00
|
|
|
virtual void mousePressEvent(QMouseEvent *event) override;
|
|
|
|
virtual void wheelEvent(QWheelEvent *event) override;
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
protected:
|
2018-12-16 16:14:58 +00:00
|
|
|
void paintEvent(QPaintEvent *event) override;
|
2017-04-19 19:54:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class VolumeMeterTimer : public QTimer {
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
public:
|
|
|
|
inline VolumeMeterTimer() : QTimer() {}
|
|
|
|
|
|
|
|
void AddVolControl(VolumeMeter *meter);
|
|
|
|
void RemoveVolControl(VolumeMeter *meter);
|
|
|
|
|
|
|
|
protected:
|
2018-12-16 16:14:58 +00:00
|
|
|
void timerEvent(QTimerEvent *event) override;
|
2019-09-22 21:19:10 +00:00
|
|
|
QList<VolumeMeter *> volumeMeters;
|
2016-02-23 23:16:51 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class QLabel;
|
|
|
|
class QSlider;
|
|
|
|
class MuteCheckBox;
|
|
|
|
|
|
|
|
class VolControl : public QWidget {
|
|
|
|
Q_OBJECT
|
|
|
|
|
|
|
|
private:
|
|
|
|
OBSSource source;
|
2019-09-22 21:19:10 +00:00
|
|
|
QLabel *nameLabel;
|
|
|
|
QLabel *volLabel;
|
|
|
|
VolumeMeter *volMeter;
|
|
|
|
QSlider *slider;
|
|
|
|
MuteCheckBox *mute;
|
|
|
|
QPushButton *config = nullptr;
|
|
|
|
float levelTotal;
|
|
|
|
float levelCount;
|
|
|
|
obs_fader_t *obs_fader;
|
|
|
|
obs_volmeter_t *obs_volmeter;
|
|
|
|
bool vertical;
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
static void OBSVolumeChanged(void *param, float db);
|
2018-02-19 19:54:37 +00:00
|
|
|
static void OBSVolumeLevel(void *data,
|
2019-09-22 21:19:10 +00:00
|
|
|
const float magnitude[MAX_AUDIO_CHANNELS],
|
|
|
|
const float peak[MAX_AUDIO_CHANNELS],
|
|
|
|
const float inputPeak[MAX_AUDIO_CHANNELS]);
|
2016-02-23 23:16:51 +00:00
|
|
|
static void OBSVolumeMuted(void *data, calldata_t *calldata);
|
|
|
|
|
|
|
|
void EmitConfigClicked();
|
|
|
|
|
|
|
|
private slots:
|
|
|
|
void VolumeChanged();
|
|
|
|
void VolumeMuted(bool muted);
|
|
|
|
|
|
|
|
void SetMuted(bool checked);
|
|
|
|
void SliderChanged(int vol);
|
|
|
|
void updateText();
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void ConfigClicked();
|
|
|
|
|
|
|
|
public:
|
2018-12-16 16:14:58 +00:00
|
|
|
explicit VolControl(OBSSource source, bool showConfig = false,
|
2019-09-22 21:19:10 +00:00
|
|
|
bool vertical = false);
|
2016-02-23 23:16:51 +00:00
|
|
|
~VolControl();
|
|
|
|
|
2019-09-22 21:19:10 +00:00
|
|
|
inline obs_source_t *GetSource() const { return source; }
|
2016-02-23 23:16:51 +00:00
|
|
|
|
|
|
|
QString GetName() const;
|
|
|
|
void SetName(const QString &newName);
|
2018-02-19 19:54:37 +00:00
|
|
|
|
|
|
|
void SetMeterDecayRate(qreal q);
|
2018-12-16 16:14:58 +00:00
|
|
|
void setPeakMeterType(enum obs_peak_meter_type peakMeterType);
|
2016-02-23 23:16:51 +00:00
|
|
|
};
|