diff options
Diffstat (limited to 'arts/tools/levelmeters.cpp')
-rw-r--r-- | arts/tools/levelmeters.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/arts/tools/levelmeters.cpp b/arts/tools/levelmeters.cpp new file mode 100644 index 00000000..3b2ca1ac --- /dev/null +++ b/arts/tools/levelmeters.cpp @@ -0,0 +1,239 @@ +#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" |