提交 defceeef 编写于 作者: J Jim

Merge pull request #169 from hwdro/master

Simple volume meter widget
......@@ -565,8 +565,15 @@ static void calc_volume_levels(struct obs_source *source, float *array,
max_val = fmaxf(max_val, val_pow2);
}
rms_val = to_db(sqrtf(sum_val / (float)count * volume));
max_val = to_db(sqrtf(max_val * volume));
/*
We want the volume meters scale linearly in respect to current
volume, so, no need to apply volume here.
*/
UNUSED_PARAMETER(volume);
rms_val = to_db(sqrtf(sum_val / (float)count));
max_val = to_db(sqrtf(max_val));
if (max_val > source->vol_max)
source->vol_max = max_val;
......
......@@ -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,21 @@ 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) {
float vol = (float)slider->value() * 0.01f;
lastMeterTime = curMeterTime;
float finalLevel = levelTotal / levelCount;
volMeter->setValue(int(DBToLinear(finalLevel) * 10000.0f));
levelTotal = 0.0f;
levelCount = 0.0f;
volMeter->setLevels(DBToLinear(mag) * vol,
DBToLinear(peak) * vol,
DBToLinear(peakHold) * vol);
}
}
......@@ -118,7 +120,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 +135,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 +167,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);
}
......@@ -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:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册