diff --git a/doc/img/AudioInput_plugin.png b/doc/img/AudioInput_plugin.png index e8e5432fd..ca2db97d7 100644 Binary files a/doc/img/AudioInput_plugin.png and b/doc/img/AudioInput_plugin.png differ diff --git a/doc/img/AudioInput_plugin.xcf b/doc/img/AudioInput_plugin.xcf index 355344f63..f4d8d55c5 100644 Binary files a/doc/img/AudioInput_plugin.xcf and b/doc/img/AudioInput_plugin.xcf differ diff --git a/plugins/samplesource/audioinput/audioinput.cpp b/plugins/samplesource/audioinput/audioinput.cpp index 8c10c5d2f..8e267e5e1 100644 --- a/plugins/samplesource/audioinput/audioinput.cpp +++ b/plugins/samplesource/audioinput/audioinput.cpp @@ -303,6 +303,15 @@ void AudioInput::applySettings(const AudioInputSettings& settings, QListsetFcPos((int) settings.m_fcPos); + } + + qDebug() << "AudioInput::applySettings: set fc pos (enum) to " << (int) settings.m_fcPos; + } + if (settingsKeys.contains("iqMapping") || force) { forwardChange = true; @@ -437,6 +446,9 @@ void AudioInput::webapiUpdateDeviceSettings( if (deviceSettingsKeys.contains("iqImbalance")) { settings.m_iqImbalance = response.getAudioInputSettings()->getIqImbalance() != 0; } + if (deviceSettingsKeys.contains("fcPos")) { + settings.m_fcPos = (AudioInputSettings::fcPos_t) response.getAudioInputSettings()->getFcPos(); + } if (deviceSettingsKeys.contains("useReverseAPI")) { settings.m_useReverseAPI = response.getAudioInputSettings()->getUseReverseApi() != 0; } @@ -460,6 +472,7 @@ void AudioInput::webapiFormatDeviceSettings(SWGSDRangel::SWGDeviceSettings& resp response.getAudioInputSettings()->setIqMapping((int)settings.m_iqMapping); response.getAudioInputSettings()->setDcBlock(settings.m_dcBlock ? 1 : 0); response.getAudioInputSettings()->setIqImbalance(settings.m_iqImbalance ? 1 : 0); + response.getAudioInputSettings()->setFcPos((int) settings.m_fcPos); response.getAudioInputSettings()->setUseReverseApi(settings.m_useReverseAPI ? 1 : 0); @@ -505,6 +518,9 @@ void AudioInput::webapiReverseSendSettings(const QList& deviceSettingsK if (deviceSettingsKeys.contains("iqImbalance") || force) { swgAudioInputSettings->setIqImbalance(settings.m_iqImbalance ? 1 : 0); } + if (deviceSettingsKeys.contains("fcPos") || force) { + swgAudioInputSettings->setFcPos(settings.m_fcPos); + } QString deviceSettingsURL = QString("http://%1:%2/sdrangel/deviceset/%3/device/settings") .arg(settings.m_reverseAPIAddress) diff --git a/plugins/samplesource/audioinput/audioinputgui.cpp b/plugins/samplesource/audioinput/audioinputgui.cpp index f2aa2f451..e6cd67f54 100644 --- a/plugins/samplesource/audioinput/audioinputgui.cpp +++ b/plugins/samplesource/audioinput/audioinputgui.cpp @@ -245,6 +245,18 @@ void AudioInputGui::displaySettings() ui->dcOffset->setChecked(m_settings.m_dcBlock); ui->iqImbalance->setChecked(m_settings.m_iqImbalance); refreshSampleRates(ui->device->currentText()); + displayFcTooltip(); +} + +void AudioInputGui::displayFcTooltip() +{ + int32_t fShift = DeviceSampleSource::calculateFrequencyShift( + m_settings.m_log2Decim, + (DeviceSampleSource::fcPos_t) m_settings.m_fcPos, + m_settings.m_sampleRate, + DeviceSampleSource::FrequencyShiftScheme::FSHIFT_STD + ); + ui->fcPos->setToolTip(tr("Relative position of device center frequency: %1 kHz").arg(QString::number(fShift / 1000.0f, 'g', 5))); } void AudioInputGui::on_device_currentIndexChanged(int index) @@ -260,6 +272,7 @@ void AudioInputGui::on_sampleRate_currentIndexChanged(int index) { (void) index; m_settings.m_sampleRate = ui->sampleRate->currentText().toInt(); + displayFcTooltip(); m_settingsKeys.append("sampleRate"); sendSettings(); } @@ -271,6 +284,7 @@ void AudioInputGui::on_decim_currentIndexChanged(int index) } m_settings.m_log2Decim = index; + displayFcTooltip(); m_settingsKeys.append("log2Decim"); sendSettings(); } @@ -305,6 +319,14 @@ void AudioInputGui::on_iqImbalance_toggled(bool checked) sendSettings(); } +void AudioInputGui::on_fcPos_currentIndexChanged(int index) +{ + m_settings.m_fcPos = (AudioInputSettings::fcPos_t) (index < 0 ? 0 : index > 2 ? 2 : index); + displayFcTooltip(); + m_settingsKeys.append("fcPos"); + sendSettings(); +} + void AudioInputGui::on_startStop_toggled(bool checked) { if (m_doApplySettings) @@ -394,5 +416,6 @@ void AudioInputGui::makeUIConnections() QObject::connect(ui->channels, QOverload::of(&QComboBox::currentIndexChanged), this, &AudioInputGui::on_channels_currentIndexChanged); QObject::connect(ui->dcOffset, &ButtonSwitch::toggled, this, &AudioInputGui::on_dcOffset_toggled); QObject::connect(ui->iqImbalance, &ButtonSwitch::toggled, this, &AudioInputGui::on_iqImbalance_toggled); + QObject::connect(ui->fcPos, QOverload::of(&QComboBox::currentIndexChanged), this, &AudioInputGui::on_fcPos_currentIndexChanged); QObject::connect(ui->startStop, &ButtonSwitch::toggled, this, &AudioInputGui::on_startStop_toggled); } diff --git a/plugins/samplesource/audioinput/audioinputgui.h b/plugins/samplesource/audioinput/audioinputgui.h index 17d25ccb5..61767a67c 100644 --- a/plugins/samplesource/audioinput/audioinputgui.h +++ b/plugins/samplesource/audioinput/audioinputgui.h @@ -65,6 +65,7 @@ private: void refreshDeviceList(); void refreshSampleRates(QString deviceName); void displaySettings(); + void displayFcTooltip(); void sendSettings(); void updateSampleRateAndFrequency(); bool handleMessage(const Message& message); @@ -79,6 +80,7 @@ private slots: void on_channels_currentIndexChanged(int index); void on_dcOffset_toggled(bool checked); void on_iqImbalance_toggled(bool checked); + void on_fcPos_currentIndexChanged(int index); void on_startStop_toggled(bool checked); void updateHardware(); void openDeviceSettingsDialog(const QPoint& p); diff --git a/plugins/samplesource/audioinput/audioinputgui.ui b/plugins/samplesource/audioinput/audioinputgui.ui index f54f5ceb5..b79790416 100644 --- a/plugins/samplesource/audioinput/audioinputgui.ui +++ b/plugins/samplesource/audioinput/audioinputgui.ui @@ -304,6 +304,50 @@ + + + + Fp + + + + + + + + 55 + 0 + + + + + 50 + 16777215 + + + + Relative position of device center frequency + + + 2 + + + + Inf + + + + + Sup + + + + + Cen + + + + diff --git a/plugins/samplesource/audioinput/audioinputsettings.cpp b/plugins/samplesource/audioinput/audioinputsettings.cpp index dc51693f4..befc8429c 100644 --- a/plugins/samplesource/audioinput/audioinputsettings.cpp +++ b/plugins/samplesource/audioinput/audioinputsettings.cpp @@ -35,6 +35,7 @@ void AudioInputSettings::resetToDefaults() m_dcBlock = false; m_iqImbalance = false; m_useReverseAPI = false; + m_fcPos = FC_POS_CENTER; m_reverseAPIAddress = "127.0.0.1"; m_reverseAPIPort = 8888; m_reverseAPIDeviceIndex = 0; @@ -51,6 +52,7 @@ QByteArray AudioInputSettings::serialize() const s.writeS32(5, (int)m_iqMapping); s.writeBool(6, m_dcBlock); s.writeBool(7, m_iqImbalance); + s.writeS32(8, (int) m_fcPos); s.writeBool(24, m_useReverseAPI); s.writeString(25, m_reverseAPIAddress); @@ -73,6 +75,7 @@ bool AudioInputSettings::deserialize(const QByteArray& data) if (d.getVersion() == 1) { uint32_t uintval; + int intval; d.readString(1, &m_deviceName, ""); d.readS32(2, &m_sampleRate, 48000); @@ -81,6 +84,8 @@ bool AudioInputSettings::deserialize(const QByteArray& data) d.readS32(5, (int *)&m_iqMapping, IQMapping::L); d.readBool(6, &m_dcBlock, false); d.readBool(7, &m_iqImbalance, false); + d.readS32(8, &intval, 2); + m_fcPos = (fcPos_t) intval; d.readBool(24, &m_useReverseAPI, false); d.readString(25, &m_reverseAPIAddress, "127.0.0.1"); @@ -127,6 +132,9 @@ void AudioInputSettings::applySettings(const QStringList& settingsKeys, const Au if (settingsKeys.contains("iqImbalance")) { m_iqImbalance = settings.m_iqImbalance; } + if (settingsKeys.contains("fcPos")) { + m_fcPos = settings.m_fcPos; + } if (settingsKeys.contains("useReverseAPI")) { m_useReverseAPI = settings.m_useReverseAPI; } @@ -166,6 +174,9 @@ QString AudioInputSettings::getDebugString(const QStringList& settingsKeys, bool if (settingsKeys.contains("iqImbalance") || force) { ostr << " m_iqImbalance: " << m_iqImbalance; } + if (settingsKeys.contains("fcPos") || force) { + ostr << " m_fcPos: " << m_fcPos; + } if (settingsKeys.contains("useReverseAPI") || force) { ostr << " m_useReverseAPI: " << m_useReverseAPI; } diff --git a/plugins/samplesource/audioinput/audioinputsettings.h b/plugins/samplesource/audioinput/audioinputsettings.h index 1f4ccf0e8..18656402e 100644 --- a/plugins/samplesource/audioinput/audioinputsettings.h +++ b/plugins/samplesource/audioinput/audioinputsettings.h @@ -24,6 +24,12 @@ struct AudioInputSettings { + typedef enum { + FC_POS_INFRA = 0, + FC_POS_SUPRA, + FC_POS_CENTER + } fcPos_t; + QString m_deviceName; // Including realm, as from getFullDeviceName below int m_sampleRate; float m_volume; @@ -36,6 +42,7 @@ struct AudioInputSettings { } m_iqMapping; bool m_dcBlock; bool m_iqImbalance; + fcPos_t m_fcPos; bool m_useReverseAPI; QString m_reverseAPIAddress; diff --git a/plugins/samplesource/audioinput/audioinputworker.cpp b/plugins/samplesource/audioinput/audioinputworker.cpp index 7de170adf..a70967cd1 100644 --- a/plugins/samplesource/audioinput/audioinputworker.cpp +++ b/plugins/samplesource/audioinput/audioinputworker.cpp @@ -107,31 +107,90 @@ void AudioInputWorker::decimate(qint16 *buf, unsigned int nbRead) { SampleVector::iterator it = m_convertBuffer.begin(); - switch (m_log2Decim) - { - case 0: - m_decimatorsIQ.decimate1(&it, buf, 2*nbRead); - break; - case 1: - m_decimatorsIQ.decimate2_cen(&it, buf, 2*nbRead); - break; - case 2: - m_decimatorsIQ.decimate4_cen(&it, buf, 2*nbRead); - break; - case 3: - m_decimatorsIQ.decimate8_cen(&it, buf, 2*nbRead); - break; - case 4: - m_decimatorsIQ.decimate16_cen(&it, buf, 2*nbRead); - break; - case 5: - m_decimatorsIQ.decimate32_cen(&it, buf, 2*nbRead); - break; - case 6: - m_decimatorsIQ.decimate64_cen(&it, buf, 2*nbRead); - break; - default: - break; + if (m_log2Decim == 0) + { + m_decimatorsIQ.decimate1(&it, buf, 2*nbRead); + } + else + { + if (m_fcPos == 0) // Infradyne + { + switch (m_log2Decim) + { + case 1: + m_decimatorsIQ.decimate2_inf(&it, buf, 2*nbRead); + break; + case 2: + m_decimatorsIQ.decimate4_inf(&it, buf, 2*nbRead); + break; + case 3: + m_decimatorsIQ.decimate8_inf(&it, buf, 2*nbRead); + break; + case 4: + m_decimatorsIQ.decimate16_inf(&it, buf, 2*nbRead); + break; + case 5: + m_decimatorsIQ.decimate32_inf(&it, buf, 2*nbRead); + break; + case 6: + m_decimatorsIQ.decimate64_inf(&it, buf, 2*nbRead); + break; + default: + break; + } + } + else if (m_fcPos == 1) // Supradyne + { + switch (m_log2Decim) + { + case 1: + m_decimatorsIQ.decimate2_sup(&it, buf, 2*nbRead); + break; + case 2: + m_decimatorsIQ.decimate4_sup(&it, buf, 2*nbRead); + break; + case 3: + m_decimatorsIQ.decimate8_sup(&it, buf, 2*nbRead); + break; + case 4: + m_decimatorsIQ.decimate16_sup(&it, buf, 2*nbRead); + break; + case 5: + m_decimatorsIQ.decimate32_sup(&it, buf, 2*nbRead); + break; + case 6: + m_decimatorsIQ.decimate64_sup(&it, buf, 2*nbRead); + break; + default: + break; + } + } + else // centered + { + switch (m_log2Decim) + { + case 1: + m_decimatorsIQ.decimate2_cen(&it, buf, 2*nbRead); + break; + case 2: + m_decimatorsIQ.decimate4_cen(&it, buf, 2*nbRead); + break; + case 3: + m_decimatorsIQ.decimate8_cen(&it, buf, 2*nbRead); + break; + case 4: + m_decimatorsIQ.decimate16_cen(&it, buf, 2*nbRead); + break; + case 5: + m_decimatorsIQ.decimate32_cen(&it, buf, 2*nbRead); + break; + case 6: + m_decimatorsIQ.decimate64_cen(&it, buf, 2*nbRead); + break; + default: + break; + } + } } m_sampleFifo->write(m_convertBuffer.begin(), it); diff --git a/plugins/samplesource/audioinput/audioinputworker.h b/plugins/samplesource/audioinput/audioinputworker.h index f0c4e62ef..ad7bfeb64 100644 --- a/plugins/samplesource/audioinput/audioinputworker.h +++ b/plugins/samplesource/audioinput/audioinputworker.h @@ -37,6 +37,7 @@ public: void startWork(); void stopWork(); void setLog2Decimation(unsigned int log2_decim) {m_log2Decim = log2_decim;} + void setFcPos(int fcPos) { m_fcPos = fcPos; } void setIQMapping(AudioInputSettings::IQMapping iqMapping) {m_iqMapping = iqMapping;} static const int m_convBufSamples = 4096; @@ -45,6 +46,7 @@ private: bool m_running; unsigned int m_log2Decim; + int m_fcPos; AudioInputSettings::IQMapping m_iqMapping; qint16 m_buf[m_convBufSamples*2]; // stereo (I, Q) diff --git a/plugins/samplesource/audioinput/readme.md b/plugins/samplesource/audioinput/readme.md index 3e1e5d6c3..9636db683 100644 --- a/plugins/samplesource/audioinput/readme.md +++ b/plugins/samplesource/audioinput/readme.md @@ -18,27 +18,43 @@ Device start / stop button. - Green square icon: device is running and can be stopped - Magenta (or pink) square icon: an error occurred. In the case the device was accidentally disconnected you may click on the icon, plug back in and start again. -

2: Device

+

2: Auto remove DC component

+ +Software DSP auto remove DC correction. This will work in I/Q mode (stereo I/Q) only. + +

3: Auto make I/Q balance

+ +Software DSP auto I/Q imbalance correction. The DC correction (8) must be enabled for this to be effective. This will work in I/Q mode (stereo I/Q) only. + +

4: Device

The audio device to use. -

3: Refresh devices

+

5: Refresh devices

Refresh the list of audio devices. -

4: Audio sample rate

+

6: Audio sample rate

Audio sample rate in Hz (Sa/s). -

5: Decimation

+

7: Decimation

A decimation factor to apply to the audio data. The baseband sample rate will be the audio sample, divided by this decimation factor. -

6: Volume

+

8: Decimated bandpass center frequency position relative the device center frequency

+ +This will work in I/Q mode (stereo I/Q) only. + + - **Cen**: the decimation operation takes place around the device center frequency Fs + - **Inf**: the decimation operation takes place around Fs - Fc. + - **Sup**: the decimation operation takes place around Fs + Fc. + +

9: Volume

A control to set the input volume. This is not supported by all input audio devices. -

7: Channel Map

+

10: Channel Map

This controls how the left and right audio channels map on to the IQ channels. @@ -47,10 +63,3 @@ This controls how the left and right audio channels map on to the IQ channels. * I=L, Q=R - The left audio channel is driven to the I channel. The right audio channel is driven to the Q channel for a complex (analytic signal)input. * I=R, Q=L - The right audio channel is driven to the I channel. The left audio channel is driven to the Q channel for a complex (analytic signal)input. -

8: Auto remove DC component

- -Software DSP auto remove DC correction. - -

9: Auto make I/Q balance

- -Software DSP auto I/Q imbalance correction. The DC correction (8) must be enabled for this to be effective. diff --git a/sdrbase/resources/webapi/doc/html2/index.html b/sdrbase/resources/webapi/doc/html2/index.html index 2d4ce2c29..c773bcbb9 100644 --- a/sdrbase/resources/webapi/doc/html2/index.html +++ b/sdrbase/resources/webapi/doc/html2/index.html @@ -2457,6 +2457,10 @@ margin-bottom: 20px; "type" : "integer", "description" : "Auto IQ balance (you need auto DC blocking active)\n * 0 - Off\n * 1 - On\n" }, + "fcPos" : { + "type" : "integer", + "description" : "Decimated bandpass center frequency position\n * 0 - Infradyne\n * 1 - Supradyne\n * 2 - Centered\n" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -57256,7 +57260,7 @@ except ApiException as e:
- Generated 2023-03-11T04:40:02.823+01:00 + Generated 2023-03-11T09:38:49.252+01:00
diff --git a/sdrbase/resources/webapi/doc/swagger/include/AudioInput.yaml b/sdrbase/resources/webapi/doc/swagger/include/AudioInput.yaml index 4c78a925e..56a7cd227 100644 --- a/sdrbase/resources/webapi/doc/swagger/include/AudioInput.yaml +++ b/sdrbase/resources/webapi/doc/swagger/include/AudioInput.yaml @@ -33,6 +33,13 @@ AudioInputSettings: Auto IQ balance (you need auto DC blocking active) * 0 - Off * 1 - On + fcPos: + type: integer + description: > + Decimated bandpass center frequency position + * 0 - Infradyne + * 1 - Supradyne + * 2 - Centered useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/swagger/sdrangel/api/swagger/include/AudioInput.yaml b/swagger/sdrangel/api/swagger/include/AudioInput.yaml index 4c78a925e..56a7cd227 100644 --- a/swagger/sdrangel/api/swagger/include/AudioInput.yaml +++ b/swagger/sdrangel/api/swagger/include/AudioInput.yaml @@ -33,6 +33,13 @@ AudioInputSettings: Auto IQ balance (you need auto DC blocking active) * 0 - Off * 1 - On + fcPos: + type: integer + description: > + Decimated bandpass center frequency position + * 0 - Infradyne + * 1 - Supradyne + * 2 - Centered useReverseAPI: description: Synchronize with reverse API (1 for yes, 0 for no) type: integer diff --git a/swagger/sdrangel/code/html2/index.html b/swagger/sdrangel/code/html2/index.html index 2d4ce2c29..c773bcbb9 100644 --- a/swagger/sdrangel/code/html2/index.html +++ b/swagger/sdrangel/code/html2/index.html @@ -2457,6 +2457,10 @@ margin-bottom: 20px; "type" : "integer", "description" : "Auto IQ balance (you need auto DC blocking active)\n * 0 - Off\n * 1 - On\n" }, + "fcPos" : { + "type" : "integer", + "description" : "Decimated bandpass center frequency position\n * 0 - Infradyne\n * 1 - Supradyne\n * 2 - Centered\n" + }, "useReverseAPI" : { "type" : "integer", "description" : "Synchronize with reverse API (1 for yes, 0 for no)" @@ -57256,7 +57260,7 @@ except ApiException as e:
- Generated 2023-03-11T04:40:02.823+01:00 + Generated 2023-03-11T09:38:49.252+01:00
diff --git a/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.cpp b/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.cpp index 6d5e34ad4..d71aa5a82 100644 --- a/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.cpp +++ b/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.cpp @@ -42,6 +42,8 @@ SWGAudioInputSettings::SWGAudioInputSettings() { m_dc_block_isSet = false; iq_imbalance = 0; m_iq_imbalance_isSet = false; + fc_pos = 0; + m_fc_pos_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = nullptr; @@ -72,6 +74,8 @@ SWGAudioInputSettings::init() { m_dc_block_isSet = false; iq_imbalance = 0; m_iq_imbalance_isSet = false; + fc_pos = 0; + m_fc_pos_isSet = false; use_reverse_api = 0; m_use_reverse_api_isSet = false; reverse_api_address = new QString(""); @@ -94,6 +98,7 @@ SWGAudioInputSettings::cleanup() { + if(reverse_api_address != nullptr) { delete reverse_api_address; } @@ -126,6 +131,8 @@ SWGAudioInputSettings::fromJsonObject(QJsonObject &pJson) { ::SWGSDRangel::setValue(&iq_imbalance, pJson["iqImbalance"], "qint32", ""); + ::SWGSDRangel::setValue(&fc_pos, pJson["fcPos"], "qint32", ""); + ::SWGSDRangel::setValue(&use_reverse_api, pJson["useReverseAPI"], "qint32", ""); ::SWGSDRangel::setValue(&reverse_api_address, pJson["reverseAPIAddress"], "QString", "QString"); @@ -171,6 +178,9 @@ SWGAudioInputSettings::asJsonObject() { if(m_iq_imbalance_isSet){ obj->insert("iqImbalance", QJsonValue(iq_imbalance)); } + if(m_fc_pos_isSet){ + obj->insert("fcPos", QJsonValue(fc_pos)); + } if(m_use_reverse_api_isSet){ obj->insert("useReverseAPI", QJsonValue(use_reverse_api)); } @@ -257,6 +267,16 @@ SWGAudioInputSettings::setIqImbalance(qint32 iq_imbalance) { this->m_iq_imbalance_isSet = true; } +qint32 +SWGAudioInputSettings::getFcPos() { + return fc_pos; +} +void +SWGAudioInputSettings::setFcPos(qint32 fc_pos) { + this->fc_pos = fc_pos; + this->m_fc_pos_isSet = true; +} + qint32 SWGAudioInputSettings::getUseReverseApi() { return use_reverse_api; @@ -323,6 +343,9 @@ SWGAudioInputSettings::isSet(){ if(m_iq_imbalance_isSet){ isObjectUpdated = true; break; } + if(m_fc_pos_isSet){ + isObjectUpdated = true; break; + } if(m_use_reverse_api_isSet){ isObjectUpdated = true; break; } diff --git a/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.h b/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.h index ca8bb7fbf..ea021a993 100644 --- a/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.h +++ b/swagger/sdrangel/code/qt5/client/SWGAudioInputSettings.h @@ -63,6 +63,9 @@ public: qint32 getIqImbalance(); void setIqImbalance(qint32 iq_imbalance); + qint32 getFcPos(); + void setFcPos(qint32 fc_pos); + qint32 getUseReverseApi(); void setUseReverseApi(qint32 use_reverse_api); @@ -100,6 +103,9 @@ private: qint32 iq_imbalance; bool m_iq_imbalance_isSet; + qint32 fc_pos; + bool m_fc_pos_isSet; + qint32 use_reverse_api; bool m_use_reverse_api_isSet;