mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
Upgrade to QWT 6.0.1, but still uses a locally patched copy since support for 8 axes has not been included, despite it being a relatively simple patch. Fixes #634. Fixes #567.
202 lines
5.1 KiB
C++
202 lines
5.1 KiB
C++
#include "ampfrm.h"
|
|
#include <qwt_knob.h>
|
|
#include <qwt_thermo.h>
|
|
#include <qwt_round_scale_draw.h>
|
|
#include <qwt_math.h>
|
|
#include <qlayout.h>
|
|
#include <qlabel.h>
|
|
#include <qfont.h>
|
|
#include <qpen.h>
|
|
#include <qevent.h>
|
|
|
|
#if QT_VERSION < 0x040600
|
|
#define qFastSin(x) ::sin(x)
|
|
#define qFastCos(x) ::cos(x)
|
|
#endif
|
|
|
|
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->setKnobStyle(QwtKnob::Raised);
|
|
d_knob->setKnobWidth(50);
|
|
d_knob->setBorderWidth(2);
|
|
d_knob->setMarkerStyle(QwtKnob::Notch);
|
|
d_knob->setMarkerSize( 8 );
|
|
|
|
d_knob->scaleDraw()->setTickLength( QwtScaleDiv::MinorTick, 4 );
|
|
d_knob->scaleDraw()->setTickLength( QwtScaleDiv::MediumTick, 4 );
|
|
d_knob->scaleDraw()->setTickLength( QwtScaleDiv::MajorTick, 6 );
|
|
|
|
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 = qMax(sz1.width(), sz2.width());
|
|
const int h = sz1.height() + sz2.height();
|
|
|
|
int off = d_knob->scaleDraw()->extent(d_knob->font());
|
|
off -= 10; // spacing
|
|
|
|
return QSize(w, h - off);
|
|
}
|
|
|
|
void setValue( double value )
|
|
{
|
|
d_knob->setValue( value );
|
|
}
|
|
|
|
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(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->setFillBrush( Qt::green );
|
|
d_thermo->setAlarmBrush( 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);
|
|
|
|
d_knbVolume->setValue( 7.0 );
|
|
(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())
|
|
* qFastSin(13.0 * phs);
|
|
const double sig_mid_l = qFastSin(17.0 * phs);
|
|
const double sig_mid_r = qFastCos(17.5 * phs);
|
|
const double sig_trbl_l = 0.5 * (1.0 + 0.1 * d_knbTreble->value())
|
|
* qFastSin(35.0 * phs);
|
|
const double sig_trbl_r = 0.5 * (1.0 + 0.1 * d_knbTreble->value())
|
|
* qFastSin(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;
|
|
}
|