You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
240 lines
5.4 KiB
240 lines
5.4 KiB
#include <qlayout.h>
|
|
#include <qpainter.h>
|
|
#include <qfontmetrics.h>
|
|
#include <qptrlist.h>
|
|
#include <kled.h>
|
|
#include "levelmeters.h"
|
|
|
|
const int PeakBar::peakMillis=1500;
|
|
|
|
PeakBar::PeakBar(QWidget *parent)
|
|
: ACLevelMeter(parent)
|
|
, maxValue( 0.0f )
|
|
, minValue( 0.0f )
|
|
{
|
|
clipped = false;
|
|
displayMinPeak= false;
|
|
horizontalMode= false;
|
|
currentValue= 0.0f;
|
|
|
|
lastValues.setAutoDelete( TRUE );
|
|
|
|
setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
|
|
setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred));
|
|
setBackgroundMode(NoBackground);
|
|
setMinimumSize(frameWidth()+7, 70);
|
|
}
|
|
|
|
void PeakBar::frameChanged() {
|
|
setMinimumSize(frameWidth()+7, 70);
|
|
QFrame::frameChanged();
|
|
}
|
|
|
|
QSize PeakBar::sizeHint() const {
|
|
return QSize(13, 250);
|
|
}
|
|
|
|
void PeakBar::checkMinMax() {
|
|
int mustRecheck= 0; // bool
|
|
Observation *o;
|
|
|
|
while ((o= lastValues.first()) && o->time.elapsed() > peakMillis) {
|
|
lastValues.removeFirst();
|
|
mustRecheck= 1;
|
|
}
|
|
|
|
if (mustRecheck) {
|
|
maxValue= 0.f;
|
|
minValue= 1.f;
|
|
clipped = false;
|
|
for (QPtrListIterator<Observation> it(lastValues); it.current(); ++it) {
|
|
float value= it.current()->value;
|
|
if (value>maxValue)
|
|
maxValue= value;
|
|
if (value<minValue)
|
|
minValue= value;
|
|
if (value > 1.f)
|
|
clipped = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
void PeakBar::drawContents(QPainter *p)
|
|
{
|
|
QRect size= contentsRect();
|
|
|
|
checkMinMax();
|
|
|
|
p->setBrush(clipped ? darkRed : darkBlue);
|
|
p->setPen(NoPen);
|
|
p->drawRect(size);
|
|
|
|
QRect bar= size;
|
|
p->setBrush(clipped ? red : blue);
|
|
if (horizontalMode) {
|
|
bar.setWidth((int)(bar.width()*currentValue));
|
|
} else {
|
|
int newHeight= (int)(bar.height()*currentValue);
|
|
bar.moveBy(0, bar.height()-newHeight);
|
|
bar.setHeight(newHeight);
|
|
}
|
|
p->drawRect(bar);
|
|
|
|
int y;
|
|
// TODO: if (horizontalMode)
|
|
if (displayMinPeak) {
|
|
y= frameWidth()+size.height()-((int)(size.height()*minValue));
|
|
p->setPen(white);
|
|
p->drawLine(frameWidth(), y, frameWidth()+size.width()-1, y);
|
|
}
|
|
y= frameWidth()+size.height()-((int)(size.height()*maxValue));
|
|
p->setPen(white);
|
|
p->drawLine(frameWidth(), y, frameWidth()+size.width()-1, y);
|
|
}
|
|
|
|
void PeakBar::setValue(float f) {
|
|
if (f > 1.f)
|
|
clipped = true;
|
|
|
|
currentValue= f;
|
|
if (f>=maxValue)
|
|
maxValue= f;
|
|
if (displayMinPeak && (f<=minValue))
|
|
minValue= f;
|
|
|
|
lastValues.append(new Observation(f));
|
|
|
|
repaint();
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
PeakLevelMeters::PeakLevelMeters(QWidget *parent):
|
|
StereoLevelMeter(parent), left(this), right(this), scaleView(this)
|
|
{
|
|
QBoxLayout *layout= new QHBoxLayout(this);
|
|
layout->addWidget(&left);
|
|
// layout->setStretchFactor(&left, 0);
|
|
layout->addWidget(&right);
|
|
// layout->setStretchFactor(&right, 0);
|
|
layout->addWidget(&scaleView);
|
|
// layout->setStretchFactor(&scaleView, 0);
|
|
left.setLineWidth(2);
|
|
right.setLineWidth(2);
|
|
scaleView.setScaleMargins(right.frameWidth());
|
|
setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred));
|
|
|
|
setDbRange(36);
|
|
}
|
|
|
|
void PeakLevelMeters::setDbRange(int db) {
|
|
dbRange= db;
|
|
scaleView.setDbRange(db);
|
|
}
|
|
|
|
void PeakLevelMeters::setValues(float leftVal, float rightVal) {
|
|
float f= 1.0f+levelToDB(leftVal)/dbRange;
|
|
if (f<0.f) f= 0.f;
|
|
left.setValue(f);
|
|
|
|
f= 1.0f+levelToDB(rightVal)/dbRange;
|
|
if (f<0.f) f= 0.f;
|
|
right.setValue(f);
|
|
}
|
|
|
|
ScaleView::ScaleView(QWidget *parent): QFrame(parent) {
|
|
font.setPixelSize(10);
|
|
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred));
|
|
}
|
|
|
|
void ScaleView::setDbRange(int db) {
|
|
dbRange= db;
|
|
repaint();
|
|
}
|
|
|
|
QSize ScaleView::sizeHint() const {
|
|
return QSize(QFontMetrics(font).width("-88")+8, 250);
|
|
}
|
|
|
|
void ScaleView::drawContents(QPainter *p) {
|
|
QRect size= contentsRect();
|
|
size.rTop()+= upperMargin;
|
|
size.rBottom()-= lowerMargin;
|
|
|
|
QFrame::drawContents(p); // clear background
|
|
|
|
int step=3;
|
|
while (dbRange/step*20>size.height())
|
|
step*=2;
|
|
|
|
/* float offset= ((float)size.height()*step)/dbRange, pos=0.f;
|
|
p->setPen(black);
|
|
p->drawLine(0, (, size.width()*3/5, y);*/
|
|
|
|
p->setPen(black);
|
|
p->setFont(font);
|
|
QString numStr;
|
|
for (int i=0; i<=dbRange; i++) {
|
|
int y= size.top()+(size.height()-1)*i/dbRange;
|
|
if (i%step==0) {
|
|
p->drawLine(0, y, 4, y);
|
|
numStr.setNum(-i);
|
|
p->drawText(8, y+5, numStr);
|
|
} else
|
|
p->drawLine(0, y, 2, y);
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
LedMeter::LedMeter(QWidget *parent, bool blueState) : ACLevelMeter(parent) {
|
|
setBackgroundColor(black);
|
|
QBoxLayout * l = new QVBoxLayout( this );
|
|
l->setAutoAdd(TRUE);
|
|
for(int i=0;i<12;i++) {
|
|
QColor c;
|
|
if(blueState)
|
|
c = blue;
|
|
else {
|
|
c = red;
|
|
if(i>=2) c = yellow;
|
|
if(i>=5) c = green;
|
|
}
|
|
|
|
// put each led in its own frame, since it seems to be broken
|
|
QFrame *lframe = new QFrame(this);
|
|
QBoxLayout *lfl = new QVBoxLayout( lframe );
|
|
lfl->setAutoAdd(TRUE);
|
|
leds[i] =
|
|
new KLed(c,KLed::Off, KLed::Sunken, KLed::Circular,lframe);
|
|
}
|
|
}
|
|
|
|
void LedMeter::setValue(float f)
|
|
{
|
|
//printf("value %f\n",f);
|
|
for(int i=11;i>=0;i--)
|
|
{
|
|
if(f > 0.06) leds[i]->setState(KLed::On);
|
|
else leds[i]->setState(KLed::Off);
|
|
f /= 1.25;
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
StereoLedMeters::StereoLedMeters(QWidget *parent)
|
|
: StereoLevelMeter(parent), left(this), right(this)
|
|
{
|
|
QBoxLayout *layout= new QHBoxLayout(this);
|
|
layout->addWidget(&left);
|
|
layout->addWidget(&right);
|
|
}
|
|
|
|
void StereoLedMeters::setValues(float leftVal, float rightVal) {
|
|
left.setValue(leftVal);
|
|
right.setValue(rightVal);
|
|
}
|
|
|
|
#include "levelmeters.moc"
|