From dc4a98b58ad9cb42a41918dfe117a09d56c2f879 Mon Sep 17 00:00:00 2001 From: f4exb Date: Mon, 1 Apr 2019 14:40:01 +0200 Subject: [PATCH] HackRF output: compensate shifted interpolators --- .../samplesink/hackrfoutput/hackrfoutput.cpp | 11 ++-- .../hackrfoutput/hackrfoutputgui.cpp | 1 + sdrbase/dsp/devicesamplesink.cpp | 59 +++++++++++-------- 3 files changed, 41 insertions(+), 30 deletions(-) diff --git a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp index 550cc0b46..a15bc9dd2 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutput.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutput.cpp @@ -278,7 +278,7 @@ bool HackRFOutput::handleMessage(const Message& message) freqMsg.getFrequency(), 0, m_settings.m_log2Interp, - DeviceSampleSink::FC_POS_CENTER, + (DeviceSampleSink::fcPos_t) m_settings.m_fcPos, m_settings.m_devSampleRate); qDebug("HackRFOutput::handleMessage: MsgSynchronizeFrequency: centerFrequency: %lld Hz", centerFrequency); HackRFOutputSettings settings = m_settings; @@ -414,14 +414,17 @@ bool HackRFOutput::applySettings(const HackRFOutputSettings& settings, bool forc reverseAPIKeys.append("LOppmTenths"); } - if (force || (m_settings.m_centerFrequency != settings.m_centerFrequency) || - (m_settings.m_LOppmTenths != settings.m_LOppmTenths)) + if ((m_settings.m_centerFrequency != settings.m_centerFrequency) || + (m_settings.m_devSampleRate != settings.m_devSampleRate) || + (m_settings.m_LOppmTenths != settings.m_LOppmTenths) || + (m_settings.m_log2Interp != settings.m_log2Interp) || + (m_settings.m_fcPos != settings.m_fcPos) || force) { qint64 deviceCenterFrequency = DeviceSampleSink::calculateDeviceCenterFrequency( settings.m_centerFrequency, 0, settings.m_log2Interp, - DeviceSampleSink::FC_POS_CENTER, + (DeviceSampleSink::fcPos_t) settings.m_fcPos, settings.m_devSampleRate); setDeviceCenterFrequency(deviceCenterFrequency, settings.m_LOppmTenths); diff --git a/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp b/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp index 0ff146bfa..6473776f2 100644 --- a/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp +++ b/plugins/samplesink/hackrfoutput/hackrfoutputgui.cpp @@ -211,6 +211,7 @@ void HackRFOutputGui::displaySettings() ui->sampleRate->setValue(m_settings.m_devSampleRate); ui->interp->setCurrentIndex(m_settings.m_log2Interp); + ui->fcPos->setCurrentIndex((int) m_settings.m_fcPos); ui->lnaExt->setChecked(m_settings.m_lnaExt); ui->txvgaGainText->setText(tr("%1dB").arg(m_settings.m_vgaGain)); diff --git a/sdrbase/dsp/devicesamplesink.cpp b/sdrbase/dsp/devicesamplesink.cpp index d26237946..702fffd96 100644 --- a/sdrbase/dsp/devicesamplesink.cpp +++ b/sdrbase/dsp/devicesamplesink.cpp @@ -96,41 +96,48 @@ qint64 DeviceSampleSink::calculateCenterFrequency( /** * log2Interp = 0: no shift * - * n = log2Interp <= 2: fc = +/- 1/2^(n-1) - * center - * | ^ | - * | inf | sup | - * ^ ^ + * log2Interp = 1: middle of side band (inf or sup: 1/2) + * ^ | ^ + * | inf | inf | sup | sup | + * + * log2Interp = 2: middle of far side half side band (inf, inf or sup, sup: 1/2 + 1/4) + * ^ | ^ + * | inf | inf | sup | sup | + * + * log2Interp = 3: inf, inf, sup or sup, sup, inf: 1/2 + 1/4 - 1/8 = 5/8 + * log2Interp = 4: inf, inf, sup, inf or sup, sup, inf, sup: 1/2 + 1/4 - 1/8 + 1/16 = 11/16 + * log2Interp = 5: inf, inf, sup, inf, sup or sup, sup, inf, sup, inf: 1/2 + 1/4 - 1/8 + 1/16 - 1/32 = 21/32 + * log2Interp = 6: inf, sup, inf, sup, inf, sup or sup, inf, sup, inf, sup, inf: 1/2 - 1/4 + 1/8 -1/16 + 1/32 - 1/64 = 21/64 * - * n = log2Interp > 2: fc = +/- 1/2^n - * center - * | ^ | - * | |inf| | |sup| | - * ^ ^ */ qint32 DeviceSampleSink::calculateFrequencyShift( int log2Interp, fcPos_t fcPos, quint32 devSampleRate) { - if (log2Interp == 0) { // no shift at all + if (fcPos == FC_POS_CENTER) { return 0; - } else if (log2Interp < 3) { - if (fcPos == FC_POS_INFRA) { // shift in the square next to center frequency - return -(devSampleRate / (1<<(log2Interp+1))); - } else if (fcPos == FC_POS_SUPRA) { - return devSampleRate / (1<<(log2Interp+1)); - } else { - return 0; - } + } + + int sign = fcPos == FC_POS_INFRA ? -1 : 1; + int halfSampleRate = devSampleRate / 2; // fractions are relative to sideband thus based on half the sample rate + + if (log2Interp == 0) { + return 0; + } else if (log2Interp == 1) { + return sign * (halfSampleRate / 2); + } else if (log2Interp == 2) { + return sign * ((halfSampleRate * 3) / 4); + } else if (log2Interp == 3) { + return sign * ((halfSampleRate * 5) / 8); + } else if (log2Interp == 4) { + return sign * ((halfSampleRate * 11) / 16); + } else if (log2Interp == 5) { + return sign * ((halfSampleRate * 21) / 32); + } else if (log2Interp == 6) { + return sign * ((halfSampleRate * 21) / 64); } else { - if (fcPos == FC_POS_INFRA) { // shift centered in the square next to center frequency - return -(devSampleRate / (1<<(log2Interp))); - } else if (fcPos == FC_POS_SUPRA) { - return devSampleRate / (1<<(log2Interp)); - } else { - return 0; - } + return 0; } }