Logo Search packages:      
Sourcecode: qarecord version File versions  Download package

meter.cpp

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <qwidget.h>
#include <qstring.h>
#include <qpainter.h>
#include <qpen.h>
#include <qpixmap.h>
#include <qbrush.h>
#include <qtimer.h>
#include <qsizepolicy.h>
#include <qsize.h>
#include <math.h>
#include "meter.h"
#include "recdata.h"

Meter::Meter(tickType p_tick, RecData *p_recdata, int *p_maxRef, QWidget* parent, const char *name) 
             : QWidget (parent, name)
{
  tick = p_tick;
  recdata = p_recdata;
  maxRef = p_maxRef;
  globalMaxResetCount = 0;
  globalMax = 0;
  setPalette(QPalette(QColor(0, 20, 100), QColor(0, 20, 100)));
  timer = new QTimer(this);
  QObject::connect(timer, SIGNAL(timeout()), this, SLOT(updateMeter()));
  timer->start(200, true);  
}

Meter::~Meter()
{
}

void Meter::paintEvent(QPaintEvent *) {

  QPixmap pm(width(), height());  
  QPainter p(&pm);
  QPointArray points(7);
  QPen pen;
  double dB, gdB, len, xscale, overscale, over_dB, meter_over;
  int l1, x, x1, x2, gx, max, ofs;

  if ((max = *maxRef) < 0) {
    return;
  }
  pm.fill(QColor(10, 50, 10));
  p.setViewport(0, 0, width(), height());
  p.setWindow(0, 0, width(), height());
  pen.setColor(QColor(20, 160, 20));
  pen.setWidth(1);
  p.setPen(pen);
  p.drawRect(0, 0, width()-1, height()-1);
  len = (double)abs(METER_MINDB);  
  xscale = (double)(width()-6-METER_OVER_WIDTH) / len;  
  meter_over = (recdata->samplesize == 2) ? METER_OVER : METER_OVER32;
  if ((recdata->doCapture || recdata->jackRunning) && (max > 0)) {
    dB = 20.0 * log((double)max/meter_over)/log(10.0);  
//    printf("max: %d dB: %lf\n", max, dB);
    if (dB < METER_MINDB) dB = METER_MINDB;  
    x = (int)((abs(METER_MINDB) + dB) * xscale);  
//  fprintf(stderr, "max: %7d x: %3d dB: %f\n", max, x, dB);
    if (tick == TICK_DOWN) {
      p.fillRect(3, 3, x, height()-3-METER_TICK_WIDTH, QBrush(QColor(40, 150, 40)));
    } else {
      p.fillRect(3, METER_TICK_WIDTH - 1, x, height()-3-METER_TICK_WIDTH, QBrush(QColor(40, 150, 40)));
    }
    if (dB >= -6) {
      x1 = (int)((abs(METER_MINDB) - 6) * xscale);
      x2 = (int)((abs(METER_MINDB) + dB) * xscale);
      if (tick == TICK_DOWN) {
        p.fillRect(3 + x1, 3, x2 - x1, height()-3-METER_TICK_WIDTH, QBrush(QColor(200, 200, 0)));
      } else {
        p.fillRect(3 + x1, METER_TICK_WIDTH - 1, x2 - x1, height()-3-METER_TICK_WIDTH, QBrush(QColor(200, 200, 0)));
      }
    }
    if (dB > 0) {
      over_dB = 20.0 * log(32767.0/meter_over)/log(10.0);
      overscale = (double)METER_OVER_WIDTH / over_dB;
      x1 = (int)(abs(METER_MINDB) * xscale);
      x2 = (int)(dB * overscale);
      if (tick == TICK_DOWN) {
        p.fillRect(3 + x1, 3, x2, height()-3-METER_TICK_WIDTH, QBrush(QColor(200, 0, 0)));
      } else {
        p.fillRect(3 + x1, METER_TICK_WIDTH - 1, x2, height()-3-METER_TICK_WIDTH, QBrush(QColor(200, 0, 0)));
      } 
    }
    pen.setColor(QColor(60, 180, 60));
    pen.setWidth(3);
    gdB = (globalMax > 0) ?  20.0 * log((double)globalMax/meter_over)/log(10.0) : METER_MINDB;
    if (gdB < METER_MINDB) gdB = METER_MINDB;
    gx = (int)((abs(METER_MINDB) + gdB) * xscale);   
    if (gdB > -6) {
      pen.setColor(QColor(240, 240, 0));
    } 
    if (gdB > 0) {
      pen.setColor(QColor(250, 0, 0));
      over_dB = 20.0 * log(32767.0/meter_over)/log(10.0);
      overscale = (double)METER_OVER_WIDTH / over_dB;
      gx = (int)(abs(METER_MINDB) * xscale + gdB * overscale);
    }       
    p.setPen(pen); 
    if (tick == TICK_DOWN) {
      p.drawLine(3 + gx, 3, 3 + gx, height()-METER_TICK_WIDTH); 
    } else {
      p.drawLine(3 + gx, METER_TICK_WIDTH - 1, 3 + gx, height()-4);
    }
    pen.setWidth(2);
  }
  p.setFont(QFont("Helvetica", 8));
  for (l1 = 0; l1 < -METER_MINDB/10 + 1; l1++) {
    if (!l1) {
      ofs = 2;
      pen.setColor(QColor(250, 0, 0));
    } else {
      ofs = -5;
      pen.setColor(QColor(60, 180, 60));
    }
    p.setPen(pen);
    x = (int)((abs(METER_MINDB)-10.0*(double)l1) * xscale);
    if (tick == TICK_DOWN) {
      p.drawLine(4 + x, height() - METER_TICK_WIDTH + 2, 4 + x, height()-16);
      p.drawText(ofs + x, height()-4, QString::number(-10*l1));
    } else {
      p.drawLine(4 + x, 15, 4 + x, METER_TICK_WIDTH-3);
      p.drawText(ofs + x, 12, QString::number(-10*l1));
    }
  }
  pen.setColor(QColor(240, 240, 0));
  p.setPen(pen);  
  if (tick == TICK_DOWN) {
    x = (int)((abs(METER_MINDB)-6.0) * xscale);
    p.drawText(x-1, height()-4, QString::number(-6));
    p.drawLine(4 + x, height() - METER_TICK_WIDTH + 2, 4 + x, height()-16);
    x = (int)((abs(METER_MINDB)-3.0) * xscale);
    p.drawText(x-1, height()-4, QString::number(-3));
    p.drawLine(4 + x, height() - METER_TICK_WIDTH + 2, 4 + x, height()-16);
    p.setPen(QColor(240, 250, 200));
    p.drawText(width()-18, height()-4, "dB");
  } else {
    x = (int)((abs(METER_MINDB)-6.0) * xscale);
    p.drawLine(4 + x, 15, 4 + x, METER_TICK_WIDTH-3);
    p.drawText(x-1, 12, QString::number(-6));
    x = (int)((abs(METER_MINDB)-3.0) * xscale);
    p.drawLine(4 + x, 15, 4 + x, METER_TICK_WIDTH-3);
    p.drawText(x-1, 12, QString::number(-3));
    p.setPen(QColor(240, 250, 200));  
    p.drawText(width()-18, 12, "dB");
  }
  bitBlt(this, 0, 0, &pm);
}

void Meter::updateMeter() {

  int max;

  recdata->newMax = true;
  if (globalMaxResetCount > 20) {
    globalMaxResetCount = 0;
    globalMax = 0;
  }
  if ((max = *maxRef) > globalMax) {
    globalMax = max;
    globalMaxResetCount = 0;
  }
  globalMaxResetCount++;
  repaint(false);
  timer->start(200, true);
}

QSize Meter::sizeHint() const {

  return QSize(METER_MINIMUM_WIDTH, METER_MINIMUM_HEIGHT); 
}

QSizePolicy Meter::sizePolicy() const {

  return QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
}

void Meter::resizeEvent (QResizeEvent* )
{
  repaint(true);
}

void Meter::resetGlobalMax() {

  globalMaxResetCount = 0;
  globalMax = 0;
}

Generated by  Doxygen 1.6.0   Back to index