mirror of
https://github.com/f4exb/sdrangel.git
synced 2025-08-16 04:32:30 -04:00
WDSP receiver: implement dB or S points option for the signal strength meter
This commit is contained in:
parent
4ad190c401
commit
c411e8fbf5
@ -283,6 +283,14 @@ void WDSPRxGUI::on_ritFrequency_valueChanged(int value)
|
|||||||
applySettings();
|
applySettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WDSPRxGUI::on_dbOrS_toggled(bool checked)
|
||||||
|
{
|
||||||
|
ui->dbOrS->setText(checked ? "dB": "S");
|
||||||
|
m_settings.m_dbOrS = checked;
|
||||||
|
m_settings.m_profiles[m_settings.m_profileIndex].m_dbOrS = m_settings.m_dbOrS;
|
||||||
|
ui->channelPowerMeter->setRange(WDSPRxSettings::m_minPowerThresholdDB, 0, !checked);
|
||||||
|
}
|
||||||
|
|
||||||
void WDSPRxGUI::on_audioMute_toggled(bool checked)
|
void WDSPRxGUI::on_audioMute_toggled(bool checked)
|
||||||
{
|
{
|
||||||
m_audioMute = checked;
|
m_audioMute = checked;
|
||||||
@ -333,6 +341,7 @@ void WDSPRxGUI::on_profileIndex_valueChanged(int value)
|
|||||||
m_settings.m_audioBinaural = m_settings.m_profiles[m_settings.m_profileIndex].m_audioBinaural;
|
m_settings.m_audioBinaural = m_settings.m_profiles[m_settings.m_profileIndex].m_audioBinaural;
|
||||||
m_settings.m_audioFlipChannels = m_settings.m_profiles[m_settings.m_profileIndex].m_audioFlipChannels;
|
m_settings.m_audioFlipChannels = m_settings.m_profiles[m_settings.m_profileIndex].m_audioFlipChannels;
|
||||||
m_settings.m_dsb = m_settings.m_profiles[m_settings.m_profileIndex].m_dsb;
|
m_settings.m_dsb = m_settings.m_profiles[m_settings.m_profileIndex].m_dsb;
|
||||||
|
m_settings.m_dbOrS = m_settings.m_profiles[m_settings.m_profileIndex].m_dbOrS;
|
||||||
// AGC setup
|
// AGC setup
|
||||||
m_settings.m_agc = m_settings.m_profiles[m_settings.m_profileIndex].m_agc;
|
m_settings.m_agc = m_settings.m_profiles[m_settings.m_profileIndex].m_agc;
|
||||||
m_settings.m_agcGain = m_settings.m_profiles[m_settings.m_profileIndex].m_agcGain;
|
m_settings.m_agcGain = m_settings.m_profiles[m_settings.m_profileIndex].m_agcGain;
|
||||||
@ -730,8 +739,6 @@ void WDSPRxGUI::applyBandwidths(unsigned int spanLog2, bool force)
|
|||||||
ui->lowCut->blockSignals(false);
|
ui->lowCut->blockSignals(false);
|
||||||
ui->BW->blockSignals(false);
|
ui->BW->blockSignals(false);
|
||||||
|
|
||||||
ui->channelPowerMeter->setRange(WDSPRxSettings::m_minPowerThresholdDB, 0);
|
|
||||||
|
|
||||||
m_settings.m_dsb = dsb;
|
m_settings.m_dsb = dsb;
|
||||||
m_settings.m_profiles[m_settings.m_profileIndex].m_dsb = dsb;
|
m_settings.m_profiles[m_settings.m_profileIndex].m_dsb = dsb;
|
||||||
m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2 = spanLog2;
|
m_settings.m_profiles[m_settings.m_profileIndex].m_spanLog2 = spanLog2;
|
||||||
@ -843,6 +850,9 @@ void WDSPRxGUI::displaySettings()
|
|||||||
ui->BWText->setText(tr("%1k").arg(s));
|
ui->BWText->setText(tr("%1k").arg(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ui->dbOrS->setText(m_settings.m_dbOrS ? "dB": "S");
|
||||||
|
ui->channelPowerMeter->setRange(WDSPRxSettings::m_minPowerThresholdDB, 0, !m_settings.m_dbOrS);
|
||||||
|
|
||||||
ui->spanLog2->blockSignals(false);
|
ui->spanLog2->blockSignals(false);
|
||||||
ui->dsb->blockSignals(false);
|
ui->dsb->blockSignals(false);
|
||||||
ui->BW->blockSignals(false);
|
ui->BW->blockSignals(false);
|
||||||
@ -857,6 +867,7 @@ void WDSPRxGUI::displaySettings()
|
|||||||
ui->volume->setValue(volume);
|
ui->volume->setValue(volume);
|
||||||
ui->volumeText->setText(QString("%1").arg(volume));
|
ui->volumeText->setText(QString("%1").arg(volume));
|
||||||
|
|
||||||
|
|
||||||
updateIndexLabel();
|
updateIndexLabel();
|
||||||
|
|
||||||
getRollupContents()->restoreState(m_rollupState);
|
getRollupContents()->restoreState(m_rollupState);
|
||||||
@ -1364,6 +1375,7 @@ void WDSPRxGUI::makeUIConnections()
|
|||||||
QObject::connect(ui->equalizer, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_equalizer_toggled);
|
QObject::connect(ui->equalizer, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_equalizer_toggled);
|
||||||
QObject::connect(ui->rit, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_rit_toggled);
|
QObject::connect(ui->rit, &ButtonSwitch::toggled, this, &WDSPRxGUI::on_rit_toggled);
|
||||||
QObject::connect(ui->ritFrequency, &QDial::valueChanged, this, &WDSPRxGUI::on_ritFrequency_valueChanged);
|
QObject::connect(ui->ritFrequency, &QDial::valueChanged, this, &WDSPRxGUI::on_ritFrequency_valueChanged);
|
||||||
|
QObject::connect(ui->dbOrS, &QToolButton::toggled, this, &WDSPRxGUI::on_dbOrS_toggled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WDSPRxGUI::updateAbsoluteCenterFrequency()
|
void WDSPRxGUI::updateAbsoluteCenterFrequency()
|
||||||
|
@ -149,6 +149,7 @@ private slots:
|
|||||||
void on_equalizer_toggled(bool checked);
|
void on_equalizer_toggled(bool checked);
|
||||||
void on_rit_toggled(bool checked);
|
void on_rit_toggled(bool checked);
|
||||||
void on_ritFrequency_valueChanged(int value);
|
void on_ritFrequency_valueChanged(int value);
|
||||||
|
void on_dbOrS_toggled(bool checked);
|
||||||
void onWidgetRolled(QWidget* widget, bool rollDown);
|
void onWidgetRolled(QWidget* widget, bool rollDown);
|
||||||
void onMenuDialogCalled(const QPoint& p);
|
void onMenuDialogCalled(const QPoint& p);
|
||||||
void handleInputMessages();
|
void handleInputMessages();
|
||||||
|
@ -331,10 +331,19 @@
|
|||||||
<item>
|
<item>
|
||||||
<layout class="QHBoxLayout" name="channelPowerMeterLayout">
|
<layout class="QHBoxLayout" name="channelPowerMeterLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="channelPowerMeterUnits">
|
<widget class="QToolButton" name="dbOrS">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Toggle between dB and S units</string>
|
||||||
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>dB</string>
|
<string>dB</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="checkable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -46,6 +46,7 @@ void WDSPRxSettings::resetToDefaults()
|
|||||||
m_audioFlipChannels = false;
|
m_audioFlipChannels = false;
|
||||||
m_dsb = false;
|
m_dsb = false;
|
||||||
m_audioMute = false;
|
m_audioMute = false;
|
||||||
|
m_dbOrS = true;
|
||||||
// AGC
|
// AGC
|
||||||
m_agc = false;
|
m_agc = false;
|
||||||
m_agcMode = WDSPRxProfile::AGCMedium;
|
m_agcMode = WDSPRxProfile::AGCMedium;
|
||||||
@ -126,6 +127,7 @@ QByteArray WDSPRxSettings::serialize() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
s.writeU32( 5, m_rgbColor);
|
s.writeU32( 5, m_rgbColor);
|
||||||
|
s.writeBool( 7, m_dbOrS);
|
||||||
s.writeBool( 8, m_audioBinaural);
|
s.writeBool( 8, m_audioBinaural);
|
||||||
s.writeBool( 9, m_audioFlipChannels);
|
s.writeBool( 9, m_audioFlipChannels);
|
||||||
s.writeBool( 10, m_dsb);
|
s.writeBool( 10, m_dsb);
|
||||||
@ -224,6 +226,7 @@ QByteArray WDSPRxSettings::serialize() const
|
|||||||
s.writeBool (105 + 100*i, (int) m_profiles[i].m_audioBinaural);
|
s.writeBool (105 + 100*i, (int) m_profiles[i].m_audioBinaural);
|
||||||
s.writeBool (106 + 100*i, (int) m_profiles[i].m_audioFlipChannels);
|
s.writeBool (106 + 100*i, (int) m_profiles[i].m_audioFlipChannels);
|
||||||
s.writeBool (107 + 100*i, (int) m_profiles[i].m_dsb);
|
s.writeBool (107 + 100*i, (int) m_profiles[i].m_dsb);
|
||||||
|
s.writeBool (108 + 100*i, (int) m_profiles[i].m_dbOrS);
|
||||||
// Filter
|
// Filter
|
||||||
s.writeS32 (100 + 100*i, m_profiles[i].m_spanLog2);
|
s.writeS32 (100 + 100*i, m_profiles[i].m_spanLog2);
|
||||||
s.writeS32 (101 + 100*i, m_profiles[i].m_highCutoff / 100.0);
|
s.writeS32 (101 + 100*i, m_profiles[i].m_highCutoff / 100.0);
|
||||||
@ -332,6 +335,7 @@ bool WDSPRxSettings::deserialize(const QByteArray& data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
d.readU32( 5, &m_rgbColor);
|
d.readU32( 5, &m_rgbColor);
|
||||||
|
d.readBool( 7, &m_dbOrS, true);
|
||||||
d.readBool( 8, &m_audioBinaural, false);
|
d.readBool( 8, &m_audioBinaural, false);
|
||||||
d.readBool( 9, &m_audioFlipChannels, false);
|
d.readBool( 9, &m_audioFlipChannels, false);
|
||||||
d.readBool( 10, &m_dsb, false);
|
d.readBool( 10, &m_dsb, false);
|
||||||
@ -451,6 +455,7 @@ bool WDSPRxSettings::deserialize(const QByteArray& data)
|
|||||||
d.readBool( 105 + 100*i, &m_profiles[i].m_audioBinaural, false);
|
d.readBool( 105 + 100*i, &m_profiles[i].m_audioBinaural, false);
|
||||||
d.readBool( 106 + 100*i, &m_profiles[i].m_audioFlipChannels, false);
|
d.readBool( 106 + 100*i, &m_profiles[i].m_audioFlipChannels, false);
|
||||||
d.readBool( 107 + 100*i, &m_profiles[i].m_dsb, false);
|
d.readBool( 107 + 100*i, &m_profiles[i].m_dsb, false);
|
||||||
|
d.readBool( 108 + 100*i, &m_profiles[i].m_dbOrS, true);
|
||||||
// Filter
|
// Filter
|
||||||
d.readS32 (100 + 100*i, &m_profiles[i].m_spanLog2, 3);
|
d.readS32 (100 + 100*i, &m_profiles[i].m_spanLog2, 3);
|
||||||
d.readS32 (101 + 100*i, &tmp, 30);
|
d.readS32 (101 + 100*i, &tmp, 30);
|
||||||
|
@ -89,6 +89,7 @@ struct WDSPRxProfile
|
|||||||
bool m_audioBinaural;
|
bool m_audioBinaural;
|
||||||
bool m_audioFlipChannels;
|
bool m_audioFlipChannels;
|
||||||
bool m_dsb;
|
bool m_dsb;
|
||||||
|
bool m_dbOrS;
|
||||||
// Filter
|
// Filter
|
||||||
int m_spanLog2;
|
int m_spanLog2;
|
||||||
Real m_highCutoff;
|
Real m_highCutoff;
|
||||||
@ -151,6 +152,7 @@ struct WDSPRxProfile
|
|||||||
m_audioBinaural(false),
|
m_audioBinaural(false),
|
||||||
m_audioFlipChannels(false),
|
m_audioFlipChannels(false),
|
||||||
m_dsb(false),
|
m_dsb(false),
|
||||||
|
m_dbOrS(true),
|
||||||
m_spanLog2(3),
|
m_spanLog2(3),
|
||||||
m_highCutoff(3000),
|
m_highCutoff(3000),
|
||||||
m_lowCutoff(300),
|
m_lowCutoff(300),
|
||||||
@ -214,6 +216,7 @@ struct WDSPRxSettings
|
|||||||
bool m_audioFlipChannels;
|
bool m_audioFlipChannels;
|
||||||
bool m_dsb;
|
bool m_dsb;
|
||||||
bool m_audioMute;
|
bool m_audioMute;
|
||||||
|
bool m_dbOrS;
|
||||||
// AGC
|
// AGC
|
||||||
bool m_agc;
|
bool m_agc;
|
||||||
WDSPRxProfile::WDSPRxAGCMode m_agcMode;
|
WDSPRxProfile::WDSPRxAGCMode m_agcMode;
|
||||||
|
@ -123,7 +123,7 @@ WDSPRxSink::WDSPRxSink() :
|
|||||||
|
|
||||||
m_sAvg = 0.0;
|
m_sAvg = 0.0;
|
||||||
m_sPeak = 0.0;
|
m_sPeak = 0.0;
|
||||||
m_sCount = 1;
|
m_sCount = m_wdspBufSize;
|
||||||
|
|
||||||
m_rxa = WDSP::RXA::create_rxa(
|
m_rxa = WDSP::RXA::create_rxa(
|
||||||
m_wdspSampleRate, // input samplerate
|
m_wdspSampleRate, // input samplerate
|
||||||
|
@ -33,7 +33,8 @@ namespace Unit {
|
|||||||
Time,
|
Time,
|
||||||
TimeHMS,
|
TimeHMS,
|
||||||
Volt,
|
Volt,
|
||||||
Scientific
|
Scientific,
|
||||||
|
SUnits
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -309,9 +309,9 @@ LevelMeterSignalDB::~LevelMeterSignalDB()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelMeterSignalDB::setRange(int min, int max)
|
void LevelMeterSignalDB::setRange(int min, int max, bool sUnits)
|
||||||
{
|
{
|
||||||
m_scaleEngine.setRange(Unit::Decibel, min, max);
|
m_scaleEngine.setRange(sUnits ? Unit::SUnits : Unit::Decibel, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LevelMeterSignalDB::resized()
|
void LevelMeterSignalDB::resized()
|
||||||
|
@ -186,7 +186,8 @@ public:
|
|||||||
virtual ~LevelMeterSignalDB();
|
virtual ~LevelMeterSignalDB();
|
||||||
|
|
||||||
void setColorTheme(ColorTheme colorTheme) { m_colorTheme = colorTheme; }
|
void setColorTheme(ColorTheme colorTheme) { m_colorTheme = colorTheme; }
|
||||||
void setRange(int min, int max);
|
void setRange(int min, int max, bool sUnits = false);
|
||||||
|
void setS(bool s);
|
||||||
|
|
||||||
static const QColor m_avgColor[4];
|
static const QColor m_avgColor[4];
|
||||||
static const QColor m_decayedPeakColor[4];
|
static const QColor m_decayedPeakColor[4];
|
||||||
|
@ -36,20 +36,20 @@ QString ScaleEngine::formatTick(double value, int decimalPlaces)
|
|||||||
{
|
{
|
||||||
if (m_physicalUnit != Unit::TimeHMS)
|
if (m_physicalUnit != Unit::TimeHMS)
|
||||||
{
|
{
|
||||||
if (m_physicalUnit == Unit::Scientific) {
|
if (m_physicalUnit == Unit::Scientific) {
|
||||||
return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'e', m_fixedDecimalPlaces);
|
return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'e', m_fixedDecimalPlaces);
|
||||||
} else {
|
} else {
|
||||||
return QString("%1%2%3")
|
return QString("%1%2%3")
|
||||||
.arg(m_truncated ? "'" : "")
|
.arg(m_truncated ? "'" : "")
|
||||||
.arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces)
|
.arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces)
|
||||||
.arg(m_truncated ? m_multiplierStr : "");
|
.arg(m_truncated ? m_multiplierStr : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_scale < 1.0f) { // sub second prints just as is
|
if (m_scale < 1.0f) { // sub second prints just as is
|
||||||
return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces);
|
return QString("%1").arg(m_makeOpposite ? -value : value, 0, 'f', decimalPlaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString str;
|
QString str;
|
||||||
double actual = value * m_scale; // this is the actual value in seconds
|
double actual = value * m_scale; // this is the actual value in seconds
|
||||||
@ -66,7 +66,7 @@ QString ScaleEngine::formatTick(double value, int decimalPlaces)
|
|||||||
str += QString("%1.").arg(tmp, 0, 'f', 0);
|
str += QString("%1.").arg(tmp, 0, 'f', 0);
|
||||||
actual -= tmp * 86400.0;
|
actual -= tmp * 86400.0;
|
||||||
|
|
||||||
if (actual < 0.0) {
|
if (actual < 0.0) {
|
||||||
actual *= -1.0;
|
actual *= -1.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,6 +197,10 @@ void ScaleEngine::calcScaleFactor()
|
|||||||
m_unitStr = QString("dB");
|
m_unitStr = QString("dB");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Unit::SUnits:
|
||||||
|
m_unitStr = QString("S");
|
||||||
|
break;
|
||||||
|
|
||||||
case Unit::DecibelMilliWatt:
|
case Unit::DecibelMilliWatt:
|
||||||
m_unitStr = QString("dBm");
|
m_unitStr = QString("dBm");
|
||||||
break;
|
break;
|
||||||
@ -223,9 +227,9 @@ void ScaleEngine::calcScaleFactor()
|
|||||||
m_unitStr = QString("s");
|
m_unitStr = QString("s");
|
||||||
m_multiplierStr = "";
|
m_multiplierStr = "";
|
||||||
} else {
|
} else {
|
||||||
m_unitStr = QString("ks");
|
m_unitStr = QString("ks");
|
||||||
m_multiplierStr = "k";
|
m_multiplierStr = "k";
|
||||||
m_scale = 1000.0;
|
m_scale = 1000.0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -393,6 +397,15 @@ void ScaleEngine::forceTwoTicks()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ScaleEngine::reCalc()
|
void ScaleEngine::reCalc()
|
||||||
|
{
|
||||||
|
if (m_physicalUnit == Unit::SUnits) {
|
||||||
|
reCalcS();
|
||||||
|
} else {
|
||||||
|
reCalcStd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleEngine::reCalcStd()
|
||||||
{
|
{
|
||||||
float majorTickSize;
|
float majorTickSize;
|
||||||
double rangeMinScaled;
|
double rangeMinScaled;
|
||||||
@ -430,7 +443,7 @@ void ScaleEngine::reCalc()
|
|||||||
rangeMinScaled = rangeMin / m_scale;
|
rangeMinScaled = rangeMin / m_scale;
|
||||||
rangeMaxScaled = rangeMax / m_scale;
|
rangeMaxScaled = rangeMax / m_scale;
|
||||||
|
|
||||||
if(m_orientation == Qt::Vertical)
|
if (m_orientation == Qt::Vertical)
|
||||||
{
|
{
|
||||||
maxNumMajorTicks = (int)(m_size / (fontMetrics.lineSpacing() * 1.3f));
|
maxNumMajorTicks = (int)(m_size / (fontMetrics.lineSpacing() * 1.3f));
|
||||||
m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces);
|
m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces);
|
||||||
@ -439,10 +452,10 @@ void ScaleEngine::reCalc()
|
|||||||
{
|
{
|
||||||
majorTickSize = (calcTickTextSize((rangeMaxScaled - rangeMinScaled) / 20) + 2) * m_charSize;
|
majorTickSize = (calcTickTextSize((rangeMaxScaled - rangeMinScaled) / 20) + 2) * m_charSize;
|
||||||
|
|
||||||
if(majorTickSize != 0.0) {
|
if (majorTickSize != 0.0) {
|
||||||
maxNumMajorTicks = (int)(m_size / majorTickSize);
|
maxNumMajorTicks = (int)(m_size / majorTickSize);
|
||||||
} else {
|
} else {
|
||||||
maxNumMajorTicks = 20;
|
maxNumMajorTicks = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces);
|
m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces);
|
||||||
@ -450,29 +463,33 @@ void ScaleEngine::reCalc()
|
|||||||
|
|
||||||
numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance);
|
numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance);
|
||||||
|
|
||||||
if(numMajorTicks == 0) {
|
if (numMajorTicks == 0)
|
||||||
|
{
|
||||||
forceTwoTicks();
|
forceTwoTicks();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(maxNumMajorTicks > 0)
|
if(maxNumMajorTicks > 0)
|
||||||
m_numMinorTicks = (int)(m_size / (maxNumMajorTicks * fontMetrics.height()));
|
m_numMinorTicks = (int)(m_size / (maxNumMajorTicks * fontMetrics.height()));
|
||||||
else m_numMinorTicks = 0;
|
else
|
||||||
if(m_numMinorTicks < 1)
|
m_numMinorTicks = 0;
|
||||||
|
|
||||||
|
if (m_numMinorTicks < 1)
|
||||||
m_numMinorTicks = 0;
|
m_numMinorTicks = 0;
|
||||||
else if(m_numMinorTicks < 2)
|
else if (m_numMinorTicks < 2)
|
||||||
m_numMinorTicks = 1;
|
m_numMinorTicks = 1;
|
||||||
else if(m_numMinorTicks < 5)
|
else if (m_numMinorTicks < 5)
|
||||||
m_numMinorTicks = 2;
|
m_numMinorTicks = 2;
|
||||||
else if(m_numMinorTicks < 10)
|
else if (m_numMinorTicks < 10)
|
||||||
m_numMinorTicks = 5;
|
m_numMinorTicks = 5;
|
||||||
else m_numMinorTicks = 10;
|
else
|
||||||
|
m_numMinorTicks = 10;
|
||||||
|
|
||||||
m_firstMajorTickValue = floor(rangeMinScaled / m_majorTickValueDistance) * m_majorTickValueDistance;
|
m_firstMajorTickValue = floor(rangeMinScaled / m_majorTickValueDistance) * m_majorTickValueDistance;
|
||||||
|
|
||||||
skip = 0;
|
skip = 0;
|
||||||
|
|
||||||
if(rangeMinScaled == rangeMaxScaled)
|
if (rangeMinScaled == rangeMaxScaled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
@ -490,25 +507,33 @@ void ScaleEngine::reCalc()
|
|||||||
for (j = 1; j < m_numMinorTicks; j++)
|
for (j = 1; j < m_numMinorTicks; j++)
|
||||||
{
|
{
|
||||||
value2 = value + minorTickValue(j);
|
value2 = value + minorTickValue(j);
|
||||||
if(value2 < rangeMinScaled)
|
|
||||||
|
if (value2 < rangeMinScaled)
|
||||||
continue;
|
continue;
|
||||||
if(value2 > rangeMaxScaled)
|
|
||||||
|
if (value2 > rangeMaxScaled)
|
||||||
break;
|
break;
|
||||||
pos = getPosFromValueTrunc((value + minorTickValue(j)) * m_scale);
|
|
||||||
if((pos >= 0) && (pos < m_size)) {
|
pos = getPosFromValueTrunc((value + minorTickValue(j)) * m_scale);
|
||||||
|
|
||||||
|
if ((pos >= 0) && (pos < m_size))
|
||||||
|
{
|
||||||
tick.pos = pos;
|
tick.pos = pos;
|
||||||
tick.major = false;
|
tick.major = false;
|
||||||
tick.textPos = -1;
|
tick.textPos = -1;
|
||||||
tick.textSize = -1;
|
tick.textSize = -1;
|
||||||
tick.text.clear();
|
tick.text.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_tickList.append(tick);
|
m_tickList.append(tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = getPosFromValueTrunc(value * m_scale);
|
pos = getPosFromValueTrunc(value * m_scale);
|
||||||
if(pos < 0.0)
|
|
||||||
|
if (pos < 0.0)
|
||||||
continue;
|
continue;
|
||||||
if(pos >= m_size)
|
|
||||||
|
if (pos >= m_size)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
tick.pos = pos;
|
tick.pos = pos;
|
||||||
@ -517,49 +542,295 @@ void ScaleEngine::reCalc()
|
|||||||
tick.textSize = -1;
|
tick.textSize = -1;
|
||||||
tick.text.clear();
|
tick.text.clear();
|
||||||
|
|
||||||
if(step % (skip + 1) != 0) {
|
if (step % (skip + 1) != 0)
|
||||||
|
{
|
||||||
m_tickList.append(tick);
|
m_tickList.append(tick);
|
||||||
step++;
|
step++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
step++;
|
|
||||||
|
|
||||||
|
step++;
|
||||||
str = formatTick(value, m_decimalPlaces);
|
str = formatTick(value, m_decimalPlaces);
|
||||||
tick.text = str;
|
tick.text = str;
|
||||||
tick.textSize = fontMetrics.boundingRect(tick.text).width();
|
tick.textSize = fontMetrics.boundingRect(tick.text).width();
|
||||||
if(m_orientation == Qt::Vertical) {
|
|
||||||
|
if (m_orientation == Qt::Vertical)
|
||||||
|
{
|
||||||
tick.textPos = pos - fontMetrics.ascent() / 2;
|
tick.textPos = pos - fontMetrics.ascent() / 2;
|
||||||
endPos = tick.textPos + fontMetrics.ascent();
|
endPos = tick.textPos + fontMetrics.ascent();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
tick.textPos = pos - fontMetrics.boundingRect(tick.text).width() / 2;
|
tick.textPos = pos - fontMetrics.boundingRect(tick.text).width() / 2;
|
||||||
endPos = tick.textPos + tick.textSize;
|
endPos = tick.textPos + tick.textSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastEndPos >= tick.textPos) {
|
if (lastEndPos >= tick.textPos)
|
||||||
|
{
|
||||||
done = false;
|
done = false;
|
||||||
break;
|
break;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
lastEndPos = endPos;
|
lastEndPos = endPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_tickList.append(tick);
|
m_tickList.append(tick);
|
||||||
}
|
}
|
||||||
if(done)
|
|
||||||
|
if (done)
|
||||||
break;
|
break;
|
||||||
skip++;
|
|
||||||
|
skip++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we have at least two major ticks with numbers
|
// make sure we have at least two major ticks with numbers
|
||||||
numMajorTicks = 0;
|
numMajorTicks = 0;
|
||||||
for(i = 0; i < m_tickList.count(); i++) {
|
|
||||||
|
for (i = 0; i < m_tickList.count(); i++)
|
||||||
|
{
|
||||||
tick = m_tickList.at(i);
|
tick = m_tickList.at(i);
|
||||||
if(tick.major)
|
|
||||||
|
if (tick.major)
|
||||||
numMajorTicks++;
|
numMajorTicks++;
|
||||||
}
|
}
|
||||||
if(numMajorTicks < 2)
|
|
||||||
|
if (numMajorTicks < 2)
|
||||||
forceTwoTicks();
|
forceTwoTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScaleEngine::reCalcS()
|
||||||
|
{
|
||||||
|
float majorTickSize;
|
||||||
|
double rangeMinScaled;
|
||||||
|
double rangeMaxScaled;
|
||||||
|
int maxNumMajorTicks;
|
||||||
|
int numMajorTicks;
|
||||||
|
Tick tick;
|
||||||
|
QString str;
|
||||||
|
QFontMetricsF fontMetrics(m_font);
|
||||||
|
|
||||||
|
if (!m_recalc) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateTruncation();
|
||||||
|
|
||||||
|
m_recalc = false;
|
||||||
|
m_tickList.clear();
|
||||||
|
|
||||||
|
calcScaleFactor();
|
||||||
|
|
||||||
|
double rangeMin = m_truncated ? m_rangeMin - m_truncationValue : m_rangeMin;
|
||||||
|
double rangeMax = m_truncated ? m_rangeMax - m_truncationValue : m_rangeMax;
|
||||||
|
|
||||||
|
rangeMinScaled = rangeMin / m_scale;
|
||||||
|
rangeMaxScaled = rangeMax / m_scale;
|
||||||
|
|
||||||
|
if (m_orientation == Qt::Vertical)
|
||||||
|
{
|
||||||
|
maxNumMajorTicks = (int)(m_size / (fontMetrics.lineSpacing() * 1.3f));
|
||||||
|
m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
majorTickSize = (calcTickTextSize((rangeMaxScaled - rangeMinScaled) / 20) + 2) * m_charSize;
|
||||||
|
|
||||||
|
if (majorTickSize != 0.0) {
|
||||||
|
maxNumMajorTicks = (int)(m_size / majorTickSize);
|
||||||
|
} else {
|
||||||
|
maxNumMajorTicks = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_majorTickValueDistance = calcMajorTickUnits((rangeMaxScaled - rangeMinScaled) / maxNumMajorTicks, &m_decimalPlaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
numMajorTicks = (int)((rangeMaxScaled - rangeMinScaled) / m_majorTickValueDistance);
|
||||||
|
|
||||||
|
if (numMajorTicks == 0)
|
||||||
|
{
|
||||||
|
forceTwoTicks();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maxNumMajorTicks > 0)
|
||||||
|
m_numMinorTicks = (int)(m_size / (maxNumMajorTicks * fontMetrics.height()));
|
||||||
|
else
|
||||||
|
m_numMinorTicks = 0;
|
||||||
|
|
||||||
|
if (m_numMinorTicks < 1)
|
||||||
|
m_numMinorTicks = 0;
|
||||||
|
else if (m_numMinorTicks < 2)
|
||||||
|
m_numMinorTicks = 1;
|
||||||
|
else if (m_numMinorTicks < 5)
|
||||||
|
m_numMinorTicks = 2;
|
||||||
|
else if (m_numMinorTicks < 10)
|
||||||
|
m_numMinorTicks = 5;
|
||||||
|
else
|
||||||
|
m_numMinorTicks = 10;
|
||||||
|
|
||||||
|
m_firstMajorTickValue = floor(rangeMinScaled / m_majorTickValueDistance) * m_majorTickValueDistance;
|
||||||
|
// skip = 0;
|
||||||
|
|
||||||
|
if (rangeMinScaled == rangeMaxScaled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (rangeMinScaled > -73.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rangeMaxScaled < -73.0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// qDebug("ScaleEngine::reCalcS: m_numMinorTicks: %d maxNumMajorTicks: %d m_firstMajorTickValue: %le rangeMinScaled: %le rangeMaxScaled: %le",
|
||||||
|
// m_numMinorTicks, maxNumMajorTicks, m_firstMajorTickValue, rangeMinScaled, rangeMaxScaled);
|
||||||
|
|
||||||
|
std::vector<double> sVals;
|
||||||
|
std::vector<double> dbVals;
|
||||||
|
|
||||||
|
int nbSVals = ((int) (-73.0 - rangeMinScaled)) / 6;
|
||||||
|
double sFloor = -73.0 - (double) nbSVals*6;
|
||||||
|
|
||||||
|
for (int i = 0; i < nbSVals; i++) {
|
||||||
|
sVals.push_back(sFloor + 6*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
sVals.push_back(-73.0);
|
||||||
|
|
||||||
|
int nbDbVals = ((int) (rangeMaxScaled - -73.0)) / 10;
|
||||||
|
|
||||||
|
for (int i = 1; i < nbDbVals; i++) {
|
||||||
|
dbVals.push_back(-73.0 + 10*i);
|
||||||
|
}
|
||||||
|
|
||||||
|
truncS(maxNumMajorTicks, sVals, dbVals);
|
||||||
|
|
||||||
|
double minTickShiftS = 0.0;
|
||||||
|
double minTickShiftDb = 0.0;
|
||||||
|
m_tickList.clear();
|
||||||
|
|
||||||
|
if ((m_numMinorTicks > 1) && (sVals.size() > 1)) {
|
||||||
|
minTickShiftS = (sVals[1] - sVals[0]) / m_numMinorTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_numMinorTicks > 1) && (dbVals.size() > 1)) {
|
||||||
|
minTickShiftDb = (dbVals[1] - dbVals[0]) / m_numMinorTicks;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto sVal : sVals)
|
||||||
|
{
|
||||||
|
int s = (int) (sVal + 6*9 - -73.0) / 6;
|
||||||
|
// qDebug("ScaleEngine::reCalcS: S : %le (%d)", sVal, s);
|
||||||
|
tick.pos = getPosFromValue(sVal);
|
||||||
|
tick.major = true;
|
||||||
|
tick.textPos = -1;
|
||||||
|
tick.textSize = -1;
|
||||||
|
tick.text.clear();
|
||||||
|
tick.text = QString("%1").arg(s);
|
||||||
|
adjustText(fontMetrics, tick);
|
||||||
|
m_tickList.append(tick);
|
||||||
|
|
||||||
|
if (s == 9)
|
||||||
|
{
|
||||||
|
if (dbVals.size() != 0)
|
||||||
|
{
|
||||||
|
tick.pos = getPosFromValue(sVal + minTickShiftDb);
|
||||||
|
tick.major = false;
|
||||||
|
tick.textPos = -1;
|
||||||
|
tick.textSize = -1;
|
||||||
|
tick.text.clear();
|
||||||
|
m_tickList.append(tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 1; i < m_numMinorTicks; i++)
|
||||||
|
{
|
||||||
|
tick.pos = getPosFromValue(sVal + i*(minTickShiftS / (m_numMinorTicks - 1)));
|
||||||
|
tick.major = false;
|
||||||
|
tick.textPos = -1;
|
||||||
|
tick.textSize = -1;
|
||||||
|
tick.text.clear();
|
||||||
|
m_tickList.append(tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto dbVal : dbVals)
|
||||||
|
{
|
||||||
|
int db = (int) (dbVal - -73.0);
|
||||||
|
// qDebug("ScaleEngine::reCalcS: dB: %le (+%d)", dbVal, db);
|
||||||
|
tick.pos = getPosFromValue(dbVal);
|
||||||
|
tick.major = true;
|
||||||
|
tick.textPos = -1;
|
||||||
|
tick.textSize = -1;
|
||||||
|
tick.text.clear();
|
||||||
|
tick.text = QString("+%1").arg(db);
|
||||||
|
adjustText(fontMetrics, tick);
|
||||||
|
m_tickList.append(tick);
|
||||||
|
|
||||||
|
for (int i = 1; i < m_numMinorTicks; i++)
|
||||||
|
{
|
||||||
|
tick.pos = getPosFromValue(dbVal + i*(minTickShiftDb / (m_numMinorTicks - 1)));
|
||||||
|
tick.major = false;
|
||||||
|
tick.textPos = -1;
|
||||||
|
tick.textSize = -1;
|
||||||
|
tick.text.clear();
|
||||||
|
m_tickList.append(tick);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleEngine::truncS(int nbMaxTicks, std::vector<double>& sVals, std::vector<double>& dbVals)
|
||||||
|
{
|
||||||
|
int nbAvailDb = nbMaxTicks - (int) sVals.size();
|
||||||
|
|
||||||
|
if (nbAvailDb <= 0)
|
||||||
|
{
|
||||||
|
dbVals.clear();
|
||||||
|
|
||||||
|
if (nbMaxTicks == (int) sVals.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> newSVals;
|
||||||
|
int n = sVals.size() / nbMaxTicks;
|
||||||
|
|
||||||
|
for (int i = 0; n*i < (int) sVals.size(); i++) {
|
||||||
|
newSVals.push_back(sVals[sVals.size() -1 -n*i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
sVals = newSVals;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbAvailDb < (int) dbVals.size())
|
||||||
|
{
|
||||||
|
std::vector<double> newDbVals;
|
||||||
|
int n = dbVals.size() / nbAvailDb;
|
||||||
|
|
||||||
|
for (int i = 0; n*i < (int) dbVals.size(); i++) {
|
||||||
|
newDbVals.push_back(dbVals[n*i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
dbVals = newDbVals;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScaleEngine::adjustText(const QFontMetricsF& fontMetrics, Tick& tick)
|
||||||
|
{
|
||||||
|
tick.textSize = fontMetrics.boundingRect(tick.text).width();
|
||||||
|
|
||||||
|
if (m_orientation == Qt::Vertical)
|
||||||
|
{
|
||||||
|
tick.textPos = tick.pos - fontMetrics.ascent() / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tick.textPos = tick.pos - fontMetrics.boundingRect(tick.text).width() / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double ScaleEngine::majorTickValue(int tick)
|
double ScaleEngine::majorTickValue(int tick)
|
||||||
{
|
{
|
||||||
return m_firstMajorTickValue + (tick * m_majorTickValueDistance);
|
return m_firstMajorTickValue + (tick * m_majorTickValueDistance);
|
||||||
@ -569,6 +840,7 @@ double ScaleEngine::minorTickValue(int tick)
|
|||||||
{
|
{
|
||||||
if(m_numMinorTicks < 1)
|
if(m_numMinorTicks < 1)
|
||||||
return 0.0;
|
return 0.0;
|
||||||
|
|
||||||
return (m_majorTickValueDistance * tick) / m_numMinorTicks;
|
return (m_majorTickValueDistance * tick) / m_numMinorTicks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,6 +94,10 @@ private:
|
|||||||
int calcTickTextSize(double distance);
|
int calcTickTextSize(double distance);
|
||||||
void forceTwoTicks();
|
void forceTwoTicks();
|
||||||
void reCalc();
|
void reCalc();
|
||||||
|
void reCalcStd();
|
||||||
|
void reCalcS();
|
||||||
|
void truncS(int nbMaxTicks, std::vector<double>& sVals, std::vector<double>& dbVals);
|
||||||
|
void adjustText(const QFontMetricsF& fontMetrics, Tick& tick);
|
||||||
void updateTruncation();
|
void updateTruncation();
|
||||||
|
|
||||||
inline int order(double value) {
|
inline int order(double value) {
|
||||||
|
@ -28,8 +28,6 @@ warren@wpratt.com
|
|||||||
#ifndef wdsp_channel_h
|
#ifndef wdsp_channel_h
|
||||||
#define wdsp_channel_h
|
#define wdsp_channel_h
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
|
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
|
||||||
#include "export.h"
|
#include "export.h"
|
||||||
@ -55,7 +53,7 @@ public:
|
|||||||
int bfo; // 'block_for_output', block fexchange until output is available
|
int bfo; // 'block_for_output', block fexchange until output is available
|
||||||
volatile long flushflag;
|
volatile long flushflag;
|
||||||
QThread channelThread;
|
QThread channelThread;
|
||||||
std::atomic<long> upslew;
|
long upslew;
|
||||||
// struct //io buffers
|
// struct //io buffers
|
||||||
// {
|
// {
|
||||||
// IOB pc, pd, pe, pf; // copies for console calls, dsp, exchange, and flush thread
|
// IOB pc, pd, pe, pf; // copies for console calls, dsp, exchange, and flush thread
|
||||||
|
@ -81,10 +81,11 @@ void METER::flush_meter (METER *a)
|
|||||||
{
|
{
|
||||||
a->avg = 0.0;
|
a->avg = 0.0;
|
||||||
a->peak = 0.0;
|
a->peak = 0.0;
|
||||||
a->result[a->enum_av] = -400.0;
|
a->result[a->enum_av] = -100.0;
|
||||||
a->result[a->enum_pk] = -400.0;
|
a->result[a->enum_pk] = -100.0;
|
||||||
|
|
||||||
if ((a->pgain != 0) && (a->enum_gain >= 0))
|
if ((a->pgain != 0) && (a->enum_gain >= 0))
|
||||||
a->result[a->enum_gain] = -400.0;
|
a->result[a->enum_gain] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void METER::xmeter (METER *a)
|
void METER::xmeter (METER *a)
|
||||||
@ -107,7 +108,9 @@ void METER::xmeter (METER *a)
|
|||||||
smag = a->buff[2 * i + 0] * a->buff[2 * i + 0] + a->buff[2 * i + 1] * a->buff[2 * i + 1];
|
smag = a->buff[2 * i + 0] * a->buff[2 * i + 0] + a->buff[2 * i + 1] * a->buff[2 * i + 1];
|
||||||
a->avg = a->avg * a->mult_average + (1.0 - a->mult_average) * smag;
|
a->avg = a->avg * a->mult_average + (1.0 - a->mult_average) * smag;
|
||||||
a->peak *= a->mult_peak;
|
a->peak *= a->mult_peak;
|
||||||
if (smag > np) np = smag;
|
|
||||||
|
if (smag > np)
|
||||||
|
np = smag;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (np > a->peak)
|
if (np > a->peak)
|
||||||
@ -121,9 +124,12 @@ void METER::xmeter (METER *a)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (a->enum_av >= 0) a->result[a->enum_av] = -400.0;
|
if (a->enum_av >= 0)
|
||||||
if (a->enum_pk >= 0) a->result[a->enum_pk] = -400.0;
|
a->result[a->enum_av] = -100.0;
|
||||||
if (a->enum_gain >= 0) a->result[a->enum_gain] = 0.0;
|
if (a->enum_pk >= 0)
|
||||||
|
a->result[a->enum_pk] = -100.0;
|
||||||
|
if (a->enum_gain >= 0)
|
||||||
|
a->result[a->enum_gain] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,8 +158,7 @@ void METER::setSize_meter (METER *a, int size)
|
|||||||
|
|
||||||
double METER::GetMeter (RXA& rxa, int mt)
|
double METER::GetMeter (RXA& rxa, int mt)
|
||||||
{
|
{
|
||||||
double val;
|
double val = rxa.meter[mt];
|
||||||
val = rxa.meter[mt];
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +170,7 @@ double METER::GetMeter (RXA& rxa, int mt)
|
|||||||
|
|
||||||
double METER::GetMeter (TXA& txa, int mt)
|
double METER::GetMeter (TXA& txa, int mt)
|
||||||
{
|
{
|
||||||
double val;
|
double val = txa.meter[mt];
|
||||||
val = txa.meter[mt];
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user