📄 ampfrm.cpp
字号:
#include "ampfrm.h"
#include <qwt_knob.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qfont.h>
#include <qpen.h>
#include <qevent.h>
#include <qwt_thermo.h>
#include <qwt_round_scale_draw.h>
#include <qwt_math.h>
class Knob: public QWidget
{
public:
Knob(const QString &title, double min, double max, QWidget *parent):
QWidget(parent)
{
d_knob = new QwtKnob(this);
d_knob->setRange(min, max, 0,1);
d_knob->setScaleMaxMajor(10);
d_knob->setKnobWidth(50);
d_label = new QLabel(title, this);
d_label->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
setSizePolicy(QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding);
}
virtual QSize sizeHint() const
{
QSize sz1 = d_knob->sizeHint();
QSize sz2 = d_label->sizeHint();
const int w = qwtMax(sz1.width(), sz2.width());
const int h = sz1.height() + sz2.height();
int off = d_knob->scaleDraw()->extent(QPen(), d_knob->font());
off -= 10; // spacing
return QSize(w, h - off);
}
double value() const
{
return d_knob->value();
}
protected:
virtual void resizeEvent(QResizeEvent *e)
{
const QSize sz = e->size();
int h = d_label->sizeHint().height();
d_label->setGeometry(0, sz.height() - h,
sz.width(), h);
h = d_knob->sizeHint().height();
int off = d_knob->scaleDraw()->extent(QPen(), d_knob->font());
off -= 10; // spacing
d_knob->setGeometry(0, d_label->pos().y() - h + off,
sz.width(), h);
}
private:
QwtKnob *d_knob;
QLabel *d_label;
};
class Thermo: public QWidget
{
public:
Thermo(const QString &title, QWidget *parent):
QWidget(parent)
{
d_thermo = new QwtThermo(this);
d_thermo->setPipeWidth(6);
d_thermo->setRange(-40,10);
d_thermo->setFillColor(Qt::green);
d_thermo->setAlarmColor(Qt::red);
d_thermo->setAlarmLevel(0.0);
d_thermo->setAlarmEnabled(true);
QLabel *label = new QLabel(title, this);
label->setAlignment(Qt::AlignTop | Qt::AlignLeft);
QVBoxLayout *layout = new QVBoxLayout(this);
layout->setMargin(0);
layout->setSpacing(0);
layout->addWidget(d_thermo, 10);
layout->addWidget(label);
}
void setValue(double value)
{
d_thermo->setValue(value);
}
private:
QwtThermo *d_thermo;
};
AmpFrame::AmpFrame(QWidget *p):
QFrame(p)
{
d_knbVolume = new Knob("Volume", 0.0, 10.0, this);
d_knbBalance = new Knob("Balance", -10.0, 10.0, this);
d_knbTreble = new Knob("Treble", -10.0, 10.0, this);
d_knbBass = new Knob("Bass", -10.0, 10.0, this);
d_thmLeft = new Thermo("Left [dB]", this);
d_thmRight = new Thermo("Right [dB]", this);
QHBoxLayout *layout = new QHBoxLayout(this);
layout->setSpacing(0);
layout->setMargin(10);
layout->addWidget(d_knbVolume);
layout->addWidget(d_knbBalance);
layout->addWidget(d_knbTreble);
layout->addWidget(d_knbBass);
layout->addSpacing(20);
layout->addStretch(10);
layout->addWidget(d_thmLeft);
layout->addSpacing(10);
layout->addWidget(d_thmRight);
(void)startTimer(50);
}
void AmpFrame::timerEvent(QTimerEvent *)
{
static double phs = 0;
//
// This amplifier generates its own input signal...
//
const double sig_bass = (1.0 + 0.1 * d_knbBass->value())
* sin(13.0 * phs);
const double sig_mid_l = sin(17.0 * phs);
const double sig_mid_r = cos(17.5 * phs);
const double sig_trbl_l = 0.5 * (1.0 + 0.1 * d_knbTreble->value())
* sin(35.0 * phs);
const double sig_trbl_r = 0.5 * (1.0 + 0.1 * d_knbTreble->value())
* sin(34.0 * phs);
double sig_l = 0.05 * d_master * d_knbVolume->value()
* qwtSqr(sig_bass + sig_mid_l + sig_trbl_l);
double sig_r = 0.05 * d_master * d_knbVolume->value()
* qwtSqr(sig_bass + sig_mid_r + sig_trbl_r);
double balance = 0.1 * d_knbBalance->value();
if (balance > 0)
sig_l *= (1.0 - balance);
else
sig_r *= (1.0 + balance);
if (sig_l > 0.01)
sig_l = 20.0 * log10(sig_l);
else
sig_l = -40.0;
if (sig_r > 0.01)
sig_r = 20.0 * log10(sig_r);
else
sig_r = - 40.0;
d_thmLeft->setValue(sig_l);
d_thmRight->setValue(sig_r);
phs += M_PI / 100;
if (phs > M_PI)
phs = 0;
}
void AmpFrame::setMaster(double v)
{
d_master = v;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -