mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 21:20:31 -05:00 
			
		
		
		
	Channel analyzer NG: implemented optional RRC filter
This commit is contained in:
		
							parent
							
								
									1dcb84ef8f
								
							
						
					
					
						commit
						775a9775eb
					
				@ -52,6 +52,7 @@ ChannelAnalyzerNG::ChannelAnalyzerNG(DeviceSourceAPI *deviceAPI) :
 | 
			
		||||
	m_inputFrequencyOffset = 0;
 | 
			
		||||
	SSBFilter = new fftfilt(m_settings.m_lowCutoff / m_inputSampleRate, m_settings.m_bandwidth / m_inputSampleRate, ssbFftLen);
 | 
			
		||||
	DSBFilter = new fftfilt(m_settings.m_bandwidth / m_inputSampleRate, 2*ssbFftLen);
 | 
			
		||||
	RRCFilter = new fftfilt(m_settings.m_bandwidth / m_inputSampleRate, 2*ssbFftLen);
 | 
			
		||||
	m_corr = new fftcorr(8*ssbFftLen); // 8k for 4k effective samples
 | 
			
		||||
	m_pll.computeCoefficients(0.002f, 0.5f, 10.0f); // bandwidth, damping factor, loop gain
 | 
			
		||||
 | 
			
		||||
@ -72,6 +73,7 @@ ChannelAnalyzerNG::~ChannelAnalyzerNG()
 | 
			
		||||
    delete m_channelizer;
 | 
			
		||||
    delete SSBFilter;
 | 
			
		||||
    delete DSBFilter;
 | 
			
		||||
    delete RRCFilter;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ChannelAnalyzerNG::configure(MessageQueue* messageQueue,
 | 
			
		||||
@ -129,11 +131,18 @@ void ChannelAnalyzerNG::processOneSample(Complex& c, fftfilt::cmplx *sideband)
 | 
			
		||||
    int n_out;
 | 
			
		||||
    int decim = 1<<m_settings.m_spanLog2;
 | 
			
		||||
 | 
			
		||||
    if (m_settings.m_ssb) {
 | 
			
		||||
    if (m_settings.m_ssb)
 | 
			
		||||
    {
 | 
			
		||||
        n_out = SSBFilter->runSSB(c, &sideband, m_usb);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        if (m_settings.m_rrc) {
 | 
			
		||||
            n_out = RRCFilter->runFilt(c, &sideband);
 | 
			
		||||
        } else {
 | 
			
		||||
            n_out = DSBFilter->runDSB(c, &sideband);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (int i = 0; i < n_out; i++)
 | 
			
		||||
    {
 | 
			
		||||
@ -293,6 +302,7 @@ void ChannelAnalyzerNG::setFilters(int sampleRate, float bandwidth, float lowCut
 | 
			
		||||
 | 
			
		||||
    SSBFilter->create_filter(lowCutoff / sampleRate, bandwidth / sampleRate);
 | 
			
		||||
    DSBFilter->create_dsb_filter(bandwidth / sampleRate);
 | 
			
		||||
    RRCFilter->create_rrc_filter(bandwidth / sampleRate, m_settings.m_rrcRolloff / 100.0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings, bool force)
 | 
			
		||||
@ -300,6 +310,8 @@ void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings,
 | 
			
		||||
    qDebug() << "ChannelAnalyzerNG::applySettings:"
 | 
			
		||||
            << " m_downSample: " << settings.m_downSample
 | 
			
		||||
            << " m_downSampleRate: " << settings.m_downSampleRate
 | 
			
		||||
            << " m_rcc: " << settings.m_rrc
 | 
			
		||||
            << " m_rrcRolloff: " << settings.m_rrcRolloff / 100.0
 | 
			
		||||
            << " m_bandwidth: " << settings.m_bandwidth
 | 
			
		||||
            << " m_lowCutoff: " << settings.m_lowCutoff
 | 
			
		||||
            << " m_spanLog2: " << settings.m_spanLog2
 | 
			
		||||
@ -338,6 +350,14 @@ void ChannelAnalyzerNG::applySettings(const ChannelAnalyzerNGSettings& settings,
 | 
			
		||||
        m_settingsMutex.unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_rrcRolloff != m_settings.m_rrcRolloff) || force)
 | 
			
		||||
    {
 | 
			
		||||
        float sampleRate = settings.m_downSample ? (float) settings.m_downSampleRate : (float) m_inputSampleRate;
 | 
			
		||||
        m_settingsMutex.lock();
 | 
			
		||||
        RRCFilter->create_rrc_filter(settings.m_bandwidth / sampleRate, settings.m_rrcRolloff / 100.0);
 | 
			
		||||
        m_settingsMutex.unlock();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if ((settings.m_spanLog2 != m_settings.m_spanLog2) || force)
 | 
			
		||||
    {
 | 
			
		||||
        int sampleRate = (settings.m_downSample ? settings.m_downSampleRate : m_inputSampleRate) / (1<<m_settings.m_spanLog2);
 | 
			
		||||
 | 
			
		||||
@ -231,6 +231,7 @@ private:
 | 
			
		||||
 | 
			
		||||
	fftfilt* SSBFilter;
 | 
			
		||||
	fftfilt* DSBFilter;
 | 
			
		||||
	fftfilt* RRCFilter;
 | 
			
		||||
	fftcorr* m_corr;
 | 
			
		||||
 | 
			
		||||
	BasebandSampleSink* m_sampleSink;
 | 
			
		||||
 | 
			
		||||
@ -114,6 +114,9 @@ void ChannelAnalyzerNGGUI::displaySettings()
 | 
			
		||||
    ui->spanLog2->setCurrentIndex(m_settings.m_spanLog2);
 | 
			
		||||
    displayPLLSettings();
 | 
			
		||||
    ui->signalSelect->setCurrentIndex((int) m_settings.m_inputType);
 | 
			
		||||
    ui->rrcFilter->setChecked(m_settings.m_rrc);
 | 
			
		||||
    QString rolloffStr = QString::number(m_settings.m_rrcRolloff/100.0, 'f', 2);
 | 
			
		||||
    ui->rrcRolloffText->setText(rolloffStr);
 | 
			
		||||
 | 
			
		||||
    blockApplySettings(false);
 | 
			
		||||
}
 | 
			
		||||
@ -291,6 +294,20 @@ void ChannelAnalyzerNGGUI::on_deltaFrequency_changed(qint64 value)
 | 
			
		||||
    applySettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ChannelAnalyzerNGGUI::on_rrcFilter_toggled(bool checked)
 | 
			
		||||
{
 | 
			
		||||
    m_settings.m_rrc = checked;
 | 
			
		||||
    applySettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ChannelAnalyzerNGGUI::on_rrcRolloff_valueChanged(int value)
 | 
			
		||||
{
 | 
			
		||||
    m_settings.m_rrcRolloff = value;
 | 
			
		||||
    QString rolloffStr = QString::number(value/100.0, 'f', 2);
 | 
			
		||||
    ui->rrcRolloffText->setText(rolloffStr);
 | 
			
		||||
    applySettings();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ChannelAnalyzerNGGUI::on_BW_valueChanged(int value __attribute__((unused)))
 | 
			
		||||
{
 | 
			
		||||
    setFiltersUIBoundaries();
 | 
			
		||||
 | 
			
		||||
@ -99,6 +99,8 @@ private slots:
 | 
			
		||||
    void on_pllPskOrder_currentIndexChanged(int index);
 | 
			
		||||
    void on_useRationalDownsampler_toggled(bool checked);
 | 
			
		||||
    void on_signalSelect_currentIndexChanged(int index);
 | 
			
		||||
    void on_rrcFilter_toggled(bool checked);
 | 
			
		||||
    void on_rrcRolloff_valueChanged(int value);
 | 
			
		||||
	void on_BW_valueChanged(int value);
 | 
			
		||||
	void on_lowCut_valueChanged(int value);
 | 
			
		||||
	void on_spanLog2_currentIndexChanged(int index);
 | 
			
		||||
 | 
			
		||||
@ -419,6 +419,58 @@
 | 
			
		||||
    </item>
 | 
			
		||||
    <item>
 | 
			
		||||
     <layout class="QHBoxLayout" name="BWLayout">
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="ButtonSwitch" name="rrcFilter">
 | 
			
		||||
        <property name="toolTip">
 | 
			
		||||
         <string>Toggle RRC filter</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string/>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="icon">
 | 
			
		||||
         <iconset resource="../../../sdrgui/resources/res.qrc">
 | 
			
		||||
          <normaloff>:/dsb.png</normaloff>:/dsb.png</iconset>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="checkable">
 | 
			
		||||
         <bool>true</bool>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QDial" name="rrcRolloff">
 | 
			
		||||
        <property name="maximumSize">
 | 
			
		||||
         <size>
 | 
			
		||||
          <width>24</width>
 | 
			
		||||
          <height>24</height>
 | 
			
		||||
         </size>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="toolTip">
 | 
			
		||||
         <string>Tune RRC filter rolloff factor</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="minimum">
 | 
			
		||||
         <number>10</number>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="maximum">
 | 
			
		||||
         <number>50</number>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="pageStep">
 | 
			
		||||
         <number>1</number>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="value">
 | 
			
		||||
         <number>30</number>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLabel" name="rrcRolloffText">
 | 
			
		||||
        <property name="toolTip">
 | 
			
		||||
         <string>RRC filter rolloff factor value</string>
 | 
			
		||||
        </property>
 | 
			
		||||
        <property name="text">
 | 
			
		||||
         <string>0.00</string>
 | 
			
		||||
        </property>
 | 
			
		||||
       </widget>
 | 
			
		||||
      </item>
 | 
			
		||||
      <item>
 | 
			
		||||
       <widget class="QLabel" name="BWLabel">
 | 
			
		||||
        <property name="minimumSize">
 | 
			
		||||
 | 
			
		||||
@ -40,6 +40,8 @@ void ChannelAnalyzerNGSettings::resetToDefaults()
 | 
			
		||||
    m_ssb = false;
 | 
			
		||||
    m_pll = false;
 | 
			
		||||
    m_fll = false;
 | 
			
		||||
    m_rrc = false;
 | 
			
		||||
    m_rrcRolloff = 30; // 0.3
 | 
			
		||||
    m_pllPskOrder = 1;
 | 
			
		||||
    m_inputType = InputSignal;
 | 
			
		||||
    m_rgbColor = QColor(128, 128, 128).rgb();
 | 
			
		||||
@ -65,6 +67,8 @@ QByteArray ChannelAnalyzerNGSettings::serialize() const
 | 
			
		||||
    s.writeU32(13, m_pllPskOrder);
 | 
			
		||||
    s.writeS32(14, (int) m_inputType);
 | 
			
		||||
    s.writeString(15, m_title);
 | 
			
		||||
    s.writeBool(16, m_rrc);
 | 
			
		||||
    s.writeU32(17, m_rrcRolloff);
 | 
			
		||||
 | 
			
		||||
    return s.final();
 | 
			
		||||
}
 | 
			
		||||
@ -110,6 +114,8 @@ bool ChannelAnalyzerNGSettings::deserialize(const QByteArray& data)
 | 
			
		||||
        d.readS32(14, &tmp, 0);
 | 
			
		||||
        m_inputType = (InputType) tmp;
 | 
			
		||||
        d.readString(15, &m_title, "Channel Analyzer NG");
 | 
			
		||||
        d.readBool(16, &m_rrc, false);
 | 
			
		||||
        d.readU32(17, &m_rrcRolloff, 30);
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -39,6 +39,8 @@ struct ChannelAnalyzerNGSettings
 | 
			
		||||
    bool m_ssb;
 | 
			
		||||
    bool m_pll;
 | 
			
		||||
    bool m_fll;
 | 
			
		||||
    bool m_rrc;
 | 
			
		||||
    quint32 m_rrcRolloff; //!< in 100ths
 | 
			
		||||
    unsigned int m_pllPskOrder;
 | 
			
		||||
    InputType m_inputType;
 | 
			
		||||
    quint32 m_rgbColor;
 | 
			
		||||
 | 
			
		||||
@ -69,7 +69,7 @@ protected:
 | 
			
		||||
	{
 | 
			
		||||
        float x = i/(float)len; // normalize to [0..1]
 | 
			
		||||
        x = 0.5-fabs(x-0.5); // apply symmetry: now both halves overlap near 0
 | 
			
		||||
        float tr = (fb*a)/2.0; // half the transition zone
 | 
			
		||||
        float tr = fb*a; // half the transition zone
 | 
			
		||||
 | 
			
		||||
        if (x < fb-tr)
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user