0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-19 20:32:15 +02:00

Implemented a simple volume meter widget

This commit is contained in:
HomeWorld 2014-07-14 19:32:39 +03:00
parent 336c3821fc
commit 37828ce26d
2 changed files with 101 additions and 36 deletions

View File

@ -5,6 +5,7 @@
#include <QVBoxLayout>
#include <QSlider>
#include <QLabel>
#include <QPainter>
#include <string>
#include <math.h>
@ -13,6 +14,12 @@ using namespace std;
#define VOL_MIN -96.0f
#define VOL_MAX 0.0f
/*
VOL_MIN_LOG = DBToLog(VOL_MIN)
VOL_MAX_LOG = DBToLog(VOL_MAX)
... just in case someone wants to use a smaller scale
*/
#define VOL_MIN_LOG -2.0086001717619175
#define VOL_MAX_LOG -0.77815125038364363
@ -40,18 +47,14 @@ void VolControl::OBSVolumeChanged(void *data, calldata_t calldata)
void VolControl::OBSVolumeLevel(void *data, calldata_t calldata)
{
VolControl *volControl = static_cast<VolControl*>(data);
float level = calldata_float(calldata, "level");
float mag = calldata_float(calldata, "magnitude");
/*
* TODO: an actual volume control that can process level, mag, peak.
*
* for the time being, just average level and magnitude.
*/
float result = (level + mag) * 0.5f;
float peak = calldata_float(calldata, "level");
float mag = calldata_float(calldata, "magnitude");
float peakHold = calldata_float(calldata, "peak");
QMetaObject::invokeMethod(volControl, "VolumeLevel",
Q_ARG(float, result));
Q_ARG(float, mag),
Q_ARG(float, peak),
Q_ARG(float, peakHold));
}
void VolControl::VolumeChanged(int vol)
@ -61,22 +64,20 @@ void VolControl::VolumeChanged(int vol)
signalChanged = true;
}
void VolControl::VolumeLevel(float level)
void VolControl::VolumeLevel(float mag, float peak, float peakHold)
{
uint64_t curMeterTime = os_gettime_ns() / 1000000;
levelTotal += level;
levelCount += 1.0f;
/*
Add again peak averaging?
*/
/* only update after a certain amount of time */
if ((curMeterTime - lastMeterTime) > UPDATE_INTERVAL_MS) {
lastMeterTime = curMeterTime;
float finalLevel = levelTotal / levelCount;
volMeter->setValue(int(DBToLinear(finalLevel) * 10000.0f));
levelTotal = 0.0f;
levelCount = 0.0f;
volMeter->setLevels(DBToLinear(mag),
DBToLinear(peak),
DBToLinear(peakHold));
}
}
@ -118,7 +119,7 @@ VolControl::VolControl(OBSSource source_)
nameLabel = new QLabel();
volLabel = new QLabel();
volMeter = new QProgressBar();
volMeter = new VolumeMeter();
slider = new QSlider(Qt::Horizontal);
QFont font = nameLabel->font();
@ -133,18 +134,6 @@ VolControl::VolControl(OBSSource source_)
slider->setValue(vol);
// slider->setMaximumHeight(13);
volMeter->setMaximumHeight(1);
volMeter->setMinimum(0);
volMeter->setMaximum(10000);
volMeter->setTextVisible(false);
/* [Danni] Temporary color. */
QString testColor = "QProgressBar "
"{border: 0px} "
"QProgressBar::chunk "
"{width: 1px; background-color: #AA0000;}";
volMeter->setStyleSheet(testColor);
textLayout->setContentsMargins(0, 0, 0, 0);
textLayout->addWidget(nameLabel);
textLayout->addWidget(volLabel);
@ -177,3 +166,69 @@ VolControl::~VolControl()
signal_handler_disconnect(obs_source_signalhandler(source),
"volume_level", OBSVolumeLevel, this);
}
VolumeMeter::VolumeMeter(QWidget *parent)
: QWidget(parent)
{
setMinimumSize(1, 3);
bkColor.setRgb(0xDD, 0xDD, 0xDD);
magColor.setRgb(0x20, 0x7D, 0x17);
peakColor.setRgb(0x3E, 0xF1, 0x2B);
peakHoldColor.setRgb(0x00, 0x00, 0x00);
setLevels(0.0f, 0.0f, 0.0f);
}
void VolumeMeter::setLevels(float nmag, float npeak, float npeakHold)
{
mag = nmag;
peak = npeak;
peakHold = npeakHold;
update();
}
void VolumeMeter::paintEvent(QPaintEvent *event)
{
UNUSED_PARAMETER(event);
QPainter painter(this);
QLinearGradient gradient;
int width = size().width();
int height = size().height();
int scaledMag = int((float)width * mag);
int scaledPeak = int((float)width * peak);
int scaledPeakHold = int((float)width * peakHold);
gradient.setStart(qreal(scaledMag), 0);
gradient.setFinalStop(qreal(scaledPeak), 0);
gradient.setColorAt(0, magColor);
gradient.setColorAt(1, peakColor);
// RMS
painter.fillRect(0, 0,
scaledMag, height,
magColor);
// RMS - Peak gradient
painter.fillRect(scaledMag, 0,
scaledPeak - scaledMag + 1, height,
QBrush(gradient));
// Background
painter.fillRect(scaledPeak, 0,
width - scaledPeak, height,
bkColor);
// Peak hold
if(peakHold == 1.0f)
scaledPeakHold--;
painter.setPen(peakHoldColor);
painter.drawLine(scaledPeakHold, 0,
scaledPeakHold, height);
}

View File

@ -2,9 +2,19 @@
#include <obs.hpp>
#include <QWidget>
#include <QProgressBar>
/* TODO: Make a real volume control that isn't terrible */
class VolumeMeter : public QWidget
{
Q_OBJECT
private:
float mag, peak, peakHold;
QColor bkColor, magColor, peakColor, peakHoldColor;
public:
explicit VolumeMeter(QWidget *parent = 0);
void setLevels(float nmag, float npeak, float npeakHold);
protected:
void paintEvent(QPaintEvent *event);
};
class QLabel;
class QSlider;
@ -16,7 +26,7 @@ private:
OBSSource source;
QLabel *nameLabel;
QLabel *volLabel;
QProgressBar *volMeter;
VolumeMeter *volMeter;
QSlider *slider;
bool signalChanged;
uint64_t lastMeterTime;
@ -28,7 +38,7 @@ private:
private slots:
void VolumeChanged(int vol);
void VolumeLevel(float level);
void VolumeLevel(float mag, float peak, float peakHold);
void SliderChanged(int vol);
public: