yolobs-studio/UI/volume-control.hpp

256 lines
8 KiB
C++
Raw Normal View History

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
};