Пример #1
0
//////////////////////////////////////////////////////////////////////
// Called to display the input pBuf.
//Called by thread so no GUI calls!
// STEREO 16 bit Data version.
//////////////////////////////////////////////////////////////////////
void CTestBench::DisplayData(int length, TYPESTEREO16* pBuf, double samplerate, int profile)
{
	if(!m_Active || (profile!=m_Profile) )
		return;
	if(m_DisplaySampleRate != samplerate)
	{
		m_DisplaySampleRate = samplerate;
		emit ResetSignal();
		return;
	}
	m_NewDataIsCpx = true;
	if(! m_TimeDisplay)
	{	//if displaying frequency domain data
		//accumulate samples into m_FftInBuf until have enough to perform an FFT
		for(int i=0; i<length; i++)
		{
			m_FftInBuf[m_FftBufPos].re = (TYPEREAL)pBuf[i].re;
			m_FftInBuf[m_FftBufPos++].im = (TYPEREAL)pBuf[i].im;
			if(m_FftBufPos >= TEST_FFTSIZE )
			{
				m_FftBufPos = 0;
				if(++m_DisplaySkipCounter >= m_DisplaySkipValue )
				{
					m_DisplaySkipCounter = 0;
					m_Fft.PutInDisplayFFT( TESTFFT_SIZE, m_FftInBuf);
					emit NewFftData();
				}
			}
		}
	}
	else
	{	//if displaying time domain data
		for(int i=0; i<length; i++)
		{
			double intime = (double)m_TimeInPos/samplerate;
			double scrntime = (double)m_TimeScrnPos*m_TimeScrnPixel;
			m_TimeInPos++;
			while(intime >= scrntime)
			{
				ChkForTrigger( (int)pBuf[i].re );
				m_TimeBuf1[m_TimeScrnPos] = pBuf[i].re;
				m_TimeBuf2[m_TimeScrnPos++] = pBuf[i].im;
				scrntime = (double)m_TimeScrnPos*m_TimeScrnPixel;
				if( m_TimeScrnPos >= m_Rect.width() )
				{
					m_TimeScrnPos = 0;
					m_TimeInPos = 0;
					break;
				}
			}

		}
	}
}
Пример #2
0
///////////////////////////////////////////////////////////////////////////////
// Called by worker thread with new I/Q data fom the SDR.
//  This thread is what is used to perform all the DSP functions
// pIQData is ptr to complex I/Q double samples.  (order is I then Q)
// Length is the number of doubles in pIQData. (2x the number of data samples)
// emits "NewFftData()" when it accumulates an entire FFT length of samples
// and the display update time is ready
///////////////////////////////////////////////////////////////////////////////
void CSdrInterface::ProcessIQData( double* pIQData, int Length)
{
	if(!m_Running)	//ignor any incoming data if not running
		return;

	g_pTestBench->CreateGeneratorSamples(Length/2, (TYPECPX*)pIQData, m_SampleRate);
	m_NoiseProc.ProcessBlanker(Length/2, (TYPECPX*)pIQData, (TYPECPX*)pIQData);

	if(m_NcoSpurCalActive)	//if performing NCO spur calibration
		NcoSpurCalibrate(pIQData, Length);
	//accumulate samples into m_DataBuf until have enough to perform an FFT
	for(int i=0; i<Length; i++)
	{
		if(m_FftBufPos&1)	//apply I/Q DC offset correction to all samples
			m_DataBuf[m_FftBufPos++] = pIQData[i] - m_NCOSpurOffsetQ;
		else
			m_DataBuf[m_FftBufPos++] = pIQData[i] - m_NCOSpurOffsetI;
		if(m_FftBufPos >= (m_FftSize*2) )
		{
			m_FftBufPos = 0;
			if(++m_DisplaySkipCounter >= m_DisplaySkipValue )
			{
				m_DisplaySkipCounter = 0;
				if(m_ScreenUpateFinished)
				{
					m_Fft.PutInDisplayFFT(m_FftSize, (TYPECPX*)m_DataBuf);
					m_ScreenUpateFinished = FALSE;
					emit NewFftData();
				}
			}
		}
	}
	TYPECPX SoundBuf[8192];
	int n;
	if(m_StereoOut)
	{
		n = m_Demodulator.ProcessData(Length/2, (TYPECPX*)pIQData, SoundBuf);
		m_pSoundCardOut->PutOutQueue(n, SoundBuf);
	}
	else
	{
		n = m_Demodulator.ProcessData(Length/2, (TYPECPX*)pIQData, (TYPEREAL*)SoundBuf);
		m_pSoundCardOut->PutOutQueue(n, (TYPEREAL*)SoundBuf);
	}
}
Пример #3
0
/////////////////////////////////////////////////////////////////////
// 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();
	}
}
Пример #4
0
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CTestBench::CTestBench(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::CTestBench)
{
	m_Active = false;
	m_2DPixmap = QPixmap(0,0);
	m_OverlayPixmap = QPixmap(0,0);
	m_Size = QSize(0,0);
	m_Rect = QRect(0,0,100,100);

	m_MaxdB = 10;
	m_MindB = -120;
	m_dBStepSize = 10;
	m_FreqUnits = 1;
	m_CenterFreq = 0;
	m_GenSampleRate = 1;
	m_DisplaySampleRate = 1;
	m_Span = m_DisplaySampleRate/2;
	m_FftBufPos = 0;

	m_GenOn = false;
	m_PeakOn = false;
	m_NewDataIsCpx = false;
	m_CurrentDataIsCpx = true;
	m_TimeDisplay = false;
	m_DisplayRate = 10;
	m_HorzSpan = 100;
	m_VertRange = 65000;
	m_TrigLevel = 100;
	m_TrigBufPos = 0;
	m_TrigCounter = 0;
	m_TrigState = TRIGSTATE_WAIT;

	m_PulseWidth = .01;
	m_PulsePeriod = .5;
	m_PulseTimer = 0.0;

	connect(this, SIGNAL(ResetSignal()), this,  SLOT( Reset() ) );
	connect(this, SIGNAL(NewFftData()), this,  SLOT( DrawFftPlot() ) );
	connect(this, SIGNAL(NewTimeData()), this,  SLOT( DrawTimePlot() ) );
	connect( this, SIGNAL( SendTxt(QString)), this, SLOT( GotTxt(QString) ) );

	m_Fft.SetFFTParams( 2048,
						FALSE,
						0.0,
						m_GenSampleRate);
	m_Fft.SetFFTAve(0);
	ui->setupUi(this);
	setWindowTitle("CuteSDR Test Bench");
	ui->textEdit->clear();
	m_pTimer = new QTimer(this);
	connect(m_pTimer, SIGNAL(timeout()), this, SLOT(OnTimer()));

#if USE_FILE	//test file reading kludge
	QDir::setCurrent("d:/");
	m_File.setFileName(FILE_NAME);
	if(m_File.open(QIODevice::ReadOnly))
	{
		qDebug()<<"file Opend OK";
		if(USE_SVFILE)
			m_File.seek(0x7e);		//SV
		else if(USE_PERSEUSFILE)
			m_File.seek(0x7A);		//perseus
	}
	else
		qDebug()<<"file Failed to Open";
#endif
}