///////////////////////////////////////////////////////////////////// // Constructor/Destructor ///////////////////////////////////////////////////////////////////// MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); setWindowTitle(PROGRAM_TITLE_VERSION); //create SDR interface class m_pSdrInterface = new CSdrInterface; //give GUI plotter access to the sdr interface object ui->framePlot->SetSdrInterface(m_pSdrInterface); //create the global Testbench object if(!g_pTestBench) g_pTestBench = new CTestBench(this); readSettings(); //read persistent settings ui->actionAlwaysOnTop->setChecked(m_AlwaysOnTop); AlwaysOnTop(); //create Demod setup menu for non-modal use(can leave up and still access rest of program) m_pDemodSetupDlg = new CDemodSetupDlg(this); m_pTimer = new QTimer(this); //connect a bunch of signals to the GUI objects connect(m_pTimer, SIGNAL(timeout()), this, SLOT(OnTimer())); connect(ui->frameFreqCtrl, SIGNAL(NewFrequency(qint64)), this, SLOT(OnNewCenterFrequency(qint64))); connect(ui->frameDemodFreqCtrl, SIGNAL(NewFrequency(qint64)), this, SLOT(OnNewDemodFrequency(qint64))); connect(m_pSdrInterface, SIGNAL(NewStatus(int)), this, SLOT( OnStatus(int) ) ); connect(m_pSdrInterface, SIGNAL(NewInfoData()), this, SLOT( OnNewInfoData() ) ); connect(m_pSdrInterface, SIGNAL(NewFftData()), this, SLOT( OnNewFftData() ) ); connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(OnExit())); connect(ui->actionNetwork, SIGNAL(triggered()), this, SLOT(OnNetworkDlg())); connect(ui->actionSoundCard, SIGNAL(triggered()), this, SLOT(OnSoundCardDlg())); connect(ui->actionSDR, SIGNAL(triggered()), this, SLOT(OnSdrDlg())); connect(ui->actionDisplay, SIGNAL(triggered()), this, SLOT(OnDisplayDlg())); connect(ui->actionAlwaysOnTop, SIGNAL(triggered()), this, SLOT(AlwaysOnTop())); connect(ui->actionDemod_Setup, SIGNAL(triggered()), this, SLOT(OnDemodDlg())); connect(ui->actionNoise_Processing, SIGNAL(triggered()), this, SLOT(OnNoiseProcDlg())); connect(ui->actionAbout, SIGNAL(triggered()), this, SLOT(OnAbout())); connect(ui->framePlot, SIGNAL(NewDemodFreq(qint64)), this, SLOT( OnNewScreenDemodFreq(qint64) ) ); connect(ui->framePlot, SIGNAL(NewCenterFreq(qint64)), this, SLOT( OnNewScreenCenterFreq(qint64) ) ); connect(ui->framePlot, SIGNAL(NewLowCutFreq(int)), this, SLOT( OnNewLowCutFreq(int) ) ); connect(ui->framePlot, SIGNAL(NewHighCutFreq(int)), this, SLOT( OnNewHighCutFreq(int) ) ); m_pTimer->start(200); //start up status timer m_pSdrInterface->SetRadioType(m_RadioType); quint32 maxspan = m_pSdrInterface->GetMaxBWFromIndex(m_BandwidthIndex); ui->framePlot->SetPercent2DScreen(m_Percent2DScreen); //initialize controls and limits qint32 tmpspan = m_SpanFrequency; //save since setting range triggers control to update ui->SpanspinBox->setMaximum(maxspan/1000); m_SpanFrequency = tmpspan; if(m_SpanFrequency>maxspan) m_SpanFrequency = maxspan; ui->SpanspinBox->setValue(m_SpanFrequency/1000); m_LastSpanKhz = m_SpanFrequency/1000; //tmp save demod freq since gets set to center freq by center freq control inititalization qint64 tmpdemod = m_DemodFrequency; ui->frameFreqCtrl->Setup(9, 100U, 500000000U, 1, UNITS_KHZ ); ui->frameFreqCtrl->SetBkColor(Qt::darkBlue); ui->frameFreqCtrl->SetDigitColor(Qt::cyan); ui->frameFreqCtrl->SetUnitsColor(Qt::lightGray); ui->frameFreqCtrl->SetHighlightColor(Qt::darkGray); ui->frameFreqCtrl->SetFrequency(m_CenterFrequency); m_DemodFrequency = tmpdemod; ui->frameDemodFreqCtrl->Setup(9, 100U, 500000000U, 1, UNITS_KHZ ); ui->frameDemodFreqCtrl->SetBkColor(Qt::darkBlue); ui->frameDemodFreqCtrl->SetDigitColor(Qt::white); ui->frameDemodFreqCtrl->SetUnitsColor(Qt::lightGray); ui->frameDemodFreqCtrl->SetHighlightColor(Qt::darkGray); //limit demod frequency to Center Frequency +/-span frequency ui->frameDemodFreqCtrl->Setup(9, m_CenterFrequency-m_SpanFrequency/2, m_CenterFrequency+m_SpanFrequency/2, 1, UNITS_KHZ ); ui->frameDemodFreqCtrl->SetFrequency(m_DemodFrequency); ui->framePlot->SetSpanFreq( m_SpanFrequency ); ui->framePlot->SetCenterFreq( m_CenterFrequency ); ui->framePlot->SetClickResolution(m_ClickResolution); m_FreqChanged = false; ui->horizontalSliderVol->setValue(m_Volume); m_pSdrInterface->SetVolume(m_Volume); ui->ScalecomboBox->addItem("10 dB/Div", 10); ui->ScalecomboBox->addItem("5 dB/Div", 5); ui->ScalecomboBox->addItem("3 dB/Div", 3); ui->ScalecomboBox->addItem("1 dB/Div", 1); m_dBStepSize = (int)ui->ScalecomboBox->itemData(m_VertScaleIndex).toInt(); ui->ScalecomboBox->setCurrentIndex(m_VertScaleIndex); ui->framePlot->SetdBStepSize(m_dBStepSize); ui->MaxdBspinBox->setValue(m_MaxdB); ui->MaxdBspinBox->setSingleStep(m_dBStepSize); ui->MaxdBspinBox->setMinimum(MIN_FFTDB+VERT_DIVS*m_dBStepSize); ui->MaxdBspinBox->setMaximum(MAX_FFTDB); ui->framePlot->SetMaxdB(m_MaxdB); m_pSdrInterface->SetFftSize( m_FftSize); m_pSdrInterface->SetFftAve( m_FftAve); m_pSdrInterface->SetMaxDisplayRate(m_MaxDisplayRate); m_pSdrInterface->SetSdrBandwidthIndex(m_BandwidthIndex); m_pSdrInterface->SetSdrRfGain( m_RfGain ); m_pSdrInterface->ManageNCOSpurOffsets(CSdrInterface::NCOSPUR_CMD_SET, &m_NCOSpurOffsetI, &m_NCOSpurOffsetQ); m_pSdrInterface->SetSoundCardSelection(m_SoundInIndex, m_SoundOutIndex, m_StereoOut); m_pSdrInterface->SetSpectrumInversion(m_InvertSpectrum); m_pSdrInterface->SetUSFmVersion(m_USFm); InitDemodSettings(); ui->framePlot->SetDemodCenterFreq( m_DemodFrequency ); SetupDemod(m_DemodMode); m_RdsDecode.DecodeReset(m_USFm); SetupNoiseProc(); UpdateInfoBox(); m_ActiveDevice = ""; m_pSdrInterface->SetupNetwork(m_IPAdr,m_Port); m_Status = CSdrInterface::NOT_CONNECTED; m_LastStatus = m_Status; m_pSdrInterface->StartIO(); m_KeepAliveTimer = 0; if(m_UseTestBench) { //make sure top of dialog is visable(0,0 doesn't include menu bar.Qt bug?) if(m_TestBenchRect.top()<30) m_TestBenchRect.setTop(30); g_pTestBench->setGeometry(m_TestBenchRect); g_pTestBench->show(); g_pTestBench->Init(); } }
//////////////////////////////////////////////////////////////////////// // Called from worker thread with new ASCP message to parse from radio // Cannot call any QT functions since is a thread so use signals // to inform the GUI. //////////////////////////////////////////////////////////////////////// void CSdrInterface::ParseAscpMsg(CAscpMsg *pMsg) { quint16 Length; quint32 tmp32; pMsg->InitRxMsg(); //initialize receive msg object for read back if( pMsg->GetType() == TYPE_TARG_RESP_CITEM ) { // Is a message from SDR in response to a request //qDebug()<<"Msg "<<pMsg->GetCItem(); switch(pMsg->GetCItem()) { case CI_GENERAL_INTERFACE_NAME: m_DeviceName = (const char*)(&pMsg->Buf8[4]); // create radio type value from connected device string if("SDR-14" == m_DeviceName) m_RadioType = SDR14; else if("SDR-IQ" == m_DeviceName) m_RadioType = SDRIQ; else if("SDR-IP" == m_DeviceName) m_RadioType = SDRIP; if("NetSDR" == m_DeviceName) m_RadioType = NETSDR; break; case CI_GENERAL_INTERFACE_SERIALNUM: m_SerialNum = (const char*)(&pMsg->Buf8[4]); break; case CI_GENERAL_INTERFACE_VERSION: break; case CI_GENERAL_HARDFIRM_VERSION: if(pMsg->GetParm8() == 0) { m_BootRev = (float)pMsg->GetParm16()/100.0; } else { m_AppRev =(float)pMsg->GetParm16()/100.0; m_BandwidthIndex = -1; //force update of sample rate logic emit NewInfoData(); } break; case CI_RX_STATE: pMsg->GetParm8(); if(RX_STATE_ON == pMsg->GetParm8()) { emit NewStatus( RUNNING ); m_Running = true; } else { emit NewStatus( CONNECTED ); m_Running = false; } break; case CI_GENERAL_OPTIONS: break; case CI_GENERAL_SECURITY_CODE: //qDebug()<<"security = "<<pMsg->GetParm16(); break; case CI_GENERAL_STATUS_CODE: //used as keepalive ack m_KeepAliveCounter = 0; break; case CI_RX_FREQUENCY: pMsg->GetParm8(); tmp32 = pMsg->GetParm32(); break; case CI_RX_OUT_SAMPLE_RATE: pMsg->GetParm8(); m_SampleRate = (double)pMsg->GetParm32(); break; case CI_GENERAL_PRODUCT_ID: break; case CI_UPDATE_MODE_PARAMS: break; default: break; } } else if( pMsg->GetType() == TYPE_TARG_RESP_CITEM_RANGE ) { // Is a range message from SDR switch( pMsg->GetCItem() ) { case CI_RX_FREQUENCY: Length = pMsg->GetLength(); pMsg->GetParm8(); m_BaseFrequencyRangeMin = (quint64)pMsg->GetParm32(); pMsg->GetParm8(); m_BaseFrequencyRangeMax = (quint64)pMsg->GetParm32(); pMsg->GetParm8(); m_OptionFrequencyRangeMin = m_BaseFrequencyRangeMin; //set option range to base range m_OptionFrequencyRangeMax = m_BaseFrequencyRangeMax; if(Length>15) { m_OptionFrequencyRangeMin = (quint64)pMsg->GetParm32(); pMsg->GetParm8(); m_OptionFrequencyRangeMax = (quint64)pMsg->GetParm32(); } //qDebug()<<"Base range"<<m_BaseFrequencyRangeMin << m_BaseFrequencyRangeMax; //qDebug()<<"Option range"<<m_OptionFrequencyRangeMin << m_OptionFrequencyRangeMax; break; default: break; } } else if( pMsg->GetType() == TYPE_TARG_UNSOLICITED_CITEM ) { // Is an unsolicited message from SDR switch( pMsg->GetCItem() ) { case CI_GENERAL_STATUS_CODE: if( GENERAL_STATUS_ADOVERLOAD == pMsg->GetParm8() ) SendIOStatus(ADOVR); break; default: break; } } else if( pMsg->GetType() == TYPE_TARG_DATA_ITEM0 ) { } else if( pMsg->GetType() == TYPE_TARG_DATA_ITEM1 ) { } else if( pMsg->GetType() == TYPE_TARG_DATA_ITEM2 ) { } else if( pMsg->GetType() == TYPE_TARG_DATA_ITEM3 ) { } else if(pMsg->GetType() == TYPE_DATA_ITEM_ACK) { switch(pMsg->Buf8[2]) { //decode Data acks case 0: //NetSDR and SDRIP keepalive ack break; case 1: //ack of AD6620 load so ok to send next msg if any left to send if( m_AD6620.GetNext6620Msg(m_TxMsg) ) SendAscpMsg(&m_TxMsg); else qDebug()<<"AD6620 Load Complete"; break; case 2: break; case 3: break; } } }