SSB Mod: added audio compressor preamp gain and threshold controls

pull/743/head
f4exb 2020-11-25 14:19:21 +01:00
rodzic d1e0f8d865
commit 6de27fc3d0
18 zmienionych plików z 284 dodań i 14 usunięć

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 94 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 99 KiB

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Przed

Szerokość:  |  Wysokość:  |  Rozmiar: 6.3 KiB

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 10 KiB

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -113,26 +113,44 @@ Use this button to toggle audio compression on or off.
<h3>13: Input source control</h3> <h3>13: Input source control</h3>
![Modulator input source control GUI](../../../doc/img/ModControls.png) ![Modulator input source control GUI](../../../doc/img/SSBModulator_plugin_cmp.png)
<h4>13.1: Tone input select</h4> <h4>13.1: Audio compressor</h4>
Activate/deactivate it for file and audio input only.
<h4>13.2: Audio compressor input gain</h4>
Gain in dB before compression
<h4>13.3: Audio compressor threshold</h4>
Threshold in dB above which compression applies a.k.a. "knee" point. The lower the value the harder is the compression and consequently higher the distorsion.
<h4>13.4: Tone input select</h4>
Switches to the tone input. You must switch it off to make other inputs available. Switches to the tone input. You must switch it off to make other inputs available.
<h4>13.2: Morse keyer input select</h4> <h4>13.5: Morse keyer input select</h4>
Switches to the Morse keyer input. You must switch it off to make other inputs available. Switches to the Morse keyer input. You must switch it off to make other inputs available.
<h4>13.3: Tone frequency (kHz)</h4> <h4>13.6: Tone frequency (kHz)</h4>
Adjusts the tone frequency from 0.1 to 2.5 kHz in 0.01 kHz steps Adjusts the tone frequency from 0.1 to 2.5 kHz in 0.01 kHz steps
<h4>13.4: Audio input select and select audio input device</h4> <h4>13.7: Audio input select and select audio input device</h4>
Left click to switch to the audio input. You must switch it off to make other inputs available. Left click to switch to the audio input. You must switch it off to make other inputs available.
Right click to select audio input device. See [audio management documentation](../../../sdrgui/audio.md) for details. Right click to select audio input device. See [audio management documentation](../../../sdrgui/audio.md) for details.
<h4>13.8: Audio feedback</h4>
Left click to activate audio feedback.
Right click to select audio output device for audio feedback. See [audio management documentation](../../../sdrgui/audio.md) for details.
<h3>14: CW (Morse) text</h3> <h3>14: CW (Morse) text</h3>
Enter the text to be keyed when Morse input is active and in text mode Enter the text to be keyed when Morse input is active and in text mode

Wyświetl plik

@ -262,6 +262,12 @@ void SSBMod::applySettings(const SSBModSettings& settings, bool force)
if ((settings.m_agc != m_settings.m_agc) || force) { if ((settings.m_agc != m_settings.m_agc) || force) {
reverseAPIKeys.append("agc"); reverseAPIKeys.append("agc");
} }
if ((settings.m_cmpPreGainDB != m_settings.m_cmpPreGainDB) || force) {
reverseAPIKeys.append("cmpPreGainDB");
}
if ((settings.m_cmpThresholdDB != m_settings.m_cmpThresholdDB) || force) {
reverseAPIKeys.append("cmpThresholdDB");
}
if ((settings.m_rgbColor != m_settings.m_rgbColor) || force) { if ((settings.m_rgbColor != m_settings.m_rgbColor) || force) {
reverseAPIKeys.append("rgbColor"); reverseAPIKeys.append("rgbColor");
} }
@ -449,6 +455,12 @@ void SSBMod::webapiUpdateChannelSettings(
if (channelSettingsKeys.contains("agc")) { if (channelSettingsKeys.contains("agc")) {
settings.m_agc = response.getSsbModSettings()->getAgc() != 0; settings.m_agc = response.getSsbModSettings()->getAgc() != 0;
} }
if (channelSettingsKeys.contains("cmpPreGainDB")) {
settings.m_cmpPreGainDB = response.getSsbModSettings()->getCmpPreGainDb();
}
if (channelSettingsKeys.contains("cmpThresholdDB")) {
settings.m_cmpThresholdDB = response.getSsbModSettings()->getCmpThresholdDb();
}
if (channelSettingsKeys.contains("rgbColor")) { if (channelSettingsKeys.contains("rgbColor")) {
settings.m_rgbColor = response.getSsbModSettings()->getRgbColor(); settings.m_rgbColor = response.getSsbModSettings()->getRgbColor();
} }
@ -507,6 +519,8 @@ void SSBMod::webapiFormatChannelSettings(SWGSDRangel::SWGChannelSettings& respon
response.getSsbModSettings()->setAudioMute(settings.m_audioMute ? 1 : 0); response.getSsbModSettings()->setAudioMute(settings.m_audioMute ? 1 : 0);
response.getSsbModSettings()->setPlayLoop(settings.m_playLoop ? 1 : 0); response.getSsbModSettings()->setPlayLoop(settings.m_playLoop ? 1 : 0);
response.getSsbModSettings()->setAgc(settings.m_agc ? 1 : 0); response.getSsbModSettings()->setAgc(settings.m_agc ? 1 : 0);
response.getSsbModSettings()->setCmpPreGainDb(settings.m_cmpPreGainDB);
response.getSsbModSettings()->setCmpThresholdDb(settings.m_cmpThresholdDB);
response.getSsbModSettings()->setRgbColor(settings.m_rgbColor); response.getSsbModSettings()->setRgbColor(settings.m_rgbColor);
if (response.getSsbModSettings()->getTitle()) { if (response.getSsbModSettings()->getTitle()) {
@ -687,6 +701,12 @@ void SSBMod::webapiFormatChannelSettings(
if (channelSettingsKeys.contains("agc") || force) { if (channelSettingsKeys.contains("agc") || force) {
swgSSBModSettings->setAgc(settings.m_agc ? 1 : 0); swgSSBModSettings->setAgc(settings.m_agc ? 1 : 0);
} }
if (channelSettingsKeys.contains("cmpPreGainDB") || force) {
swgSSBModSettings->setCmpPreGainDb(settings.m_cmpPreGainDB);
}
if (channelSettingsKeys.contains("cmpThresholdDB") || force) {
swgSSBModSettings->setCmpThresholdDb(settings.m_cmpThresholdDB);
}
if (channelSettingsKeys.contains("rgbColor") || force) { if (channelSettingsKeys.contains("rgbColor") || force) {
swgSSBModSettings->setRgbColor(settings.m_rgbColor); swgSSBModSettings->setRgbColor(settings.m_rgbColor);
} }

Wyświetl plik

@ -292,6 +292,20 @@ void SSBModGUI::on_agc_toggled(bool checked)
applySettings(); applySettings();
} }
void SSBModGUI::on_cmpPreGain_valueChanged(int value)
{
m_settings.m_cmpPreGainDB = value;
ui->cmpPreGainText->setText(QString("%1").arg(value));
applySettings();
}
void SSBModGUI::on_cmpThreshold_valueChanged(int value)
{
m_settings.m_cmpThresholdDB = value;
ui->cmpThresholdText->setText(QString("%1").arg(value));
applySettings();
}
void SSBModGUI::on_navTimeSlider_valueChanged(int value) void SSBModGUI::on_navTimeSlider_valueChanged(int value)
{ {
if (m_enableNavTime && ((value >= 0) && (value <= 100))) if (m_enableNavTime && ((value >= 0) && (value <= 100)))
@ -633,6 +647,8 @@ void SSBModGUI::displaySettings()
blockApplySettings(true); blockApplySettings(true);
ui->agc->setChecked(m_settings.m_agc); ui->agc->setChecked(m_settings.m_agc);
ui->cmpPreGainText->setText(QString("%1").arg(m_settings.m_cmpPreGainDB));
ui->cmpThresholdText->setText(QString("%1").arg(m_settings.m_cmpThresholdDB));
ui->audioBinaural->setChecked(m_settings.m_audioBinaural); ui->audioBinaural->setChecked(m_settings.m_audioBinaural);
ui->audioFlipChannels->setChecked(m_settings.m_audioFlipChannels); ui->audioFlipChannels->setChecked(m_settings.m_audioFlipChannels);
ui->audioMute->setChecked(m_settings.m_audioMute); ui->audioMute->setChecked(m_settings.m_audioMute);

Wyświetl plik

@ -110,6 +110,8 @@ private slots:
void on_toneFrequency_valueChanged(int value); void on_toneFrequency_valueChanged(int value);
void on_mic_toggled(bool checked); void on_mic_toggled(bool checked);
void on_agc_toggled(bool checked); void on_agc_toggled(bool checked);
void on_cmpPreGain_valueChanged(int value);
void on_cmpThreshold_valueChanged(int value);
void on_play_toggled(bool checked); void on_play_toggled(bool checked);
void on_playLoop_toggled(bool checked); void on_playLoop_toggled(bool checked);
void on_morseKeyer_toggled(bool checked); void on_morseKeyer_toggled(bool checked);

Wyświetl plik

@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>390</width> <width>430</width>
<height>643</height> <height>643</height>
</rect> </rect>
</property> </property>
@ -18,7 +18,7 @@
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
<size> <size>
<width>390</width> <width>430</width>
<height>0</height> <height>0</height>
</size> </size>
</property> </property>
@ -36,7 +36,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>385</width> <width>430</width>
<height>331</height> <height>331</height>
</rect> </rect>
</property> </property>
@ -739,6 +739,121 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QLabel" name="cmpPreGainLabel">
<property name="text">
<string>G</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="cmpPreGain">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Compressor input gain (dB)</string>
</property>
<property name="minimum">
<number>-20</number>
</property>
<property name="maximum">
<number>20</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="cmpPreGainText">
<property name="minimumSize">
<size>
<width>25</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Audio input gain value</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="text">
<string>-10</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="cmpThresholdLabel">
<property name="text">
<string>T</string>
</property>
</widget>
</item>
<item>
<widget class="QDial" name="cmpThreshold">
<property name="maximumSize">
<size>
<width>24</width>
<height>24</height>
</size>
</property>
<property name="toolTip">
<string>Compressor threshold (dB)</string>
</property>
<property name="minimum">
<number>-80</number>
</property>
<property name="maximum">
<number>-20</number>
</property>
<property name="pageStep">
<number>1</number>
</property>
<property name="value">
<number>-60</number>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="cmpThresholdText">
<property name="minimumSize">
<size>
<width>25</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Audio input gain value</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="text">
<string>-60</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item> <item>
<widget class="ButtonSwitch" name="tone"> <widget class="ButtonSwitch" name="tone">
<property name="toolTip"> <property name="toolTip">
@ -1092,7 +1207,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>340</y> <y>340</y>
<width>351</width> <width>430</width>
<height>284</height> <height>284</height>
</rect> </rect>
</property> </property>

Wyświetl plik

@ -59,6 +59,8 @@ void SSBModSettings::resetToDefaults()
m_audioMute = false; m_audioMute = false;
m_playLoop = false; m_playLoop = false;
m_agc = false; m_agc = false;
m_cmpPreGainDB = -10;
m_cmpThresholdDB = -60;
m_rgbColor = QColor(0, 255, 0).rgb(); m_rgbColor = QColor(0, 255, 0).rgb();
m_title = "SSB Modulator"; m_title = "SSB Modulator";
m_modAFInput = SSBModInputAF::SSBModInputNone; m_modAFInput = SSBModInputAF::SSBModInputNone;
@ -100,6 +102,8 @@ QByteArray SSBModSettings::serialize() const
s.writeBool(10, m_audioFlipChannels); s.writeBool(10, m_audioFlipChannels);
s.writeBool(11, m_dsb); s.writeBool(11, m_dsb);
s.writeBool(12, m_agc); s.writeBool(12, m_agc);
s.writeS32(13, m_cmpPreGainDB);
s.writeS32(14, m_cmpThresholdDB);
if (m_channelMarker) { if (m_channelMarker) {
s.writeBlob(18, m_channelMarker->serialize()); s.writeBlob(18, m_channelMarker->serialize());
@ -169,7 +173,8 @@ bool SSBModSettings::deserialize(const QByteArray& data)
d.readBool(10, &m_audioFlipChannels, false); d.readBool(10, &m_audioFlipChannels, false);
d.readBool(11, &m_dsb, false); d.readBool(11, &m_dsb, false);
d.readBool(12, &m_agc, false); d.readBool(12, &m_agc, false);
d.readS32(13, &tmp, 7); d.readS32(13, &m_cmpPreGainDB, -10);
d.readS32(14, &m_cmpThresholdDB, -60);
if (m_channelMarker) { if (m_channelMarker) {
d.readBlob(18, &bytetmp); d.readBlob(18, &bytetmp);

Wyświetl plik

@ -53,6 +53,8 @@ struct SSBModSettings
bool m_audioMute; bool m_audioMute;
bool m_playLoop; bool m_playLoop;
bool m_agc; bool m_agc;
int m_cmpPreGainDB;
int m_cmpThresholdDB;
quint32 m_rgbColor; quint32 m_rgbColor;
QString m_title; QString m_title;

Wyświetl plik

@ -64,8 +64,8 @@ SSBModSource::SSBModSource() :
m_audioCompressor.initSimple( m_audioCompressor.initSimple(
m_audioSampleRate, m_audioSampleRate,
-10, // pregain (dB) -3 m_settings.m_cmpPreGainDB, // pregain (dB)
-60, // threshold (dB) -50 m_settings.m_cmpThresholdDB, // threshold (dB)
20, // knee (dB) 20, // knee (dB)
12, // ratio (dB) 12, // ratio (dB)
0.003, // attack (s) 0.003, // attack (s)
@ -648,6 +648,20 @@ void SSBModSource::applySettings(const SSBModSettings& settings, bool force)
} }
} }
if ((settings.m_cmpThresholdDB != m_settings.m_cmpThresholdDB) ||
(settings.m_cmpPreGainDB != m_settings.m_cmpPreGainDB) || force)
{
m_audioCompressor.initSimple(
m_audioSampleRate,
settings.m_cmpPreGainDB, // pregain (dB)
settings.m_cmpThresholdDB, // threshold (dB)
20, // knee (dB)
12, // ratio (dB)
0.003, // attack (s)
0.25 // release (s)
);
}
m_settings = settings; m_settings = settings;
m_settings.m_bandwidth = band; m_settings.m_bandwidth = band;
m_settings.m_lowCutoff = lowCutoff; m_settings.m_lowCutoff = lowCutoff;

Wyświetl plik

@ -7968,6 +7968,12 @@ margin-bottom: 20px;
"agc" : { "agc" : {
"type" : "integer" "type" : "integer"
}, },
"cmpPreGainDB" : {
"type" : "integer"
},
"cmpThresholdDB" : {
"type" : "integer"
},
"rgbColor" : { "rgbColor" : {
"type" : "integer" "type" : "integer"
}, },
@ -44706,7 +44712,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2020-11-24T20:20:00.458+01:00 Generated 2020-11-25T13:34:12.214+01:00
</div> </div>
</div> </div>
</div> </div>

Wyświetl plik

@ -32,6 +32,10 @@ SSBModSettings:
type: integer type: integer
agc: agc:
type: integer type: integer
cmpPreGainDB:
type: integer
cmpThresholdDB:
type: integer
rgbColor: rgbColor:
type: integer type: integer
title: title:

Wyświetl plik

@ -32,6 +32,10 @@ SSBModSettings:
type: integer type: integer
agc: agc:
type: integer type: integer
cmpPreGainDB:
type: integer
cmpThresholdDB:
type: integer
rgbColor: rgbColor:
type: integer type: integer
title: title:

Wyświetl plik

@ -7968,6 +7968,12 @@ margin-bottom: 20px;
"agc" : { "agc" : {
"type" : "integer" "type" : "integer"
}, },
"cmpPreGainDB" : {
"type" : "integer"
},
"cmpThresholdDB" : {
"type" : "integer"
},
"rgbColor" : { "rgbColor" : {
"type" : "integer" "type" : "integer"
}, },
@ -44706,7 +44712,7 @@ except ApiException as e:
</div> </div>
<div id="generator"> <div id="generator">
<div class="content"> <div class="content">
Generated 2020-11-24T20:20:00.458+01:00 Generated 2020-11-25T13:34:12.214+01:00
</div> </div>
</div> </div>
</div> </div>

Wyświetl plik

@ -54,6 +54,10 @@ SWGSSBModSettings::SWGSSBModSettings() {
m_play_loop_isSet = false; m_play_loop_isSet = false;
agc = 0; agc = 0;
m_agc_isSet = false; m_agc_isSet = false;
cmp_pre_gain_db = 0;
m_cmp_pre_gain_db_isSet = false;
cmp_threshold_db = 0;
m_cmp_threshold_db_isSet = false;
rgb_color = 0; rgb_color = 0;
m_rgb_color_isSet = false; m_rgb_color_isSet = false;
title = nullptr; title = nullptr;
@ -110,6 +114,10 @@ SWGSSBModSettings::init() {
m_play_loop_isSet = false; m_play_loop_isSet = false;
agc = 0; agc = 0;
m_agc_isSet = false; m_agc_isSet = false;
cmp_pre_gain_db = 0;
m_cmp_pre_gain_db_isSet = false;
cmp_threshold_db = 0;
m_cmp_threshold_db_isSet = false;
rgb_color = 0; rgb_color = 0;
m_rgb_color_isSet = false; m_rgb_color_isSet = false;
title = new QString(""); title = new QString("");
@ -150,6 +158,8 @@ SWGSSBModSettings::cleanup() {
if(title != nullptr) { if(title != nullptr) {
delete title; delete title;
} }
@ -207,6 +217,10 @@ SWGSSBModSettings::fromJsonObject(QJsonObject &pJson) {
::SWGSDRangel::setValue(&agc, pJson["agc"], "qint32", ""); ::SWGSDRangel::setValue(&agc, pJson["agc"], "qint32", "");
::SWGSDRangel::setValue(&cmp_pre_gain_db, pJson["cmpPreGainDB"], "qint32", "");
::SWGSDRangel::setValue(&cmp_threshold_db, pJson["cmpThresholdDB"], "qint32", "");
::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", ""); ::SWGSDRangel::setValue(&rgb_color, pJson["rgbColor"], "qint32", "");
::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString"); ::SWGSDRangel::setValue(&title, pJson["title"], "QString", "QString");
@ -284,6 +298,12 @@ SWGSSBModSettings::asJsonObject() {
if(m_agc_isSet){ if(m_agc_isSet){
obj->insert("agc", QJsonValue(agc)); obj->insert("agc", QJsonValue(agc));
} }
if(m_cmp_pre_gain_db_isSet){
obj->insert("cmpPreGainDB", QJsonValue(cmp_pre_gain_db));
}
if(m_cmp_threshold_db_isSet){
obj->insert("cmpThresholdDB", QJsonValue(cmp_threshold_db));
}
if(m_rgb_color_isSet){ if(m_rgb_color_isSet){
obj->insert("rgbColor", QJsonValue(rgb_color)); obj->insert("rgbColor", QJsonValue(rgb_color));
} }
@ -451,6 +471,26 @@ SWGSSBModSettings::setAgc(qint32 agc) {
this->m_agc_isSet = true; this->m_agc_isSet = true;
} }
qint32
SWGSSBModSettings::getCmpPreGainDb() {
return cmp_pre_gain_db;
}
void
SWGSSBModSettings::setCmpPreGainDb(qint32 cmp_pre_gain_db) {
this->cmp_pre_gain_db = cmp_pre_gain_db;
this->m_cmp_pre_gain_db_isSet = true;
}
qint32
SWGSSBModSettings::getCmpThresholdDb() {
return cmp_threshold_db;
}
void
SWGSSBModSettings::setCmpThresholdDb(qint32 cmp_threshold_db) {
this->cmp_threshold_db = cmp_threshold_db;
this->m_cmp_threshold_db_isSet = true;
}
qint32 qint32
SWGSSBModSettings::getRgbColor() { SWGSSBModSettings::getRgbColor() {
return rgb_color; return rgb_color;
@ -605,6 +645,12 @@ SWGSSBModSettings::isSet(){
if(m_agc_isSet){ if(m_agc_isSet){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }
if(m_cmp_pre_gain_db_isSet){
isObjectUpdated = true; break;
}
if(m_cmp_threshold_db_isSet){
isObjectUpdated = true; break;
}
if(m_rgb_color_isSet){ if(m_rgb_color_isSet){
isObjectUpdated = true; break; isObjectUpdated = true; break;
} }

Wyświetl plik

@ -82,6 +82,12 @@ public:
qint32 getAgc(); qint32 getAgc();
void setAgc(qint32 agc); void setAgc(qint32 agc);
qint32 getCmpPreGainDb();
void setCmpPreGainDb(qint32 cmp_pre_gain_db);
qint32 getCmpThresholdDb();
void setCmpThresholdDb(qint32 cmp_threshold_db);
qint32 getRgbColor(); qint32 getRgbColor();
void setRgbColor(qint32 rgb_color); void setRgbColor(qint32 rgb_color);
@ -158,6 +164,12 @@ private:
qint32 agc; qint32 agc;
bool m_agc_isSet; bool m_agc_isSet;
qint32 cmp_pre_gain_db;
bool m_cmp_pre_gain_db_isSet;
qint32 cmp_threshold_db;
bool m_cmp_threshold_db_isSet;
qint32 rgb_color; qint32 rgb_color;
bool m_rgb_color_isSet; bool m_rgb_color_isSet;