/** * @brief Channel filter offset has changed * @param freq The new filter offset in Hz * * This slot is activated when a new filter offset has been selected either * usig the mouse or using the keyboard. */ void DockRxOpt::on_filterFreq_newFrequency(qint64 freq) { qDebug() << "New filter offset:" << freq << "Hz"; updateHwFreq(); emit filterOffsetChanged(freq); }
/** Read receiver configuration from settings data. */ void DockRxOpt::readSettings(QSettings *settings) { bool conv_ok; int intVal; intVal = settings->value("receiver/demod", 0).toInt(&conv_ok); if (intVal >= 0) { setCurrentDemod(intVal); emit demodSelected(intVal); } intVal = settings->value("receiver/cwoffset", 700).toInt(&conv_ok); if (conv_ok) { demodOpt->setCwOffset(intVal); demodOpt_cwOffsetChanged(intVal); } qint64 offs = settings->value("receiver/offset", 0).toInt(&conv_ok); if (offs) { setFilterOffset(offs); emit filterOffsetChanged(offs); } double dblVal = settings->value("receiver/sql_level", 1.0).toDouble(&conv_ok); if (conv_ok && dblVal < 1.0) { //ui->sqlSlider->setValue(intVal); // signal emitted automatically ui->sqlSpinBox->setValue(dblVal); } }
MainWindow::MainWindow(const QString cfgfile, QWidget *parent) : QMainWindow(parent), configOk(true), ui(new Ui::MainWindow), d_lnb_lo(0), d_fftAvg(0.5), d_have_audio(true), dec_afsk1200(0) { ui->setupUi(this); /* Initialise default configuration directory */ QByteArray xdg_dir = qgetenv("XDG_CONFIG_HOME"); if (xdg_dir.isEmpty()) m_cfg_dir = QString("%1/.config/gqrx").arg(QDir::homePath()); // Qt takes care of conversion to native separators else m_cfg_dir = QString("%1/gqrx").arg(xdg_dir.data()); setWindowTitle(QString("Gqrx %1").arg(VERSION)); /* frequency control widget */ ui->freqCtrl->setup(10, (quint64) 0, (quint64) 9999e6, 1, UNITS_MHZ); ui->freqCtrl->setFrequency(144500000); d_filter_shape = receiver::FILTER_SHAPE_NORMAL; /* create receiver object */ rx = new receiver("", ""); rx->set_rf_freq(144500000.0f); /* meter timer */ meter_timer = new QTimer(this); connect(meter_timer, SIGNAL(timeout()), this, SLOT(meterTimeout())); /* FFT timer & data */ iq_fft_timer = new QTimer(this); connect(iq_fft_timer, SIGNAL(timeout()), this, SLOT(iqFftTimeout())); audio_fft_timer = new QTimer(this); connect(audio_fft_timer, SIGNAL(timeout()), this, SLOT(audioFftTimeout())); d_fftData = new std::complex<float>[MAX_FFT_SIZE]; d_realFftData = new double[MAX_FFT_SIZE]; d_pwrFftData = new double[MAX_FFT_SIZE](); d_iirFftData = new double[MAX_FFT_SIZE]; for (int i = 0; i < MAX_FFT_SIZE; i++) d_iirFftData[i] = -120.0; // dBFS /* timer for data decoders */ dec_timer = new QTimer(this); connect(dec_timer, SIGNAL(timeout()), this, SLOT(decoderTimeout())); /* create dock widgets */ uiDockRxOpt = new DockRxOpt(); uiDockAudio = new DockAudio(); uiDockInputCtl = new DockInputCtl(); //uiDockIqPlay = new DockIqPlayer(); uiDockFft = new DockFft(); /* Add dock widgets to main window. This should be done even for dock widgets that are going to be hidden, otherwise they will end up floating in their own top-level window and can not be docked to the mainwindow. */ addDockWidget(Qt::RightDockWidgetArea, uiDockInputCtl); addDockWidget(Qt::RightDockWidgetArea, uiDockRxOpt); tabifyDockWidget(uiDockInputCtl, uiDockRxOpt); addDockWidget(Qt::RightDockWidgetArea, uiDockAudio); addDockWidget(Qt::RightDockWidgetArea, uiDockFft); tabifyDockWidget(uiDockFft, uiDockAudio); //addDockWidget(Qt::BottomDockWidgetArea, uiDockIqPlay); /* hide docks that we don't want to show initially */ /** FIXME: Hide them initially but store layout in config **/ // uiDockInputCtl->hide(); // uiDockFft->hide(); //uiDockIqPlay->hide(); /* misc configurations */ //uiDockAudio->setFftRange(0, 8000); // FM /* Add dock widget actions to View menu. By doing it this way all signal/slot connections will be established automagially. */ ui->menu_View->addAction(uiDockInputCtl->toggleViewAction()); ui->menu_View->addAction(uiDockRxOpt->toggleViewAction()); ui->menu_View->addAction(uiDockAudio->toggleViewAction()); ui->menu_View->addAction(uiDockFft->toggleViewAction()); //ui->menu_View->addAction(uiDockIqPlay->toggleViewAction()); ui->menu_View->addSeparator(); ui->menu_View->addAction(ui->mainToolBar->toggleViewAction()); ui->menu_View->addSeparator(); ui->menu_View->addAction(ui->actionFullScreen); /* connect signals and slots */ connect(ui->freqCtrl, SIGNAL(newFrequency(qint64)), this, SLOT(setNewFrequency(qint64))); connect(uiDockInputCtl, SIGNAL(lnbLoChanged(double)), this, SLOT(setLnbLo(double))); connect(uiDockInputCtl, SIGNAL(gainChanged(double)), SLOT(setRfGain(double))); connect(uiDockInputCtl, SIGNAL(freqCorrChanged(int)), this, SLOT(setFreqCorr(int))); connect(uiDockInputCtl, SIGNAL(iqSwapChanged(bool)), this, SLOT(setIqSwap(bool))); connect(uiDockInputCtl, SIGNAL(dcCancelChanged(bool)), this, SLOT(setDcCancel(bool))); connect(uiDockInputCtl, SIGNAL(iqBalanceChanged(bool)), this, SLOT(setIqBalance(bool))); connect(uiDockInputCtl, SIGNAL(ignoreLimitsChanged(bool)), this, SLOT(setIgnoreLimits(bool))); connect(uiDockRxOpt, SIGNAL(filterOffsetChanged(qint64)), this, SLOT(setFilterOffset(qint64))); connect(uiDockRxOpt, SIGNAL(demodSelected(int)), this, SLOT(selectDemod(int))); connect(uiDockRxOpt, SIGNAL(fmMaxdevSelected(float)), this, SLOT(setFmMaxdev(float))); connect(uiDockRxOpt, SIGNAL(fmEmphSelected(double)), this, SLOT(setFmEmph(double))); connect(uiDockRxOpt, SIGNAL(amDcrToggled(bool)), this, SLOT(setAmDcr(bool))); connect(uiDockRxOpt, SIGNAL(agcToggled(bool)), this, SLOT(setAgcOn(bool))); connect(uiDockRxOpt, SIGNAL(agcHangToggled(bool)), this, SLOT(setAgcHang(bool))); connect(uiDockRxOpt, SIGNAL(agcThresholdChanged(int)), this, SLOT(setAgcThreshold(int))); connect(uiDockRxOpt, SIGNAL(agcSlopeChanged(int)), this, SLOT(setAgcSlope(int))); connect(uiDockRxOpt, SIGNAL(agcGainChanged(int)), this, SLOT(setAgcGain(int))); connect(uiDockRxOpt, SIGNAL(agcDecayChanged(int)), this, SLOT(setAgcDecay(int))); connect(uiDockRxOpt, SIGNAL(noiseBlankerChanged(int,bool,float)), this, SLOT(setNoiseBlanker(int,bool,float))); connect(uiDockRxOpt, SIGNAL(sqlLevelChanged(double)), this, SLOT(setSqlLevel(double))); connect(uiDockAudio, SIGNAL(audioGainChanged(float)), this, SLOT(setAudioGain(float))); connect(uiDockAudio, SIGNAL(audioRecStarted(QString)), this, SLOT(startAudioRec(QString))); connect(uiDockAudio, SIGNAL(audioRecStopped()), this, SLOT(stopAudioRec())); connect(uiDockAudio, SIGNAL(audioPlayStarted(QString)), this, SLOT(startAudioPlayback(QString))); connect(uiDockAudio, SIGNAL(audioPlayStopped()), this, SLOT(stopAudioPlayback())); connect(uiDockAudio, SIGNAL(fftRateChanged(int)), this, SLOT(setAudioFftRate(int))); connect(uiDockFft, SIGNAL(fftSizeChanged(int)), this, SLOT(setIqFftSize(int))); connect(uiDockFft, SIGNAL(fftRateChanged(int)), this, SLOT(setIqFftRate(int))); connect(uiDockFft, SIGNAL(fftSplitChanged(int)), this, SLOT(setIqFftSplit(int))); connect(uiDockFft, SIGNAL(fftAvgChanged(double)), this, SLOT(setIqFftAvg(double))); connect(uiDockFft, SIGNAL(resetFftZoom()), ui->plotter, SLOT(resetHorizontalZoom())); connect(uiDockFft, SIGNAL(gotoFftCenter()), ui->plotter, SLOT(moveToCenterFreq())); connect(uiDockFft, SIGNAL(gotoDemodFreq()), ui->plotter, SLOT(moveToDemodFreq())); // restore last session if (!loadConfig(cfgfile, true)) { qDebug() << "No input device found"; if (on_actionIoConfig_triggered() != QDialog::Accepted) { qDebug() << "I/O device configuration cancelled."; configOk = false; } } }
MainWindow::MainWindow(const QString cfgfile, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), d_lnb_lo(0), dec_bpsk1000(0), dec_afsk1200(0) { ui->setupUi(this); /* Initialise default configuration directory */ QByteArray xdg_dir = qgetenv("XDG_CONFIG_HOME"); if (xdg_dir.isEmpty()) m_cfg_dir = QString("%1/.config/gqrx").arg(QDir::homePath()); // Qt takes care of conversion to native separators else m_cfg_dir = QString("%1/gqrx").arg(xdg_dir.data()); setWindowTitle(QString("gqrx %1 (OsmoSDR)").arg(VERSION)); /* frequency control widget */ ui->freqCtrl->Setup(10, (quint64) 0, (quint64) 9999e6, 1, UNITS_MHZ); ui->freqCtrl->SetFrequency(144500000); d_filter_shape = receiver::FILTER_SHAPE_NORMAL; /* create receiver object */ QString indev = CIoConfig::getFcdDeviceName(); //QString outdev = settings.value("output").toString(); rx = new receiver(indev.toStdString(), ""); rx->set_rf_freq(144500000.0f); rx->set_rf_sample_rate(1920000.0); // TODO variable ui->plotter->setSampleRate(1920000); /* meter timer */ meter_timer = new QTimer(this); connect(meter_timer, SIGNAL(timeout()), this, SLOT(meterTimeout())); /* FFT timer & data */ iq_fft_timer = new QTimer(this); connect(iq_fft_timer, SIGNAL(timeout()), this, SLOT(iqFftTimeout())); audio_fft_timer = new QTimer(this); connect(audio_fft_timer, SIGNAL(timeout()), this, SLOT(audioFftTimeout())); d_fftData = new std::complex<float>[MAX_FFT_SIZE]; d_realFftData = new double[MAX_FFT_SIZE]; /* timer for data decoders */ dec_timer = new QTimer(this); connect(dec_timer, SIGNAL(timeout()), this, SLOT(decoderTimeout())); /* create dock widgets */ uiDockRxOpt = new DockRxOpt(); uiDockAudio = new DockAudio(); uiDockFcdCtl = new DockFcdCtl(); //uiDockIqPlay = new DockIqPlayer(); uiDockFft = new DockFft(); /* Add dock widgets to main window. This should be done even for dock widgets that are going to be hidden, otherwise they will end up floating in their own top-level window and can not be docked to the mainwindow. */ addDockWidget(Qt::RightDockWidgetArea, uiDockFcdCtl); addDockWidget(Qt::RightDockWidgetArea, uiDockRxOpt); tabifyDockWidget(uiDockFcdCtl, uiDockRxOpt); addDockWidget(Qt::RightDockWidgetArea, uiDockAudio); addDockWidget(Qt::RightDockWidgetArea, uiDockFft); tabifyDockWidget(uiDockAudio, uiDockFft); //addDockWidget(Qt::BottomDockWidgetArea, uiDockIqPlay); /* hide docks that we don't want to show initially */ //uiDockFcdCtl->hide(); //uiDockFft->hide(); //uiDockIqPlay->hide(); /* misc configurations */ //uiDockAudio->setFftRange(0, 8000); // FM /* Add dock widget actions to View menu. By doing it this way all signal/slot connections will be established automagially. */ ui->menu_View->addAction(uiDockFcdCtl->toggleViewAction()); ui->menu_View->addAction(uiDockRxOpt->toggleViewAction()); ui->menu_View->addAction(uiDockAudio->toggleViewAction()); ui->menu_View->addAction(uiDockFft->toggleViewAction()); //ui->menu_View->addAction(uiDockIqPlay->toggleViewAction()); ui->menu_View->addSeparator(); ui->menu_View->addAction(ui->mainToolBar->toggleViewAction()); ui->menu_View->addSeparator(); ui->menu_View->addAction(ui->actionFullScreen); /* connect signals and slots */ connect(ui->freqCtrl, SIGNAL(NewFrequency(qint64)), this, SLOT(setNewFrequency(qint64))); connect(uiDockFcdCtl, SIGNAL(lnbLoChanged(double)), this, SLOT(setLnbLo(double))); connect(uiDockFcdCtl, SIGNAL(lnaGainChanged(float)), SLOT(setRfGain(float))); connect(uiDockFcdCtl, SIGNAL(lnaAutoGainChanged(int)), this, SLOT(setRfGainMode(int))); connect(uiDockFcdCtl, SIGNAL(freqCorrChanged(int)), this, SLOT(setFreqCorr(int))); connect(uiDockFcdCtl, SIGNAL(iqCorrChanged(double,double)), this, SLOT(setIqCorr(double,double))); connect(uiDockRxOpt, SIGNAL(filterOffsetChanged(qint64)), this, SLOT(setFilterOffset(qint64))); connect(uiDockRxOpt, SIGNAL(demodSelected(int)), this, SLOT(selectDemod(int))); connect(uiDockRxOpt, SIGNAL(fmMaxdevSelected(float)), this, SLOT(setFmMaxdev(float))); connect(uiDockRxOpt, SIGNAL(fmEmphSelected(double)), this, SLOT(setFmEmph(double))); connect(uiDockRxOpt, SIGNAL(agcToggled(bool)), this, SLOT(setAgcOn(bool))); connect(uiDockRxOpt, SIGNAL(agcHangToggled(bool)), this, SLOT(setAgcHang(bool))); connect(uiDockRxOpt, SIGNAL(agcThresholdChanged(int)), this, SLOT(setAgcThreshold(int))); connect(uiDockRxOpt, SIGNAL(agcSlopeChanged(int)), this, SLOT(setAgcSlope(int))); connect(uiDockRxOpt, SIGNAL(agcGainChanged(int)), this, SLOT(setAgcGain(int))); connect(uiDockRxOpt, SIGNAL(agcDecayChanged(int)), this, SLOT(setAgcDecay(int))); connect(uiDockRxOpt, SIGNAL(noiseBlankerChanged(int,bool,float)), this, SLOT(setNoiseBlanker(int,bool,float))); connect(uiDockRxOpt, SIGNAL(sqlLevelChanged(double)), this, SLOT(setSqlLevel(double))); connect(uiDockAudio, SIGNAL(audioGainChanged(float)), this, SLOT(setAudioGain(float))); connect(uiDockAudio, SIGNAL(audioRecStarted(QString)), this, SLOT(startAudioRec(QString))); connect(uiDockAudio, SIGNAL(audioRecStopped()), this, SLOT(stopAudioRec())); connect(uiDockAudio, SIGNAL(audioPlayStarted(QString)), this, SLOT(startAudioPlayback(QString))); connect(uiDockAudio, SIGNAL(audioPlayStopped()), this, SLOT(stopAudioPlayback())); connect(uiDockAudio, SIGNAL(fftRateChanged(int)), this, SLOT(setAudioFftRate(int))); connect(uiDockFft, SIGNAL(fftSizeChanged(int)), this, SLOT(setIqFftSize(int))); connect(uiDockFft, SIGNAL(fftRateChanged(int)), this, SLOT(setIqFftRate(int))); connect(uiDockFft, SIGNAL(fftSplitChanged(int)), this, SLOT(setIqFftSplit(int))); // restore last session loadConfig(cfgfile); }
/** * @brief Channel filter offset has changed * @param freq The new filter offset in Hz * * This slot is activated when a new filter offset has been selected either * usig the mouse or using the keyboard. */ void DockRxOpt::on_filterFreq_newFrequency(qint64 freq) { updateHwFreq(); emit filterOffsetChanged(freq); }
/** Read receiver configuration from settings data. */ void DockRxOpt::readSettings(QSettings *settings) { bool conv_ok; int int_val; double dbl_val; bool bool_val = settings->value("gui/fctl_reset_digits", true).toBool(); ui->filterFreq->setResetLowerDigits(bool_val); int_val = settings->value("receiver/cwoffset", 700).toInt(&conv_ok); if (conv_ok) demodOpt->setCwOffset(int_val); int_val = settings->value("receiver/fm_maxdev", 2500).toInt(&conv_ok); if (conv_ok) demodOpt->setMaxDev(int_val); dbl_val = settings->value("receiver/fm_deemph", 75).toDouble(&conv_ok); if (conv_ok && dbl_val >= 0) demodOpt->setEmph(1.0e-6 * dbl_val); // was stored as usec qint64 offs = settings->value("receiver/offset", 0).toInt(&conv_ok); if (offs) { setFilterOffset(offs); emit filterOffsetChanged(offs); } dbl_val = settings->value("receiver/sql_level", 1.0).toDouble(&conv_ok); if (conv_ok && dbl_val < 1.0) ui->sqlSpinBox->setValue(dbl_val); // AGC settings int_val = settings->value("receiver/agc_threshold", -100).toInt(&conv_ok); if (conv_ok) agcOpt->setThreshold(int_val); int_val = settings->value("receiver/agc_decay", 500).toInt(&conv_ok); if (conv_ok) { agcOpt->setDecay(int_val); if (int_val == 100) ui->agcPresetCombo->setCurrentIndex(0); else if (int_val == 500) ui->agcPresetCombo->setCurrentIndex(1); else if (int_val == 2000) ui->agcPresetCombo->setCurrentIndex(2); else ui->agcPresetCombo->setCurrentIndex(3); } int_val = settings->value("receiver/agc_slope", 0).toInt(&conv_ok); if (conv_ok) agcOpt->setSlope(int_val); int_val = settings->value("receiver/agc_gain", 0).toInt(&conv_ok); if (conv_ok) agcOpt->setGain(int_val); agcOpt->setHang(settings->value("receiver/agc_usehang", false).toBool()); if (settings->value("receiver/agc_off", false).toBool()) ui->agcPresetCombo->setCurrentIndex(4); int_val = settings->value("receiver/demod", 0).toInt(&conv_ok); if (int_val >= 0) { setCurrentDemod(int_val); emit demodSelected(int_val); } }