2015-10-14 22:05:19 -04:00
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2015 F4EXB //
// written by Edouard Griffiths //
// //
// This program is free software; you can redistribute it and/or modify //
// it under the terms of the GNU General Public License as published by //
// the Free Software Foundation as version 3 of the License, or //
// //
// This program is distributed in the hope that it will be useful, //
// but WITHOUT ANY WARRANTY; without even the implied warranty of //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
// GNU General Public License V3 for more details. //
// //
// You should have received a copy of the GNU General Public License //
// along with this program. If not, see <http://www.gnu.org/licenses/>. //
///////////////////////////////////////////////////////////////////////////////////
2016-10-03 12:29:05 -04:00
# include "dspdevicesourceengine.h"
2016-10-02 16:29:04 -04:00
# include <dsp/basebandsamplesink.h>
2016-10-02 17:16:40 -04:00
# include <dsp/devicesamplesource.h>
2016-10-02 15:52:39 -04:00
# include <dsp/downchannelizer.h>
2015-10-14 22:05:19 -04:00
# include <stdio.h>
# include <QDebug>
# include "dsp/dspcommands.h"
2018-02-04 04:49:13 -05:00
# include "util/fixed.h"
2016-10-06 13:18:02 -04:00
# include "samplesinkfifo.h"
2016-10-03 09:55:16 -04:00
# include "threadedbasebandsamplesink.h"
2015-10-14 22:05:19 -04:00
2016-10-03 12:29:05 -04:00
DSPDeviceSourceEngine : : DSPDeviceSourceEngine ( uint uid , QObject * parent ) :
2015-10-14 22:05:19 -04:00
QThread ( parent ) ,
2017-05-25 14:13:34 -04:00
m_uid ( uid ) ,
2015-10-14 22:05:19 -04:00
m_state ( StNotStarted ) ,
2016-10-03 19:49:28 -04:00
m_deviceSampleSource ( 0 ) ,
2015-10-14 22:05:19 -04:00
m_sampleSourceSequence ( 0 ) ,
2016-10-03 19:49:28 -04:00
m_basebandSampleSinks ( ) ,
2015-10-14 22:05:19 -04:00
m_sampleRate ( 0 ) ,
m_centerFrequency ( 0 ) ,
m_dcOffsetCorrection ( false ) ,
m_iqImbalanceCorrection ( false ) ,
m_iOffset ( 0 ) ,
m_qOffset ( 0 ) ,
m_iRange ( 1 < < 16 ) ,
m_qRange ( 1 < < 16 ) ,
m_imbalance ( 65536 )
{
2015-10-20 20:32:21 -04:00
connect ( & m_inputMessageQueue , SIGNAL ( messageEnqueued ( ) ) , this , SLOT ( handleInputMessages ( ) ) , Qt : : QueuedConnection ) ;
connect ( & m_syncMessenger , SIGNAL ( messageSent ( ) ) , this , SLOT ( handleSynchronousMessages ( ) ) , Qt : : QueuedConnection ) ;
2015-10-14 22:05:19 -04:00
moveToThread ( this ) ;
}
2016-10-03 12:29:05 -04:00
DSPDeviceSourceEngine : : ~ DSPDeviceSourceEngine ( )
2015-10-14 22:05:19 -04:00
{
2018-02-14 05:27:57 -05:00
stop ( ) ;
wait ( ) ;
2015-10-14 22:05:19 -04:00
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : run ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::run " ;
2015-10-14 22:05:19 -04:00
m_state = StIdle ;
2018-02-14 11:33:08 -05:00
exec ( ) ;
2015-10-14 22:05:19 -04:00
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : start ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::start " ;
2015-10-14 22:05:19 -04:00
QThread : : start ( ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : stop ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::stop " ;
2017-10-03 18:50:42 -04:00
gotoIdle ( ) ;
m_state = StNotStarted ;
QThread : : exit ( ) ;
// DSPExit cmd;
// m_syncMessenger.sendWait(cmd);
2015-10-14 22:05:19 -04:00
}
2016-10-03 12:29:05 -04:00
bool DSPDeviceSourceEngine : : initAcquisition ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::initAcquisition " ;
2015-10-14 22:05:19 -04:00
DSPAcquisitionInit cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StReady ;
}
2016-10-03 12:29:05 -04:00
bool DSPDeviceSourceEngine : : startAcquisition ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::startAcquisition " ;
2015-10-14 22:05:19 -04:00
DSPAcquisitionStart cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StRunning ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : stopAcquistion ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::stopAcquistion " ;
2015-10-14 22:05:19 -04:00
DSPAcquisitionStop cmd ;
m_syncMessenger . storeMessage ( cmd ) ;
handleSynchronousMessages ( ) ;
if ( m_dcOffsetCorrection )
{
qDebug ( " DC offset:%f,%f " , m_iOffset , m_qOffset ) ;
}
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : setSource ( DeviceSampleSource * source )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::setSource " ;
2015-10-14 22:05:19 -04:00
DSPSetSource cmd ( source ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : setSourceSequence ( int sequence )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( " DSPDeviceSourceEngine::setSourceSequence: seq: %d " , sequence ) ;
2015-10-14 22:05:19 -04:00
m_sampleSourceSequence = sequence ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : addSink ( BasebandSampleSink * sink )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::addSink: " < < sink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2018-01-01 19:04:49 -05:00
DSPAddBasebandSampleSink cmd ( sink ) ;
2015-10-14 22:05:19 -04:00
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : removeSink ( BasebandSampleSink * sink )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::removeSink: " < < sink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2018-01-01 19:04:49 -05:00
DSPRemoveBasebandSampleSink cmd ( sink ) ;
2015-10-14 22:05:19 -04:00
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : addThreadedSink ( ThreadedBasebandSampleSink * sink )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::addThreadedSink: " < < sink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2018-01-01 19:04:49 -05:00
DSPAddThreadedBasebandSampleSink cmd ( sink ) ;
2015-10-14 22:05:19 -04:00
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : removeThreadedSink ( ThreadedBasebandSampleSink * sink )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::removeThreadedSink: " < < sink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2018-01-01 19:04:49 -05:00
DSPRemoveThreadedBasebandSampleSink cmd ( sink ) ;
2015-10-14 22:05:19 -04:00
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : configureCorrections ( bool dcOffsetCorrection , bool iqImbalanceCorrection )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::configureCorrections " ;
2015-10-14 22:05:19 -04:00
DSPConfigureCorrection * cmd = new DSPConfigureCorrection ( dcOffsetCorrection , iqImbalanceCorrection ) ;
m_inputMessageQueue . push ( cmd ) ;
}
2016-10-03 12:29:05 -04:00
QString DSPDeviceSourceEngine : : errorMessage ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::errorMessage " ;
2015-10-14 22:05:19 -04:00
DSPGetErrorMessage cmd ;
m_syncMessenger . sendWait ( cmd ) ;
return cmd . getErrorMessage ( ) ;
}
2016-10-03 12:29:05 -04:00
QString DSPDeviceSourceEngine : : sourceDeviceDescription ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::sourceDeviceDescription " ;
2015-10-14 22:05:19 -04:00
DSPGetSourceDeviceDescription cmd ;
m_syncMessenger . sendWait ( cmd ) ;
return cmd . getDeviceDescription ( ) ;
}
2018-01-31 20:45:55 -05:00
void DSPDeviceSourceEngine : : iqCorrections ( SampleVector : : iterator begin , SampleVector : : iterator end , bool imbalanceCorrection )
{
for ( SampleVector : : iterator it = begin ; it < end ; it + + )
{
m_iBeta ( it - > real ( ) ) ;
m_qBeta ( it - > imag ( ) ) ;
if ( imbalanceCorrection )
{
2018-02-04 12:20:16 -05:00
# if IMBALANCE_INT
// acquisition
int64_t xi = ( it - > m_real - ( int32_t ) m_iBeta ) < < 5 ;
int64_t xq = ( it - > m_imag - ( int32_t ) m_qBeta ) < < 5 ;
// phase imbalance
m_avgII ( ( xi * xi ) > > 28 ) ; // <I", I">
m_avgIQ ( ( xi * xq ) > > 28 ) ; // <I", Q">
if ( ( int64_t ) m_avgII ! = 0 )
{
int64_t phi = ( ( ( int64_t ) m_avgIQ ) < < 28 ) / ( int64_t ) m_avgII ;
m_avgPhi ( phi ) ;
}
int64_t corrPhi = ( ( ( int64_t ) m_avgPhi ) * xq ) > > 28 ; //(m_avgPhi.asDouble()/16777216.0) * ((double) xq);
int64_t yi = xi - corrPhi ;
int64_t yq = xq ;
// amplitude I/Q imbalance
m_avgII2 ( ( yi * yi ) > > 28 ) ; // <I, I>
m_avgQQ2 ( ( yq * yq ) > > 28 ) ; // <Q, Q>
if ( ( int64_t ) m_avgQQ2 ! = 0 )
{
int64_t a = ( ( ( int64_t ) m_avgII2 ) < < 28 ) / ( int64_t ) m_avgQQ2 ;
Fixed < int64_t , 28 > fA ( Fixed < int64_t , 28 > : : internal ( ) , a ) ;
Fixed < int64_t , 28 > sqrtA = sqrt ( ( Fixed < int64_t , 28 > ) fA ) ;
m_avgAmp ( sqrtA . as_internal ( ) ) ;
}
int64_t zq = ( ( ( int64_t ) m_avgAmp ) * yq ) > > 28 ;
it - > m_real = yi > > 5 ;
it - > m_imag = zq > > 5 ;
# else
2018-02-04 04:49:13 -05:00
// DC correction and conversion
float xi = ( it - > m_real - ( int32_t ) m_iBeta ) / SDR_RX_SCALEF ;
float xq = ( it - > m_imag - ( int32_t ) m_qBeta ) / SDR_RX_SCALEF ;
// phase imbalance
m_avgII ( xi * xi ) ; // <I", I">
m_avgIQ ( xi * xq ) ; // <I", Q">
if ( m_avgII . asDouble ( ) ! = 0 ) {
m_avgPhi ( m_avgIQ . asDouble ( ) / m_avgII . asDouble ( ) ) ;
}
2018-02-10 19:42:35 -05:00
float & yi = xi ; // the in phase remains the reference
float yq = xq - m_avgPhi . asDouble ( ) * xi ;
2018-02-04 04:49:13 -05:00
// amplitude I/Q imbalance
m_avgII2 ( yi * yi ) ; // <I, I>
m_avgQQ2 ( yq * yq ) ; // <Q, Q>
if ( m_avgQQ2 . asDouble ( ) ! = 0 ) {
m_avgAmp ( sqrt ( m_avgII2 . asDouble ( ) / m_avgQQ2 . asDouble ( ) ) ) ;
}
// final correction
2018-02-10 19:42:35 -05:00
float & zi = yi ; // the in phase remains the reference
2018-02-04 04:49:13 -05:00
float zq = m_avgAmp . asDouble ( ) * yq ;
// convert and store
it - > m_real = zi * SDR_RX_SCALEF ;
it - > m_imag = zq * SDR_RX_SCALEF ;
2018-02-04 12:20:16 -05:00
# endif
2018-01-31 20:45:55 -05:00
}
else
{
2018-02-04 04:49:13 -05:00
// DC correction only
2018-01-31 20:45:55 -05:00
it - > m_real - = ( int32_t ) m_iBeta ;
it - > m_imag - = ( int32_t ) m_qBeta ;
}
}
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : dcOffset ( SampleVector : : iterator begin , SampleVector : : iterator end )
2015-10-14 22:05:19 -04:00
{
// sum and correct in one pass
for ( SampleVector : : iterator it = begin ; it < end ; it + + )
{
2018-01-31 20:45:55 -05:00
m_iBeta ( it - > real ( ) ) ;
m_qBeta ( it - > imag ( ) ) ;
it - > m_real - = ( int32_t ) m_iBeta ;
it - > m_imag - = ( int32_t ) m_qBeta ;
2015-10-14 22:05:19 -04:00
}
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : imbalance ( SampleVector : : iterator begin , SampleVector : : iterator end )
2015-10-14 22:05:19 -04:00
{
int iMin = 0 ;
int iMax = 0 ;
int qMin = 0 ;
int qMax = 0 ;
// find value ranges for both I and Q
// both intervals should be same same size (for a perfect circle)
for ( SampleVector : : iterator it = begin ; it < end ; it + + )
{
if ( it ! = begin )
{
if ( it - > real ( ) < iMin ) {
iMin = it - > real ( ) ;
} else if ( it - > real ( ) > iMax ) {
iMax = it - > real ( ) ;
}
if ( it - > imag ( ) < qMin ) {
qMin = it - > imag ( ) ;
} else if ( it - > imag ( ) > qMax ) {
qMax = it - > imag ( ) ;
}
}
else
{
iMin = it - > real ( ) ;
iMax = it - > real ( ) ;
qMin = it - > imag ( ) ;
qMax = it - > imag ( ) ;
}
}
// sliding average (el cheapo again)
m_iRange = ( m_iRange * 15 + ( iMax - iMin ) ) > > 4 ;
m_qRange = ( m_qRange * 15 + ( qMax - qMin ) ) > > 4 ;
2018-01-24 18:48:11 -05:00
// calculate imbalance on 32 bit full scale
2015-10-14 22:05:19 -04:00
if ( m_qRange ! = 0 ) {
2018-01-24 18:48:11 -05:00
m_imbalance = ( ( uint ) m_iRange < < ( 32 - SDR_RX_SAMP_SZ ) ) / ( uint ) m_qRange ;
2015-10-14 22:05:19 -04:00
}
2018-01-24 18:48:11 -05:00
// correct imbalance and convert back to sample size
2015-10-14 22:05:19 -04:00
for ( SampleVector : : iterator it = begin ; it < end ; it + + ) {
2018-01-24 18:48:11 -05:00
it - > m_imag = ( it - > m_imag * m_imbalance ) > > ( 32 - SDR_RX_SAMP_SZ ) ;
2015-10-14 22:05:19 -04:00
}
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : work ( )
2015-10-14 22:05:19 -04:00
{
2016-10-06 13:18:02 -04:00
SampleSinkFifo * sampleFifo = m_deviceSampleSource - > getSampleFifo ( ) ;
2015-10-14 22:05:19 -04:00
std : : size_t samplesDone = 0 ;
bool positiveOnly = false ;
while ( ( sampleFifo - > fill ( ) > 0 ) & & ( m_inputMessageQueue . size ( ) = = 0 ) & & ( samplesDone < m_sampleRate ) )
{
SampleVector : : iterator part1begin ;
SampleVector : : iterator part1end ;
SampleVector : : iterator part2begin ;
SampleVector : : iterator part2end ;
std : : size_t count = sampleFifo - > readBegin ( sampleFifo - > fill ( ) , & part1begin , & part1end , & part2begin , & part2end ) ;
// first part of FIFO data
if ( part1begin ! = part1end )
{
// correct stuff
2018-02-04 04:49:13 -05:00
if ( m_dcOffsetCorrection )
{
iqCorrections ( part1begin , part1end , m_iqImbalanceCorrection ) ;
}
// if (m_dcOffsetCorrection)
// {
// dcOffset(part1begin, part1end);
// }
//
// if (m_iqImbalanceCorrection)
// {
// imbalance(part1begin, part1end);
// }
2015-10-14 22:05:19 -04:00
// feed data to direct sinks
2016-10-03 19:49:28 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks . begin ( ) ; it ! = m_basebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
( * it ) - > feed ( part1begin , part1end , positiveOnly ) ;
}
// feed data to threaded sinks
2016-10-03 19:49:28 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks . begin ( ) ; it ! = m_threadedBasebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
( * it ) - > feed ( part1begin , part1end , positiveOnly ) ;
}
}
// second part of FIFO data (used when block wraps around)
if ( part2begin ! = part2end )
{
// correct stuff
2018-02-04 04:49:13 -05:00
if ( m_dcOffsetCorrection )
{
iqCorrections ( part2begin , part2end , m_iqImbalanceCorrection ) ;
}
// if (m_dcOffsetCorrection)
// {
// dcOffset(part2begin, part2end);
// }
//
// if (m_iqImbalanceCorrection)
// {
// imbalance(part2begin, part2end);
// }
2015-10-14 22:05:19 -04:00
// feed data to direct sinks
2016-10-03 19:49:28 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks . begin ( ) ; it ! = m_basebandSampleSinks . end ( ) ; it + + )
2015-10-14 22:05:19 -04:00
{
( * it ) - > feed ( part2begin , part2end , positiveOnly ) ;
}
// feed data to threaded sinks
2016-10-03 19:49:28 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks . begin ( ) ; it ! = m_threadedBasebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
( * it ) - > feed ( part2begin , part2end , positiveOnly ) ;
}
}
// adjust FIFO pointers
sampleFifo - > readCommit ( ( unsigned int ) count ) ;
samplesDone + = count ;
}
}
// notStarted -> idle -> init -> running -+
// ^ |
// +-----------------------+
2016-10-03 12:29:05 -04:00
DSPDeviceSourceEngine : : State DSPDeviceSourceEngine : : gotoIdle ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoIdle " ;
2015-10-14 22:05:19 -04:00
switch ( m_state ) {
case StNotStarted :
return StNotStarted ;
case StIdle :
case StError :
return StIdle ;
case StReady :
case StRunning :
break ;
}
2016-10-03 19:49:28 -04:00
if ( m_deviceSampleSource = = 0 )
2015-10-14 22:05:19 -04:00
{
return StIdle ;
}
// stop everything
2016-10-03 19:49:28 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks . begin ( ) ; it ! = m_basebandSampleSinks . end ( ) ; it + + )
2015-10-14 22:05:19 -04:00
{
( * it ) - > stop ( ) ;
}
2016-10-17 16:40:02 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks . begin ( ) ; it ! = m_threadedBasebandSampleSinks . end ( ) ; it + + )
{
( * it ) - > stop ( ) ;
}
2016-10-17 12:15:08 -04:00
2016-10-03 19:49:28 -04:00
m_deviceSampleSource - > stop ( ) ;
2015-10-14 22:05:19 -04:00
m_deviceDescription . clear ( ) ;
m_sampleRate = 0 ;
return StIdle ;
}
2016-10-03 12:29:05 -04:00
DSPDeviceSourceEngine : : State DSPDeviceSourceEngine : : gotoInit ( )
2015-10-14 22:05:19 -04:00
{
switch ( m_state ) {
case StNotStarted :
return StNotStarted ;
case StRunning : // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
return StRunning ;
case StReady :
return StReady ;
case StIdle :
case StError :
break ;
}
2016-10-03 19:49:28 -04:00
if ( m_deviceSampleSource = = 0 )
2015-10-14 22:05:19 -04:00
{
return gotoError ( " No sample source configured " ) ;
}
// init: pass sample rate and center frequency to all sample rate and/or center frequency dependent sinks and wait for completion
m_iOffset = 0 ;
m_qOffset = 0 ;
m_iRange = 1 < < 16 ;
m_qRange = 1 < < 16 ;
2016-10-03 19:49:28 -04:00
m_deviceDescription = m_deviceSampleSource - > getDeviceDescription ( ) ;
m_centerFrequency = m_deviceSampleSource - > getCenterFrequency ( ) ;
m_sampleRate = m_deviceSampleSource - > getSampleRate ( ) ;
2015-10-14 22:05:19 -04:00
2017-12-25 03:10:19 -05:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoInit: "
< < " m_deviceDescription: " < < m_deviceDescription . toStdString ( ) . c_str ( )
2015-10-14 22:05:19 -04:00
< < " sampleRate: " < < m_sampleRate
< < " centerFrequency: " < < m_centerFrequency ;
DSPSignalNotification notif ( m_sampleRate , m_centerFrequency ) ;
2016-10-03 19:49:28 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks . begin ( ) ; it ! = m_basebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoInit: initializing " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2015-10-14 22:05:19 -04:00
( * it ) - > handleMessage ( notif ) ;
}
2016-10-03 19:49:28 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks . begin ( ) ; it ! = m_threadedBasebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoInit: initializing ThreadedSampleSink( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
2015-10-14 22:05:19 -04:00
( * it ) - > handleSinkMessage ( notif ) ;
}
// pass data to listeners
2017-09-17 11:35:03 -04:00
if ( m_deviceSampleSource - > getMessageQueueToGUI ( ) )
{
DSPSignalNotification * rep = new DSPSignalNotification ( notif ) ; // make a copy for the output queue
m_deviceSampleSource - > getMessageQueueToGUI ( ) - > push ( rep ) ;
}
2015-10-14 22:05:19 -04:00
return StReady ;
}
2016-10-03 12:29:05 -04:00
DSPDeviceSourceEngine : : State DSPDeviceSourceEngine : : gotoRunning ( )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoRunning " ;
2015-10-14 22:05:19 -04:00
switch ( m_state )
{
case StNotStarted :
return StNotStarted ;
case StIdle :
return StIdle ;
case StRunning :
return StRunning ;
case StReady :
case StError :
break ;
}
2016-10-03 19:49:28 -04:00
if ( m_deviceSampleSource = = NULL ) {
2016-10-08 04:35:07 -04:00
return gotoError ( " DSPDeviceSourceEngine::gotoRunning: No sample source configured " ) ;
2015-10-14 22:05:19 -04:00
}
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoRunning: " < < m_deviceDescription . toStdString ( ) . c_str ( ) < < " started " ;
2015-10-14 22:05:19 -04:00
// Start everything
2017-04-13 21:40:45 -04:00
if ( ! m_deviceSampleSource - > start ( ) )
2015-10-14 22:05:19 -04:00
{
return gotoError ( " Could not start sample source " ) ;
}
2016-10-03 19:49:28 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks . begin ( ) ; it ! = m_basebandSampleSinks . end ( ) ; it + + )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoRunning: starting " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2015-10-14 22:05:19 -04:00
( * it ) - > start ( ) ;
}
2016-10-03 19:49:28 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks . begin ( ) ; it ! = m_threadedBasebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoRunning: starting ThreadedSampleSink( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
2015-10-14 22:05:19 -04:00
( * it ) - > start ( ) ;
}
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoRunning:input message queue pending: " < < m_inputMessageQueue . size ( ) ;
2015-10-14 22:05:19 -04:00
return StRunning ;
}
2016-10-03 12:29:05 -04:00
DSPDeviceSourceEngine : : State DSPDeviceSourceEngine : : gotoError ( const QString & errorMessage )
2015-10-14 22:05:19 -04:00
{
2016-11-15 20:38:21 -05:00
qDebug ( ) < < " DSPDeviceSourceEngine::gotoError: " < < errorMessage ;
2015-10-14 22:05:19 -04:00
m_errorMessage = errorMessage ;
m_deviceDescription . clear ( ) ;
m_state = StError ;
return StError ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : handleSetSource ( DeviceSampleSource * source )
2015-10-14 22:05:19 -04:00
{
gotoIdle ( ) ;
2016-05-19 18:49:55 -04:00
// if(m_sampleSource != 0)
// {
// disconnect(m_sampleSource->getSampleFifo(), SIGNAL(dataReady()), this, SLOT(handleData()));
// }
2015-10-14 22:05:19 -04:00
2016-10-03 19:49:28 -04:00
m_deviceSampleSource = source ;
2015-10-14 22:05:19 -04:00
2016-10-03 19:49:28 -04:00
if ( m_deviceSampleSource ! = 0 )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( " DSPDeviceSourceEngine::handleSetSource: set %s " , qPrintable ( source - > getDeviceDescription ( ) ) ) ;
2016-10-03 19:49:28 -04:00
connect ( m_deviceSampleSource - > getSampleFifo ( ) , SIGNAL ( dataReady ( ) ) , this , SLOT ( handleData ( ) ) , Qt : : QueuedConnection ) ;
2015-10-14 22:05:19 -04:00
}
else
{
2016-10-08 04:35:07 -04:00
qDebug ( " DSPDeviceSourceEngine::handleSetSource: set none " ) ;
2015-10-14 22:05:19 -04:00
}
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : handleData ( )
2015-10-14 22:05:19 -04:00
{
if ( m_state = = StRunning )
{
work ( ) ;
}
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : handleSynchronousMessages ( )
2015-10-14 22:05:19 -04:00
{
Message * message = m_syncMessenger . getMessage ( ) ;
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::handleSynchronousMessages: " < < message - > getIdentifier ( ) ;
2015-10-14 22:05:19 -04:00
2018-02-14 11:33:08 -05:00
if ( DSPAcquisitionInit : : match ( * message ) )
2015-10-14 22:05:19 -04:00
{
m_state = gotoIdle ( ) ;
if ( m_state = = StIdle ) {
m_state = gotoInit ( ) ; // State goes ready if init is performed
}
}
else if ( DSPAcquisitionStart : : match ( * message ) )
{
if ( m_state = = StReady ) {
m_state = gotoRunning ( ) ;
}
}
else if ( DSPAcquisitionStop : : match ( * message ) )
{
m_state = gotoIdle ( ) ;
}
else if ( DSPGetSourceDeviceDescription : : match ( * message ) )
{
( ( DSPGetSourceDeviceDescription * ) message ) - > setDeviceDescription ( m_deviceDescription ) ;
}
else if ( DSPGetErrorMessage : : match ( * message ) )
{
( ( DSPGetErrorMessage * ) message ) - > setErrorMessage ( m_errorMessage ) ;
}
else if ( DSPSetSource : : match ( * message ) ) {
handleSetSource ( ( ( DSPSetSource * ) message ) - > getSampleSource ( ) ) ;
}
2018-01-01 19:04:49 -05:00
else if ( DSPAddBasebandSampleSink : : match ( * message ) )
2015-10-14 22:05:19 -04:00
{
2018-01-01 19:04:49 -05:00
BasebandSampleSink * sink = ( ( DSPAddBasebandSampleSink * ) message ) - > getSampleSink ( ) ;
2016-10-03 19:49:28 -04:00
m_basebandSampleSinks . push_back ( sink ) ;
2018-01-02 10:25:34 -05:00
// initialize sample rate and center frequency in the sink:
DSPSignalNotification msg ( m_sampleRate , m_centerFrequency ) ;
sink - > handleMessage ( msg ) ;
// start the sink:
if ( m_state = = StRunning ) {
sink - > start ( ) ;
}
2015-10-14 22:05:19 -04:00
}
2018-01-01 19:04:49 -05:00
else if ( DSPRemoveBasebandSampleSink : : match ( * message ) )
2015-10-14 22:05:19 -04:00
{
2018-01-01 19:04:49 -05:00
BasebandSampleSink * sink = ( ( DSPRemoveBasebandSampleSink * ) message ) - > getSampleSink ( ) ;
2015-10-14 22:05:19 -04:00
if ( m_state = = StRunning ) {
sink - > stop ( ) ;
}
2016-10-03 19:49:28 -04:00
m_basebandSampleSinks . remove ( sink ) ;
2015-10-14 22:05:19 -04:00
}
2018-01-01 19:04:49 -05:00
else if ( DSPAddThreadedBasebandSampleSink : : match ( * message ) )
2015-10-14 22:05:19 -04:00
{
2018-01-01 19:04:49 -05:00
ThreadedBasebandSampleSink * threadedSink = ( ( DSPAddThreadedBasebandSampleSink * ) message ) - > getThreadedSampleSink ( ) ;
2016-10-03 19:49:28 -04:00
m_threadedBasebandSampleSinks . push_back ( threadedSink ) ;
2017-02-14 15:46:35 -05:00
// initialize sample rate and center frequency in the sink:
DSPSignalNotification msg ( m_sampleRate , m_centerFrequency ) ;
threadedSink - > handleSinkMessage ( msg ) ;
// start the sink:
2018-01-02 10:25:34 -05:00
if ( m_state = = StRunning ) {
threadedSink - > start ( ) ;
}
2015-10-14 22:05:19 -04:00
}
2018-01-01 19:04:49 -05:00
else if ( DSPRemoveThreadedBasebandSampleSink : : match ( * message ) )
2015-10-14 22:05:19 -04:00
{
2018-01-01 19:04:49 -05:00
ThreadedBasebandSampleSink * threadedSink = ( ( DSPRemoveThreadedBasebandSampleSink * ) message ) - > getThreadedSampleSink ( ) ;
2015-10-14 22:05:19 -04:00
threadedSink - > stop ( ) ;
2016-10-03 19:49:28 -04:00
m_threadedBasebandSampleSinks . remove ( threadedSink ) ;
2015-10-14 22:05:19 -04:00
}
m_syncMessenger . done ( m_state ) ;
}
2016-10-03 12:29:05 -04:00
void DSPDeviceSourceEngine : : handleInputMessages ( )
2015-10-14 22:05:19 -04:00
{
Message * message ;
while ( ( message = m_inputMessageQueue . pop ( ) ) ! = 0 )
{
2016-10-08 04:35:07 -04:00
qDebug ( " DSPDeviceSourceEngine::handleInputMessages: message: %s " , message - > getIdentifier ( ) ) ;
2015-10-14 22:05:19 -04:00
if ( DSPConfigureCorrection : : match ( * message ) )
{
DSPConfigureCorrection * conf = ( DSPConfigureCorrection * ) message ;
m_iqImbalanceCorrection = conf - > getIQImbalanceCorrection ( ) ;
if ( m_dcOffsetCorrection ! = conf - > getDCOffsetCorrection ( ) )
{
m_dcOffsetCorrection = conf - > getDCOffsetCorrection ( ) ;
m_iOffset = 0 ;
m_qOffset = 0 ;
}
if ( m_iqImbalanceCorrection ! = conf - > getIQImbalanceCorrection ( ) )
{
m_iqImbalanceCorrection = conf - > getIQImbalanceCorrection ( ) ;
m_iRange = 1 < < 16 ;
m_qRange = 1 < < 16 ;
m_imbalance = 65536 ;
}
2018-02-15 19:23:49 -05:00
m_avgAmp . reset ( ) ;
m_avgII . reset ( ) ;
m_avgII2 . reset ( ) ;
m_avgIQ . reset ( ) ;
m_avgPhi . reset ( ) ;
m_avgQQ2 . reset ( ) ;
m_iBeta . reset ( ) ;
m_qBeta . reset ( ) ;
2015-10-14 22:05:19 -04:00
delete message ;
}
else if ( DSPSignalNotification : : match ( * message ) )
{
DSPSignalNotification * notif = ( DSPSignalNotification * ) message ;
// update DSP values
m_sampleRate = notif - > getSampleRate ( ) ;
m_centerFrequency = notif - > getCenterFrequency ( ) ;
2019-01-04 04:49:47 -05:00
qDebug ( ) < < " DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: "
< < " m_sampleRate: " < < m_sampleRate
< < " m_centerFrequency: " < < m_centerFrequency ;
2015-10-14 22:05:19 -04:00
2017-09-16 18:06:09 -04:00
// forward source changes to channel sinks with immediate execution (no queuing)
2015-10-14 22:05:19 -04:00
2016-10-03 19:49:28 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks . begin ( ) ; it ! = m_basebandSampleSinks . end ( ) ; it + + )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::handleInputMessages: forward message to " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2015-10-14 22:05:19 -04:00
( * it ) - > handleMessage ( * message ) ;
}
2016-10-03 19:49:28 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks . begin ( ) ; it ! = m_threadedBasebandSampleSinks . end ( ) ; + + it )
2015-10-14 22:05:19 -04:00
{
2016-10-08 04:35:07 -04:00
qDebug ( ) < < " DSPDeviceSourceEngine::handleSourceMessages: forward message to ThreadedSampleSink( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
2015-10-14 22:05:19 -04:00
( * it ) - > handleSinkMessage ( * message ) ;
}
2017-09-16 18:06:09 -04:00
// forward changes to source GUI input queue
2015-10-14 22:05:19 -04:00
2017-09-16 18:06:09 -04:00
MessageQueue * guiMessageQueue = m_deviceSampleSource - > getMessageQueueToGUI ( ) ;
2017-12-25 03:10:19 -05:00
qDebug ( " DSPDeviceSourceEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p " , guiMessageQueue ) ;
2017-09-16 18:06:09 -04:00
if ( guiMessageQueue ) {
DSPSignalNotification * rep = new DSPSignalNotification ( * notif ) ; // make a copy for the source GUI
2019-01-04 04:49:47 -05:00
guiMessageQueue - > push ( rep ) ;
2017-09-16 18:06:09 -04:00
}
//m_outputMessageQueue.push(rep);
2015-10-14 22:05:19 -04:00
delete message ;
}
}
}