2019-05-12 19:55:12 -04:00
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 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 //
// (at your option) any later version. //
// //
// 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/>. //
///////////////////////////////////////////////////////////////////////////////////
# include <QDebug>
2019-09-03 23:00:22 -04:00
# include "dspcommands.h"
2019-05-12 19:55:12 -04:00
# include "threadedbasebandsamplesource.h"
# include "threadedbasebandsamplesink.h"
# include "devicesamplemimo.h"
2019-09-03 23:00:22 -04:00
# include "mimochannel.h"
2019-05-12 19:55:12 -04:00
# include "dspdevicemimoengine.h"
2019-05-15 12:51:10 -04:00
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : SetSampleMIMO , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : AddThreadedBasebandSampleSource , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : RemoveThreadedBasebandSampleSource , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : AddThreadedBasebandSampleSink , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : RemoveThreadedBasebandSampleSink , Message )
2019-09-03 23:00:22 -04:00
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : AddMIMOChannel , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : RemoveMIMOChannel , Message )
2019-05-15 12:51:10 -04:00
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : AddBasebandSampleSink , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : RemoveBasebandSampleSink , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : AddSpectrumSink , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : RemoveSpectrumSink , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : GetErrorMessage , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : GetMIMODeviceDescription , Message )
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : ConfigureCorrection , Message )
2019-05-19 04:23:18 -04:00
MESSAGE_CLASS_DEFINITION ( DSPDeviceMIMOEngine : : SetSpectrumSinkInput , Message )
2019-05-15 12:51:10 -04:00
2019-05-12 19:55:12 -04:00
DSPDeviceMIMOEngine : : DSPDeviceMIMOEngine ( uint32_t uid , QObject * parent ) :
QThread ( parent ) ,
m_uid ( uid ) ,
2019-10-20 14:05:01 -04:00
m_stateRx ( StNotStarted ) ,
m_stateTx ( StNotStarted ) ,
2019-05-19 04:23:18 -04:00
m_deviceSampleMIMO ( nullptr ) ,
m_spectrumInputSourceElseSink ( true ) ,
m_spectrumInputIndex ( 0 )
2019-05-12 19:55:12 -04:00
{
connect ( & m_inputMessageQueue , SIGNAL ( messageEnqueued ( ) ) , this , SLOT ( handleInputMessages ( ) ) , Qt : : QueuedConnection ) ;
connect ( & m_syncMessenger , SIGNAL ( messageSent ( ) ) , this , SLOT ( handleSynchronousMessages ( ) ) , Qt : : QueuedConnection ) ;
moveToThread ( this ) ;
}
DSPDeviceMIMOEngine : : ~ DSPDeviceMIMOEngine ( )
{
stop ( ) ;
wait ( ) ;
}
void DSPDeviceMIMOEngine : : run ( )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::run " ;
2019-10-20 14:05:01 -04:00
m_stateRx = StIdle ;
m_stateTx = StIdle ;
2019-05-12 19:55:12 -04:00
exec ( ) ;
}
void DSPDeviceMIMOEngine : : start ( )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::start " ;
QThread : : start ( ) ;
}
void DSPDeviceMIMOEngine : : stop ( )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::stop " ;
2019-10-20 14:05:01 -04:00
gotoIdle ( 0 ) ; // Rx
gotoIdle ( 1 ) ; // Tx
m_stateRx = StNotStarted ;
m_stateTx = StNotStarted ;
2019-05-12 19:55:12 -04:00
QThread : : exit ( ) ;
}
2019-10-20 14:05:01 -04:00
bool DSPDeviceMIMOEngine : : initProcess ( int subsystemIndex )
2019-05-12 19:55:12 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::initProcess: subsystemIndex: " < < subsystemIndex ;
2019-05-12 19:55:12 -04:00
2019-10-20 14:05:01 -04:00
if ( subsystemIndex = = 0 ) // Rx side
{
DSPAcquisitionInit cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StReady ;
}
else if ( subsystemIndex = = 1 ) // Tx side
{
DSPGenerationInit cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StReady ;
}
2019-05-12 19:55:12 -04:00
}
2019-10-20 14:05:01 -04:00
bool DSPDeviceMIMOEngine : : startProcess ( int subsystemIndex )
2019-05-12 19:55:12 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::startProcess: subsystemIndex: " < < subsystemIndex ;
if ( subsystemIndex = = 0 ) // Rx side
{
DSPAcquisitionStart cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StRunning ;
}
else if ( subsystemIndex = = 1 ) // Tx side
{
DSPGenerationStart cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StRunning ;
}
2019-05-12 19:55:12 -04:00
}
2019-10-20 14:05:01 -04:00
void DSPDeviceMIMOEngine : : stopProcess ( int subsystemIndex )
2019-05-12 19:55:12 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::stopProcess: subsystemIndex: " < < subsystemIndex ;
if ( subsystemIndex = = 0 ) // Rx side
{
DSPAcquisitionStop cmd ;
m_syncMessenger . storeMessage ( cmd ) ;
}
else if ( subsystemIndex = = 1 ) // Tx side
{
DSPGenerationStop cmd ;
m_syncMessenger . storeMessage ( cmd ) ;
}
2019-05-12 19:55:12 -04:00
handleSynchronousMessages ( ) ;
}
void DSPDeviceMIMOEngine : : setMIMO ( DeviceSampleMIMO * mimo )
{
2019-05-18 05:59:56 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::setMIMO " ;
2019-05-12 19:55:12 -04:00
SetSampleMIMO cmd ( mimo ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : setMIMOSequence ( int sequence )
{
qDebug ( " DSPDeviceMIMOEngine::setSinkSequence: seq: %d " , sequence ) ;
m_sampleMIMOSequence = sequence ;
}
void DSPDeviceMIMOEngine : : addChannelSource ( ThreadedBasebandSampleSource * source , int index )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::addThreadedSource: "
< < source - > objectName ( ) . toStdString ( ) . c_str ( )
< < " at: "
< < index ;
AddThreadedBasebandSampleSource cmd ( source , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : removeChannelSource ( ThreadedBasebandSampleSource * source , int index )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::removeThreadedSource: "
< < source - > objectName ( ) . toStdString ( ) . c_str ( )
< < " at: "
< < index ;
RemoveThreadedBasebandSampleSource cmd ( source , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : addChannelSink ( ThreadedBasebandSampleSink * sink , int index )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::addThreadedSink: "
< < sink - > objectName ( ) . toStdString ( ) . c_str ( )
< < " at: "
< < index ;
AddThreadedBasebandSampleSink cmd ( sink , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : removeChannelSink ( ThreadedBasebandSampleSink * sink , int index )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::removeThreadedSink: "
< < sink - > objectName ( ) . toStdString ( ) . c_str ( )
< < " at: "
< < index ;
RemoveThreadedBasebandSampleSink cmd ( sink , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
2019-09-03 23:00:22 -04:00
void DSPDeviceMIMOEngine : : addMIMOChannel ( MIMOChannel * channel )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::addMIMOChannel: "
< < channel - > objectName ( ) . toStdString ( ) . c_str ( ) ;
AddMIMOChannel cmd ( channel ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : removeMIMOChannel ( MIMOChannel * channel )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::removeMIMOChannel: "
< < channel - > objectName ( ) . toStdString ( ) . c_str ( ) ;
RemoveMIMOChannel cmd ( channel ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
2019-05-12 19:55:12 -04:00
void DSPDeviceMIMOEngine : : addAncillarySink ( BasebandSampleSink * sink , int index )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::addSink: "
< < sink - > objectName ( ) . toStdString ( ) . c_str ( )
< < " at: "
< < index ;
AddBasebandSampleSink cmd ( sink , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : removeAncillarySink ( BasebandSampleSink * sink , int index )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::removeSink: "
< < sink - > objectName ( ) . toStdString ( ) . c_str ( )
< < " at: "
< < index ;
RemoveBasebandSampleSink cmd ( sink , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : addSpectrumSink ( BasebandSampleSink * spectrumSink )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::addSpectrumSink: " < < spectrumSink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
AddSpectrumSink cmd ( spectrumSink ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceMIMOEngine : : removeSpectrumSink ( BasebandSampleSink * spectrumSink )
{
qDebug ( ) < < " DSPDeviceSinkEngine::removeSpectrumSink: " < < spectrumSink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPRemoveSpectrumSink cmd ( spectrumSink ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
2019-05-19 04:23:18 -04:00
void DSPDeviceMIMOEngine : : setSpectrumSinkInput ( bool sourceElseSink , int index )
{
qDebug ( ) < < " DSPDeviceSinkEngine::setSpectrumSinkInput: "
< < " sourceElseSink: " < < sourceElseSink
< < " index: " < < index ;
SetSpectrumSinkInput cmd ( sourceElseSink , index ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
2019-10-20 14:05:01 -04:00
QString DSPDeviceMIMOEngine : : errorMessage ( int subsystemIndex )
2019-05-12 19:55:12 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::errorMessage: subsystemIndex: " < < subsystemIndex ;
GetErrorMessage cmd ( subsystemIndex ) ;
2019-05-12 19:55:12 -04:00
m_syncMessenger . sendWait ( cmd ) ;
return cmd . getErrorMessage ( ) ;
}
QString DSPDeviceMIMOEngine : : deviceDescription ( )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::deviceDescription " ;
2019-05-15 12:51:10 -04:00
GetMIMODeviceDescription cmd ;
2019-05-12 19:55:12 -04:00
m_syncMessenger . sendWait ( cmd ) ;
return cmd . getDeviceDescription ( ) ;
}
2019-09-25 12:39:17 -04:00
void DSPDeviceMIMOEngine : : workSampleSinkFifos ( )
2019-09-10 12:44:43 -04:00
{
2019-09-25 12:39:17 -04:00
SampleMIFifo * sampleFifo = m_deviceSampleMIMO - > getSampleMIFifo ( ) ;
2019-09-10 12:44:43 -04:00
if ( ! sampleFifo ) {
return ;
}
2019-10-02 19:19:43 -04:00
unsigned int iPart1Begin ;
unsigned int iPart1End ;
unsigned int iPart2Begin ;
unsigned int iPart2End ;
const std : : vector < SampleVector > & data = sampleFifo - > getData ( ) ;
//unsigned int samplesDone = 0;
while ( ( sampleFifo - > fillSync ( ) > 0 ) & & ( m_inputMessageQueue . size ( ) = = 0 ) )
2019-09-25 12:39:17 -04:00
{
2019-10-02 19:19:43 -04:00
//unsigned int count = sampleFifo->readSync(sampleFifo->fillSync(), iPart1Begin, iPart1End, iPart2Begin, iPart2End);
sampleFifo - > readSync ( iPart1Begin , iPart1End , iPart2Begin , iPart2End ) ;
2019-09-25 12:39:17 -04:00
2019-10-02 19:19:43 -04:00
if ( iPart1Begin ! = iPart1End )
2019-09-25 12:39:17 -04:00
{
2019-10-02 19:19:43 -04:00
for ( unsigned int stream = 0 ; stream < data . size ( ) ; stream + + ) {
2019-10-18 23:07:24 -04:00
workSamplesSink ( data [ stream ] . begin ( ) + iPart1Begin , data [ stream ] . begin ( ) + iPart1End , stream ) ;
2019-09-25 12:39:17 -04:00
}
2019-10-02 19:19:43 -04:00
}
2019-09-25 12:39:17 -04:00
2019-10-02 19:19:43 -04:00
if ( iPart2Begin ! = iPart2End )
{
for ( unsigned int stream = 0 ; stream < data . size ( ) ; stream + + ) {
2019-10-18 23:07:24 -04:00
workSamplesSink ( data [ stream ] . begin ( ) + iPart2Begin , data [ stream ] . begin ( ) + iPart2End , stream ) ;
2019-09-25 12:39:17 -04:00
}
}
}
2019-09-10 12:44:43 -04:00
}
2019-10-18 23:07:24 -04:00
void DSPDeviceMIMOEngine : : workSampleSourceFifos ( )
{
SampleMOFifo * sampleFifo = m_deviceSampleMIMO - > getSampleMOFifo ( ) ;
if ( ! sampleFifo ) {
return ;
}
std : : vector < SampleVector : : const_iterator > vbegin ;
vbegin . resize ( sampleFifo - > getNbStreams ( ) ) ;
2019-10-20 14:05:01 -04:00
unsigned int amount = sampleFifo - > remainderSync ( ) ;
2019-10-18 23:07:24 -04:00
2019-10-20 14:05:01 -04:00
while ( ( amount > 0 ) & & ( m_inputMessageQueue . size ( ) = = 0 ) )
2019-10-18 23:07:24 -04:00
{
// pull remainderSync() samples from the sources by stream
for ( unsigned int streamIndex = 0 ; streamIndex < sampleFifo - > getNbStreams ( ) ; streamIndex + + ) {
2019-10-20 14:05:01 -04:00
workSamplesSource ( vbegin [ streamIndex ] , amount , streamIndex ) ;
2019-10-18 23:07:24 -04:00
}
// write pulled samples to FIFO
2019-10-20 14:05:01 -04:00
sampleFifo - > writeSync ( vbegin , amount ) ;
// get new amount
amount = sampleFifo - > remainderSync ( ) ;
2019-10-18 23:07:24 -04:00
}
}
void DSPDeviceMIMOEngine : : workSampleSinkFifo ( unsigned int streamIndex )
2019-09-10 12:44:43 -04:00
{
2019-09-25 12:39:17 -04:00
SampleMIFifo * sampleFifo = m_deviceSampleMIMO - > getSampleMIFifo ( ) ;
2019-09-10 12:44:43 -04:00
if ( ! sampleFifo ) {
return ;
}
2019-09-25 12:39:17 -04:00
SampleVector : : const_iterator part1begin ;
SampleVector : : const_iterator part1end ;
SampleVector : : const_iterator part2begin ;
SampleVector : : const_iterator part2end ;
2019-09-10 12:44:43 -04:00
2019-10-18 23:07:24 -04:00
while ( ( sampleFifo - > fillAsync ( streamIndex ) > 0 ) & & ( m_inputMessageQueue . size ( ) = = 0 ) )
2019-09-25 12:39:17 -04:00
{
2019-10-02 19:19:43 -04:00
//unsigned int count = sampleFifo->readAsync(sampleFifo->fillAsync(stream), &part1begin, &part1end, &part2begin, &part2end, stream);
2019-10-18 23:07:24 -04:00
sampleFifo - > readAsync ( & part1begin , & part1end , & part2begin , & part2end , streamIndex ) ;
2019-09-10 12:44:43 -04:00
if ( part1begin ! = part1end ) { // first part of FIFO data
2019-10-18 23:07:24 -04:00
workSamplesSink ( part1begin , part1end , streamIndex ) ;
2019-09-10 12:44:43 -04:00
}
if ( part2begin ! = part2end ) { // second part of FIFO data (used when block wraps around)
2019-10-18 23:07:24 -04:00
workSamplesSink ( part2begin , part2end , streamIndex ) ;
2019-09-10 12:44:43 -04:00
}
}
}
2019-10-18 23:07:24 -04:00
void DSPDeviceMIMOEngine : : workSampleSourceFifo ( unsigned int streamIndex )
{
SampleMOFifo * sampleFifo = m_deviceSampleMIMO - > getSampleMOFifo ( ) ;
if ( ! sampleFifo ) {
return ;
}
SampleVector : : const_iterator begin ;
2019-10-20 14:05:01 -04:00
unsigned int amount = sampleFifo - > remainderAsync ( streamIndex ) ;
2019-10-18 23:07:24 -04:00
2019-10-20 14:05:01 -04:00
while ( ( amount > 0 ) & & ( m_inputMessageQueue . size ( ) = = 0 ) )
2019-10-18 23:07:24 -04:00
{
// pull remainderAsync() samples from the sources stream
2019-10-20 14:05:01 -04:00
workSamplesSource ( begin , amount , streamIndex ) ;
2019-10-18 23:07:24 -04:00
// write pulled samples to FIFO's corresponding stream
2019-10-20 14:05:01 -04:00
sampleFifo - > writeAsync ( begin , amount , streamIndex ) ;
// get new amount
amount = sampleFifo - > remainderAsync ( streamIndex ) ;
2019-10-18 23:07:24 -04:00
}
}
2019-05-12 19:55:12 -04:00
/**
* Routes samples from device source FIFO to sink channels that are registered for the FIFO
* Routes samples from source channels registered for the FIFO to the device sink FIFO
*/
2019-10-22 12:38:02 -04:00
void DSPDeviceMIMOEngine : : workSamplesSink ( const SampleVector : : const_iterator & vbegin , const SampleVector : : const_iterator & vend , unsigned int streamIndex )
2019-05-26 20:52:33 -04:00
{
bool positiveOnly = false ;
2019-08-24 18:45:36 -04:00
// DC and IQ corrections
2019-10-22 12:38:02 -04:00
// if (m_sourcesCorrections[streamIndex].m_dcOffsetCorrection) {
// iqCorrections(vbegin, vend, streamIndex, m_sourcesCorrections[streamIndex].m_iqImbalanceCorrection);
2019-10-01 20:05:33 -04:00
// }
2019-05-26 20:52:33 -04:00
2019-08-24 18:45:36 -04:00
// feed data to direct sinks
2019-10-22 12:38:02 -04:00
if ( streamIndex < m_basebandSampleSinks . size ( ) )
2019-08-24 18:45:36 -04:00
{
2019-10-22 12:38:02 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks [ streamIndex ] . begin ( ) ; it ! = m_basebandSampleSinks [ streamIndex ] . end ( ) ; + + it ) {
2019-08-24 18:45:36 -04:00
( * it ) - > feed ( vbegin , vend , positiveOnly ) ;
}
}
2019-05-26 20:52:33 -04:00
2019-08-24 18:45:36 -04:00
// possibly feed data to spectrum sink
2019-10-22 12:38:02 -04:00
if ( ( m_spectrumSink ) & & ( m_spectrumInputSourceElseSink ) & & ( streamIndex = = m_spectrumInputIndex ) ) {
2019-08-24 18:45:36 -04:00
m_spectrumSink - > feed ( vbegin , vend , positiveOnly ) ;
}
2019-05-26 20:52:33 -04:00
2019-08-24 18:45:36 -04:00
// feed data to threaded sinks
2019-10-22 12:38:02 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks [ streamIndex ] . begin ( ) ; it ! = m_threadedBasebandSampleSinks [ streamIndex ] . end ( ) ; + + it )
2019-08-24 18:45:36 -04:00
{
( * it ) - > feed ( vbegin , vend , positiveOnly ) ;
}
2019-09-07 04:44:40 -04:00
// feed data to MIMO channels
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it ) {
2019-10-22 12:38:02 -04:00
( * it ) - > feed ( vbegin , vend , streamIndex ) ;
2019-09-07 04:44:40 -04:00
}
2019-05-26 20:52:33 -04:00
}
2019-10-18 23:07:24 -04:00
void DSPDeviceMIMOEngine : : workSamplesSource ( SampleVector : : const_iterator & begin , unsigned int nbSamples , unsigned int streamIndex )
{
if ( m_threadedBasebandSampleSources [ streamIndex ] . size ( ) = = 0 )
{
2019-10-20 14:05:01 -04:00
m_sourceZeroBuffers [ streamIndex ] . allocate ( nbSamples , Sample { 0 , 0 } ) ;
begin = m_sourceZeroBuffers [ streamIndex ] . m_vector . begin ( ) ;
2019-10-18 23:07:24 -04:00
}
else if ( m_threadedBasebandSampleSources [ streamIndex ] . size ( ) = = 1 )
{
ThreadedBasebandSampleSource * sampleSource = m_threadedBasebandSampleSources [ streamIndex ] . front ( ) ;
sampleSource - > getSampleSourceFifo ( ) . readAdvance ( begin , nbSamples ) ;
begin - = nbSamples ;
}
else
{
SampleVector : : const_iterator sourceBegin ;
ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources [ streamIndex ] . begin ( ) ;
ThreadedBasebandSampleSource * sampleSource = * it ;
sampleSource - > getSampleSourceFifo ( ) . readAdvance ( sourceBegin , nbSamples ) ;
sourceBegin - = nbSamples ;
m_sourceSampleBuffers [ streamIndex ] . allocate ( nbSamples ) ;
std : : copy ( sourceBegin , sourceBegin + nbSamples , m_sourceSampleBuffers [ streamIndex ] . m_vector . begin ( ) ) ;
+ + it ;
for ( ; it ! = m_threadedBasebandSampleSources [ streamIndex ] . end ( ) ; + + it )
{
sampleSource = * it ;
sampleSource - > getSampleSourceFifo ( ) . readAdvance ( sourceBegin , nbSamples ) ;
sourceBegin - = nbSamples ;
std : : transform (
m_sourceSampleBuffers [ streamIndex ] . m_vector . begin ( ) ,
m_sourceSampleBuffers [ streamIndex ] . m_vector . begin ( ) + nbSamples ,
sourceBegin ,
m_sourceSampleBuffers [ streamIndex ] . m_vector . begin ( ) ,
[ ] ( Sample & a , const Sample & b ) - > Sample {
return Sample { a . real ( ) + b . real ( ) , a . imag ( ) + b . imag ( ) } ;
}
) ;
}
begin = m_sourceSampleBuffers [ streamIndex ] . m_vector . begin ( ) ;
}
2019-10-20 18:58:15 -04:00
2019-10-22 12:38:02 -04:00
// pull data from MIMO channels
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it ) {
( * it ) - > pull ( begin , nbSamples , streamIndex ) ;
}
2019-10-20 18:58:15 -04:00
// possibly feed data to spectrum sink
if ( ( m_spectrumSink ) & & ( ! m_spectrumInputSourceElseSink ) & & ( streamIndex = = m_spectrumInputIndex ) ) {
m_spectrumSink - > feed ( begin , begin + nbSamples , false ) ;
}
2019-10-18 23:07:24 -04:00
}
2019-05-15 02:33:13 -04:00
// notStarted -> idle -> init -> running -+
// ^ |
// +-----------------------+
2019-10-20 14:05:01 -04:00
DSPDeviceMIMOEngine : : State DSPDeviceMIMOEngine : : gotoIdle ( int subsystemIndex )
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoIdle: subsystemIndex: " < < subsystemIndex ;
2019-05-15 02:33:13 -04:00
2019-05-18 05:59:56 -04:00
if ( ! m_deviceSampleMIMO ) {
2019-05-15 02:33:13 -04:00
return StIdle ;
}
2019-10-20 14:05:01 -04:00
if ( subsystemIndex = = 0 ) // Rx
{
switch ( m_stateRx ) {
case StNotStarted :
return StNotStarted ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StIdle :
case StError :
return StIdle ;
2019-10-06 03:54:07 -04:00
2019-10-20 14:05:01 -04:00
case StReady :
case StRunning :
break ;
}
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
m_deviceSampleMIMO - > stopRx ( ) ; // stop everything
std : : vector < BasebandSampleSinks > : : const_iterator vbit = m_basebandSampleSinks . begin ( ) ;
for ( ; vbit ! = m_basebandSampleSinks . end ( ) ; + + vbit )
2019-09-07 04:44:40 -04:00
{
2019-10-20 14:05:01 -04:00
for ( BasebandSampleSinks : : const_iterator it = vbit - > begin ( ) ; it ! = vbit - > end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoIdle: stopping BasebandSampleSink: " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > stop ( ) ;
}
2019-05-15 02:33:13 -04:00
}
2019-10-20 14:05:01 -04:00
std : : vector < ThreadedBasebandSampleSinks > : : const_iterator vtSinkIt = m_threadedBasebandSampleSinks . begin ( ) ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
for ( ; vtSinkIt ! = m_threadedBasebandSampleSinks . end ( ) ; vtSinkIt + + )
{
for ( ThreadedBasebandSampleSinks : : const_iterator it = vtSinkIt - > begin ( ) ; it ! = vtSinkIt - > end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoIdle: stopping ThreadedBasebandSampleSource( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > stop ( ) ;
}
}
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it )
2019-09-07 04:44:40 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoIdle: stopping MIMOChannel sinks: " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > stopSinks ( ) ;
2019-05-15 02:33:13 -04:00
}
}
2019-10-20 14:05:01 -04:00
else if ( subsystemIndex = = 1 ) // Tx
{
switch ( m_stateTx ) {
case StNotStarted :
return StNotStarted ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StIdle :
case StError :
return StIdle ;
2019-09-07 04:44:40 -04:00
2019-10-20 14:05:01 -04:00
case StReady :
case StRunning :
break ;
}
m_deviceSampleMIMO - > stopTx ( ) ; // stop everything
std : : vector < ThreadedBasebandSampleSources > : : const_iterator vtSourceIt = m_threadedBasebandSampleSources . begin ( ) ;
for ( ; vtSourceIt ! = m_threadedBasebandSampleSources . end ( ) ; vtSourceIt + + )
2019-09-07 04:44:40 -04:00
{
2019-10-20 14:05:01 -04:00
for ( ThreadedBasebandSampleSources : : const_iterator it = vtSourceIt - > begin ( ) ; it ! = vtSourceIt - > end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoIdle: stopping ThreadedBasebandSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > stop ( ) ;
}
2019-09-07 04:44:40 -04:00
}
2019-10-20 14:05:01 -04:00
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoIdle: stopping MIMOChannel sources: " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > stopSources ( ) ;
}
}
else
2019-09-07 04:44:40 -04:00
{
2019-10-20 14:05:01 -04:00
return StIdle ;
2019-09-07 04:44:40 -04:00
}
2019-05-15 02:33:13 -04:00
m_deviceDescription . clear ( ) ;
return StIdle ;
}
2019-10-20 14:05:01 -04:00
DSPDeviceMIMOEngine : : State DSPDeviceMIMOEngine : : gotoInit ( int subsystemIndex )
2019-05-15 02:33:13 -04:00
{
2019-05-18 05:59:56 -04:00
if ( ! m_deviceSampleMIMO ) {
2019-10-20 14:05:01 -04:00
return gotoError ( subsystemIndex , " No sample MIMO configured " ) ;
2019-05-15 02:33:13 -04:00
}
m_deviceDescription = m_deviceSampleMIMO - > getDeviceDescription ( ) ;
2019-09-07 04:44:40 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoInit: "
2019-10-20 14:05:01 -04:00
< < " subsystemIndex: " < < subsystemIndex
2019-09-07 04:44:40 -04:00
< < " m_deviceDescription: " < < m_deviceDescription . toStdString ( ) . c_str ( ) ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
if ( subsystemIndex = = 0 ) // Rx
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
switch ( m_stateRx ) {
case StNotStarted :
return StNotStarted ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StRunning : // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
return StRunning ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StReady :
return StReady ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StIdle :
case StError :
break ;
}
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
// init: pass sample rate and center frequency to all sample rate and/or center frequency dependent sinks and wait for completion
for ( unsigned int isource = 0 ; isource < m_deviceSampleMIMO - > getNbSourceStreams ( ) ; isource + + )
2019-05-19 04:23:18 -04:00
{
2019-10-20 14:05:01 -04:00
if ( isource < m_sourcesCorrections . size ( ) )
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
m_sourcesCorrections [ isource ] . m_iOffset = 0 ;
m_sourcesCorrections [ isource ] . m_qOffset = 0 ;
m_sourcesCorrections [ isource ] . m_iRange = 1 < < 16 ;
m_sourcesCorrections [ isource ] . m_qRange = 1 < < 16 ;
2019-05-15 02:33:13 -04:00
}
2019-10-20 14:05:01 -04:00
quint64 sourceCenterFrequency = m_deviceSampleMIMO - > getSourceCenterFrequency ( isource ) ;
int sourceStreamSampleRate = m_deviceSampleMIMO - > getSourceSampleRate ( isource ) ;
qDebug ( " DSPDeviceMIMOEngine::gotoInit: m_sourceCenterFrequencies[%d] = %llu " , isource , sourceCenterFrequency ) ;
qDebug ( " DSPDeviceMIMOEngine::gotoInit: m_sourceStreamSampleRates[%d] = %d " , isource , sourceStreamSampleRate ) ;
DSPSignalNotification notif ( sourceStreamSampleRate , sourceCenterFrequency ) ;
if ( isource < m_basebandSampleSinks . size ( ) )
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks [ isource ] . begin ( ) ; it ! = m_basebandSampleSinks [ isource ] . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoInit: initializing " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > handleMessage ( notif ) ;
}
2019-05-15 02:33:13 -04:00
}
2019-05-19 04:23:18 -04:00
2019-10-20 14:05:01 -04:00
if ( isource < m_threadedBasebandSampleSinks . size ( ) )
{
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks [ isource ] . begin ( ) ; it ! = m_threadedBasebandSampleSinks [ isource ] . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoInit: initializing ThreadedSampleSink( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > handleSinkMessage ( notif ) ;
}
}
}
}
else if ( subsystemIndex = = 1 ) // Tx
{
switch ( m_stateTx ) {
case StNotStarted :
return StNotStarted ;
2019-05-19 06:54:22 -04:00
2019-10-20 14:05:01 -04:00
case StRunning : // FIXME: assumes it goes first through idle state. Could we get back to init from running directly?
return StRunning ;
2019-05-19 06:54:22 -04:00
2019-10-20 14:05:01 -04:00
case StReady :
return StReady ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StIdle :
case StError :
break ;
}
2019-05-19 04:23:18 -04:00
2019-10-20 14:05:01 -04:00
for ( unsigned int isink = 0 ; isink < m_deviceSampleMIMO - > getNbSinkStreams ( ) ; isink + + )
{
quint64 sinkCenterFrequency = m_deviceSampleMIMO - > getSinkCenterFrequency ( isink ) ;
int sinkStreamSampleRate = m_deviceSampleMIMO - > getSinkSampleRate ( isink ) ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
qDebug ( " DSPDeviceMIMOEngine::gotoInit: m_sinkCenterFrequencies[%d] = %llu " , isink , sinkCenterFrequency ) ;
qDebug ( " DSPDeviceMIMOEngine::gotoInit: m_sinkStreamSampleRates[%d] = %d " , isink , sinkStreamSampleRate ) ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
DSPSignalNotification notif ( sinkStreamSampleRate , sinkCenterFrequency ) ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
if ( isink < m_threadedBasebandSampleSources . size ( ) )
{
for ( ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources [ isink ] . begin ( ) ; it ! = m_threadedBasebandSampleSources [ isink ] . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoInit: initializing ThreadedSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > handleSourceMessage ( notif ) ;
}
}
}
}
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
return StReady ;
}
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
DSPDeviceMIMOEngine : : State DSPDeviceMIMOEngine : : gotoRunning ( int subsystemIndex )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: subsystemIndex: " < < subsystemIndex ;
2019-05-15 02:33:13 -04:00
if ( ! m_deviceSampleMIMO ) {
2019-10-20 14:05:01 -04:00
return gotoError ( subsystemIndex , " DSPDeviceMIMOEngine::gotoRunning: No sample source configured " ) ;
2019-05-15 02:33:13 -04:00
}
2019-09-07 04:44:40 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: " < < m_deviceDescription . toStdString ( ) . c_str ( ) < < " started " ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
if ( subsystemIndex = = 0 ) // Rx
{
switch ( m_stateRx )
{
case StNotStarted :
return StNotStarted ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StIdle :
return StIdle ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StRunning :
return StRunning ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
case StReady :
case StError :
break ;
}
if ( ! m_deviceSampleMIMO - > startRx ( ) ) { // Start everything
return gotoError ( 0 , " Could not start sample source " ) ;
}
std : : vector < BasebandSampleSinks > : : const_iterator vbit = m_basebandSampleSinks . begin ( ) ;
for ( ; vbit ! = m_basebandSampleSinks . end ( ) ; + + vbit )
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
for ( BasebandSampleSinks : : const_iterator it = vbit - > begin ( ) ; it ! = vbit - > end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: starting BasebandSampleSink: " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > start ( ) ;
}
2019-05-15 02:33:13 -04:00
}
2019-10-20 14:05:01 -04:00
std : : vector < ThreadedBasebandSampleSinks > : : const_iterator vtSinkIt = m_threadedBasebandSampleSinks . begin ( ) ;
2019-09-07 04:44:40 -04:00
2019-10-20 14:05:01 -04:00
for ( ; vtSinkIt ! = m_threadedBasebandSampleSinks . end ( ) ; vtSinkIt + + )
2019-09-07 04:44:40 -04:00
{
2019-10-20 14:05:01 -04:00
for ( ThreadedBasebandSampleSinks : : const_iterator it = vtSinkIt - > begin ( ) ; it ! = vtSinkIt - > end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: starting ThreadedBasebandSampleSink( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > start ( ) ;
}
2019-09-07 04:44:40 -04:00
}
2019-10-20 14:05:01 -04:00
std : : vector < ThreadedBasebandSampleSources > : : const_iterator vtSourceIt = m_threadedBasebandSampleSources . begin ( ) ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
for ( ; vtSourceIt ! = m_threadedBasebandSampleSources . end ( ) ; vtSourceIt + + )
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
for ( ThreadedBasebandSampleSources : : const_iterator it = vtSourceIt - > begin ( ) ; it ! = vtSourceIt - > end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: starting ThreadedBasebandSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > start ( ) ;
}
2019-05-15 02:33:13 -04:00
}
2019-10-20 14:05:01 -04:00
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: starting MIMOChannel sinks: " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > startSinks ( ) ;
}
}
else if ( subsystemIndex = = 1 ) // Tx
2019-09-07 04:44:40 -04:00
{
2019-10-20 14:05:01 -04:00
switch ( m_stateTx )
{
case StNotStarted :
return StNotStarted ;
case StIdle :
return StIdle ;
case StRunning :
return StRunning ;
case StReady :
case StError :
break ;
}
if ( ! m_deviceSampleMIMO - > startTx ( ) ) { // Start everything
return gotoError ( 1 , " Could not start sample sink " ) ;
}
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning: starting MIMOChannel sources: " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > startSources ( ) ;
}
2019-09-07 04:44:40 -04:00
}
2019-05-15 02:33:13 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoRunning:input message queue pending: " < < m_inputMessageQueue . size ( ) ;
return StRunning ;
}
2019-10-20 14:05:01 -04:00
DSPDeviceMIMOEngine : : State DSPDeviceMIMOEngine : : gotoError ( int subsystemIndex , const QString & errorMessage )
2019-05-15 02:33:13 -04:00
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::gotoError: "
< < " subsystemIndex: " < < subsystemIndex
< < " errorMessage: " < < errorMessage ;
2019-05-15 02:33:13 -04:00
2019-10-20 14:05:01 -04:00
if ( subsystemIndex = = 0 )
{
m_errorMessageRx = errorMessage ;
m_stateRx = StError ;
}
else if ( subsystemIndex = = 1 )
{
m_errorMessageTx = errorMessage ;
m_stateTx = StError ;
}
return StError ;
2019-05-15 02:33:13 -04:00
}
2019-05-15 12:51:10 -04:00
2019-08-13 20:56:15 -04:00
void DSPDeviceMIMOEngine : : handleDataRxSync ( )
2019-05-15 12:51:10 -04:00
{
2019-10-20 14:05:01 -04:00
if ( m_stateRx = = StRunning ) {
2019-09-25 12:39:17 -04:00
workSampleSinkFifos ( ) ;
2019-08-13 20:56:15 -04:00
}
}
2019-10-18 23:07:24 -04:00
void DSPDeviceMIMOEngine : : handleDataRxAsync ( int streamIndex )
{
2019-10-20 14:05:01 -04:00
if ( m_stateRx = = StRunning ) {
2019-10-18 23:07:24 -04:00
workSampleSinkFifo ( streamIndex ) ;
}
}
void DSPDeviceMIMOEngine : : handleDataTxSync ( )
2019-08-13 20:56:15 -04:00
{
2019-10-20 14:05:01 -04:00
if ( m_stateTx = = StRunning ) {
2019-10-18 23:07:24 -04:00
workSampleSourceFifos ( ) ;
}
}
void DSPDeviceMIMOEngine : : handleDataTxAsync ( int streamIndex )
{
2019-10-20 14:05:01 -04:00
if ( m_stateTx = = StRunning ) {
2019-10-18 23:07:24 -04:00
workSampleSourceFifo ( streamIndex ) ;
2019-05-15 12:51:10 -04:00
}
}
void DSPDeviceMIMOEngine : : handleSetMIMO ( DeviceSampleMIMO * mimo )
{
2019-05-18 05:59:56 -04:00
m_deviceSampleMIMO = mimo ;
2019-08-13 20:56:15 -04:00
if ( ! mimo ) { // Early leave
return ;
}
for ( int i = 0 ; i < m_deviceSampleMIMO - > getNbSinkFifos ( ) ; i + + )
{
m_basebandSampleSinks . push_back ( BasebandSampleSinks ( ) ) ;
m_threadedBasebandSampleSinks . push_back ( ThreadedBasebandSampleSinks ( ) ) ;
m_sourcesCorrections . push_back ( SourceCorrection ( ) ) ;
}
2019-10-18 23:07:24 -04:00
for ( int i = 0 ; i < m_deviceSampleMIMO - > getNbSourceFifos ( ) ; i + + )
{
2019-08-13 20:56:15 -04:00
m_threadedBasebandSampleSources . push_back ( ThreadedBasebandSampleSources ( ) ) ;
2019-10-18 23:07:24 -04:00
m_sourceSampleBuffers . push_back ( IncrementalVector < Sample > ( ) ) ;
2019-10-20 14:05:01 -04:00
m_sourceZeroBuffers . push_back ( IncrementalVector < Sample > ( ) ) ;
2019-08-13 20:56:15 -04:00
}
if ( m_deviceSampleMIMO - > getMIMOType ( ) = = DeviceSampleMIMO : : MIMOHalfSynchronous ) // synchronous FIFOs on Rx and not with Tx
2019-05-15 12:51:10 -04:00
{
2019-08-13 20:56:15 -04:00
qDebug ( " DSPDeviceMIMOEngine::handleSetMIMO: synchronous sources set %s " , qPrintable ( mimo - > getDeviceDescription ( ) ) ) ;
// connect(m_deviceSampleMIMO->getSampleSinkFifo(m_sampleSinkConnectionIndexes[0]), SIGNAL(dataReady()), this, SLOT(handleData()), Qt::QueuedConnection);
2019-09-25 12:39:17 -04:00
QObject : : connect (
m_deviceSampleMIMO - > getSampleMIFifo ( ) ,
& SampleMIFifo : : dataSyncReady ,
this ,
& DSPDeviceMIMOEngine : : handleDataRxSync ,
Qt : : QueuedConnection
) ;
2019-10-18 23:07:24 -04:00
QObject : : connect (
m_deviceSampleMIMO - > getSampleMOFifo ( ) ,
& SampleMOFifo : : dataSyncRead ,
this ,
& DSPDeviceMIMOEngine : : handleDataTxSync ,
Qt : : QueuedConnection
) ;
2019-08-13 20:56:15 -04:00
}
else if ( m_deviceSampleMIMO - > getMIMOType ( ) = = DeviceSampleMIMO : : MIMOAsynchronous ) // asynchronous FIFOs
{
2019-09-25 12:39:17 -04:00
for ( unsigned int stream = 0 ; stream < m_deviceSampleMIMO - > getNbSourceStreams ( ) ; stream + + )
2019-05-26 20:52:33 -04:00
{
2019-08-13 20:56:15 -04:00
qDebug ( " DSPDeviceMIMOEngine::handleSetMIMO: asynchronous sources set %s channel %u " ,
2019-09-25 12:39:17 -04:00
qPrintable ( mimo - > getDeviceDescription ( ) ) , stream ) ;
2019-08-13 20:56:15 -04:00
QObject : : connect (
2019-09-25 12:39:17 -04:00
m_deviceSampleMIMO - > getSampleMIFifo ( ) ,
& SampleMIFifo : : dataAsyncReady ,
2019-08-13 20:56:15 -04:00
this ,
2019-09-25 12:39:17 -04:00
& DSPDeviceMIMOEngine : : handleDataRxAsync ,
2019-08-13 20:56:15 -04:00
Qt : : QueuedConnection
) ;
2019-10-18 23:07:24 -04:00
QObject : : connect (
m_deviceSampleMIMO - > getSampleMOFifo ( ) ,
& SampleMOFifo : : dataAsyncRead ,
this ,
& DSPDeviceMIMOEngine : : handleDataTxAsync ,
Qt : : QueuedConnection
) ;
2019-09-25 12:39:17 -04:00
// QObject::connect(
// m_deviceSampleMIMO->getSampleSinkFifo(stream),
// &SampleSinkFifo::dataReady,
// this,
// [=](){ this->handleDataRxAsync(stream); },
// Qt::QueuedConnection
// );
2019-05-26 20:52:33 -04:00
}
2019-05-15 12:51:10 -04:00
}
}
void DSPDeviceMIMOEngine : : handleSynchronousMessages ( )
{
Message * message = m_syncMessenger . getMessage ( ) ;
qDebug ( ) < < " DSPDeviceMIMOEngine::handleSynchronousMessages: " < < message - > getIdentifier ( ) ;
2019-10-20 14:05:01 -04:00
State returnState = StNotStarted ;
2019-05-15 12:51:10 -04:00
2019-10-20 14:05:01 -04:00
if ( DSPAcquisitionInit : : match ( * message ) )
2019-05-15 12:51:10 -04:00
{
2019-10-20 14:05:01 -04:00
m_stateRx = gotoIdle ( 0 ) ;
if ( m_stateRx = = StIdle ) {
m_stateRx = gotoInit ( 0 ) ; // State goes ready if init is performed
}
2019-05-15 12:51:10 -04:00
2019-10-20 14:05:01 -04:00
returnState = m_stateRx ;
}
else if ( DSPAcquisitionStart : : match ( * message ) )
{
if ( m_stateRx = = StReady ) {
m_stateRx = gotoRunning ( 0 ) ;
2019-05-15 12:51:10 -04:00
}
2019-10-20 14:05:01 -04:00
returnState = m_stateRx ;
}
else if ( DSPAcquisitionStop : : match ( * message ) )
{
m_stateRx = gotoIdle ( 0 ) ;
returnState = m_stateRx ;
}
else if ( DSPGenerationInit : : match ( * message ) )
{
m_stateTx = gotoIdle ( 1 ) ;
if ( m_stateTx = = StIdle ) {
m_stateTx = gotoInit ( 1 ) ; // State goes ready if init is performed
}
returnState = m_stateTx ;
2019-05-15 12:51:10 -04:00
}
else if ( DSPGenerationStart : : match ( * message ) )
{
2019-10-20 14:05:01 -04:00
if ( m_stateTx = = StReady ) {
m_stateTx = gotoRunning ( 1 ) ;
2019-05-15 12:51:10 -04:00
}
2019-10-20 14:05:01 -04:00
returnState = m_stateTx ;
2019-05-15 12:51:10 -04:00
}
else if ( DSPGenerationStop : : match ( * message ) )
{
2019-10-20 14:05:01 -04:00
m_stateTx = gotoIdle ( 1 ) ;
returnState = m_stateTx ;
2019-05-15 12:51:10 -04:00
}
else if ( GetMIMODeviceDescription : : match ( * message ) )
{
( ( GetMIMODeviceDescription * ) message ) - > setDeviceDescription ( m_deviceDescription ) ;
}
2019-10-20 14:05:01 -04:00
else if ( GetErrorMessage : : match ( * message ) )
2019-05-15 12:51:10 -04:00
{
2019-10-20 14:05:01 -04:00
GetErrorMessage * cmd = ( GetErrorMessage * ) message ;
int subsystemIndex = cmd - > getSubsystemIndex ( ) ;
if ( subsystemIndex = = 0 ) {
cmd - > setErrorMessage ( m_errorMessageRx ) ;
} else if ( subsystemIndex = = 1 ) {
cmd - > setErrorMessage ( m_errorMessageTx ) ;
} else {
cmd - > setErrorMessage ( " Not implemented " ) ;
}
2019-05-15 12:51:10 -04:00
}
else if ( SetSampleMIMO : : match ( * message ) ) {
handleSetMIMO ( ( ( SetSampleMIMO * ) message ) - > getSampleMIMO ( ) ) ;
}
else if ( AddBasebandSampleSink : : match ( * message ) )
{
const AddBasebandSampleSink * msg = ( AddBasebandSampleSink * ) message ;
BasebandSampleSink * sink = msg - > getSampleSink ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int isource = msg - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
2019-05-19 06:54:22 -04:00
if ( isource < m_basebandSampleSinks . size ( ) )
2019-05-15 12:51:10 -04:00
{
m_basebandSampleSinks [ isource ] . push_back ( sink ) ;
// initialize sample rate and center frequency in the sink:
2019-05-19 04:23:18 -04:00
int sourceStreamSampleRate = m_deviceSampleMIMO - > getSourceSampleRate ( isource ) ;
quint64 sourceCenterFrequency = m_deviceSampleMIMO - > getSourceCenterFrequency ( isource ) ;
DSPSignalNotification msg ( sourceStreamSampleRate , sourceCenterFrequency ) ;
2019-05-15 12:51:10 -04:00
sink - > handleMessage ( msg ) ;
// start the sink:
2019-10-20 14:05:01 -04:00
if ( m_stateRx = = StRunning ) {
2019-05-15 12:51:10 -04:00
sink - > start ( ) ;
}
}
}
else if ( RemoveBasebandSampleSink : : match ( * message ) )
{
const RemoveBasebandSampleSink * msg = ( RemoveBasebandSampleSink * ) message ;
BasebandSampleSink * sink = ( ( DSPRemoveBasebandSampleSink * ) message ) - > getSampleSink ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int isource = msg - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
if ( isource < m_basebandSampleSinks . size ( ) )
{
2019-10-20 14:05:01 -04:00
if ( m_stateRx = = StRunning ) {
2019-05-15 12:51:10 -04:00
sink - > stop ( ) ;
}
m_basebandSampleSinks [ isource ] . remove ( sink ) ;
}
}
else if ( AddThreadedBasebandSampleSink : : match ( * message ) )
{
const AddThreadedBasebandSampleSink * msg = ( AddThreadedBasebandSampleSink * ) message ;
ThreadedBasebandSampleSink * threadedSink = msg - > getThreadedSampleSink ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int isource = msg - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
2019-05-19 06:54:22 -04:00
if ( isource < m_threadedBasebandSampleSinks . size ( ) )
2019-05-15 12:51:10 -04:00
{
m_threadedBasebandSampleSinks [ isource ] . push_back ( threadedSink ) ;
// initialize sample rate and center frequency in the sink:
2019-05-19 04:23:18 -04:00
int sourceStreamSampleRate = m_deviceSampleMIMO - > getSourceSampleRate ( isource ) ;
quint64 sourceCenterFrequency = m_deviceSampleMIMO - > getSourceCenterFrequency ( isource ) ;
DSPSignalNotification msg ( sourceStreamSampleRate , sourceCenterFrequency ) ;
2019-05-15 12:51:10 -04:00
threadedSink - > handleSinkMessage ( msg ) ;
// start the sink:
2019-10-20 14:05:01 -04:00
if ( m_stateRx = = StRunning ) {
2019-05-15 12:51:10 -04:00
threadedSink - > start ( ) ;
}
}
}
else if ( RemoveThreadedBasebandSampleSink : : match ( * message ) )
{
const RemoveThreadedBasebandSampleSink * msg = ( RemoveThreadedBasebandSampleSink * ) message ;
ThreadedBasebandSampleSink * threadedSink = msg - > getThreadedSampleSink ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int isource = msg - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
if ( isource < m_threadedBasebandSampleSinks . size ( ) )
{
threadedSink - > stop ( ) ;
m_threadedBasebandSampleSinks [ isource ] . remove ( threadedSink ) ;
}
}
else if ( AddThreadedBasebandSampleSource : : match ( * message ) )
{
const AddThreadedBasebandSampleSource * msg = ( AddThreadedBasebandSampleSource * ) message ;
ThreadedBasebandSampleSource * threadedSource = msg - > getThreadedSampleSource ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int isink = msg - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
2019-05-19 06:54:22 -04:00
if ( isink < m_threadedBasebandSampleSources . size ( ) )
2019-05-15 12:51:10 -04:00
{
m_threadedBasebandSampleSources [ isink ] . push_back ( threadedSource ) ;
// initialize sample rate and center frequency in the sink:
2019-05-19 04:23:18 -04:00
int sinkStreamSampleRate = m_deviceSampleMIMO - > getSinkSampleRate ( isink ) ;
quint64 sinkCenterFrequency = m_deviceSampleMIMO - > getSinkCenterFrequency ( isink ) ;
DSPSignalNotification msg ( sinkStreamSampleRate , sinkCenterFrequency ) ;
2019-05-15 12:51:10 -04:00
threadedSource - > handleSourceMessage ( msg ) ;
// start the sink:
2019-10-20 14:05:01 -04:00
if ( m_stateTx = = StRunning ) {
2019-05-15 12:51:10 -04:00
threadedSource - > start ( ) ;
}
}
}
else if ( RemoveThreadedBasebandSampleSource : : match ( * message ) )
{
const RemoveThreadedBasebandSampleSource * msg = ( RemoveThreadedBasebandSampleSource * ) message ;
ThreadedBasebandSampleSource * threadedSource = msg - > getThreadedSampleSource ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int isink = msg - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
if ( isink < m_threadedBasebandSampleSources . size ( ) )
{
threadedSource - > stop ( ) ;
m_threadedBasebandSampleSources [ isink ] . remove ( threadedSource ) ;
}
}
2019-09-03 23:00:22 -04:00
else if ( AddMIMOChannel : : match ( * message ) )
{
const AddMIMOChannel * msg = ( AddMIMOChannel * ) message ;
MIMOChannel * channel = msg - > getChannel ( ) ;
m_mimoChannels . push_back ( channel ) ;
for ( int isource = 0 ; isource < m_deviceSampleMIMO - > getNbSourceStreams ( ) ; isource + + )
{
DSPMIMOSignalNotification notif (
m_deviceSampleMIMO - > getSourceSampleRate ( isource ) ,
m_deviceSampleMIMO - > getSourceCenterFrequency ( isource ) ,
true ,
isource
) ;
channel - > handleMessage ( notif ) ;
}
for ( int isink = 0 ; isink < m_deviceSampleMIMO - > getNbSinkStreams ( ) ; isink + + )
{
DSPMIMOSignalNotification notif (
2019-10-20 14:05:01 -04:00
m_deviceSampleMIMO - > getSinkSampleRate ( isink ) ,
m_deviceSampleMIMO - > getSinkCenterFrequency ( isink ) ,
2019-09-03 23:00:22 -04:00
false ,
isink
) ;
channel - > handleMessage ( notif ) ;
}
2019-10-20 14:05:01 -04:00
if ( m_stateRx = = StRunning ) {
channel - > startSinks ( ) ;
}
if ( m_stateTx = = StRunning ) {
channel - > startSources ( ) ;
2019-09-03 23:00:22 -04:00
}
}
else if ( RemoveMIMOChannel : : match ( * message ) )
{
const RemoveMIMOChannel * msg = ( RemoveMIMOChannel * ) message ;
MIMOChannel * channel = msg - > getChannel ( ) ;
2019-10-20 14:05:01 -04:00
channel - > stopSinks ( ) ;
channel - > stopSources ( ) ;
2019-09-03 23:00:22 -04:00
m_mimoChannels . remove ( channel ) ;
}
2019-05-19 04:23:18 -04:00
else if ( AddSpectrumSink : : match ( * message ) )
{
m_spectrumSink = ( ( AddSpectrumSink * ) message ) - > getSampleSink ( ) ;
}
else if ( RemoveSpectrumSink : : match ( * message ) )
{
BasebandSampleSink * spectrumSink = ( ( DSPRemoveSpectrumSink * ) message ) - > getSampleSink ( ) ;
spectrumSink - > stop ( ) ;
2019-10-16 18:58:36 -04:00
// if (!m_spectrumInputSourceElseSink && m_deviceSampleMIMO && (m_spectrumInputIndex < m_deviceSampleMIMO->getNbSinkStreams()))
// {
// SampleSourceFifo *inputFIFO = m_deviceSampleMIMO->getSampleSourceFifo(m_spectrumInputIndex);
// disconnect(inputFIFO, SIGNAL(dataRead(int)), this, SLOT(handleForwardToSpectrumSink(int)));
// }
2019-05-19 04:23:18 -04:00
m_spectrumSink = nullptr ;
}
else if ( SetSpectrumSinkInput : : match ( * message ) )
{
const SetSpectrumSinkInput * msg = ( SetSpectrumSinkInput * ) message ;
bool spectrumInputSourceElseSink = msg - > getSourceElseSink ( ) ;
unsigned int spectrumInputIndex = msg - > getIndex ( ) ;
if ( ( spectrumInputSourceElseSink ! = m_spectrumInputSourceElseSink ) | | ( spectrumInputIndex ! = m_spectrumInputIndex ) )
{
2019-10-16 18:58:36 -04:00
// if (!m_spectrumInputSourceElseSink) // remove the source listener
// {
// SampleSourceFifo *inputFIFO = m_deviceSampleMIMO->getSampleSourceFifo(m_spectrumInputIndex);
// disconnect(inputFIFO, SIGNAL(dataRead(int)), this, SLOT(handleForwardToSpectrumSink(int)));
// }
2019-05-19 04:23:18 -04:00
if ( ( ! spectrumInputSourceElseSink ) & & ( spectrumInputIndex < m_deviceSampleMIMO - > getNbSinkStreams ( ) ) ) // add the source listener
{
2019-10-16 18:58:36 -04:00
// SampleSourceFifo *inputFIFO = m_deviceSampleMIMO->getSampleSourceFifo(spectrumInputIndex);
// connect(inputFIFO, SIGNAL(dataRead(int)), this, SLOT(handleForwardToSpectrumSink(int)));
2019-05-19 04:23:18 -04:00
if ( m_spectrumSink )
{
DSPSignalNotification notif (
m_deviceSampleMIMO - > getSinkSampleRate ( spectrumInputIndex ) ,
m_deviceSampleMIMO - > getSinkCenterFrequency ( spectrumInputIndex ) ) ;
m_spectrumSink - > handleMessage ( notif ) ;
}
}
if ( m_spectrumSink & & ( spectrumInputSourceElseSink ) & & ( spectrumInputIndex < m_deviceSampleMIMO - > getNbSinkFifos ( ) ) )
{
DSPSignalNotification notif (
m_deviceSampleMIMO - > getSourceSampleRate ( spectrumInputIndex ) ,
m_deviceSampleMIMO - > getSourceCenterFrequency ( spectrumInputIndex ) ) ;
m_spectrumSink - > handleMessage ( notif ) ;
}
m_spectrumInputSourceElseSink = spectrumInputSourceElseSink ;
m_spectrumInputIndex = spectrumInputIndex ;
}
}
2019-05-15 12:51:10 -04:00
2019-10-20 14:05:01 -04:00
m_syncMessenger . done ( returnState ) ;
2019-05-15 12:51:10 -04:00
}
void DSPDeviceMIMOEngine : : handleInputMessages ( )
{
Message * message ;
while ( ( message = m_inputMessageQueue . pop ( ) ) ! = 0 )
{
qDebug ( " DSPDeviceMIMOEngine::handleInputMessages: message: %s " , message - > getIdentifier ( ) ) ;
if ( ConfigureCorrection : : match ( * message ) )
{
ConfigureCorrection * conf = ( ConfigureCorrection * ) message ;
2019-05-15 18:43:15 -04:00
unsigned int isource = conf - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
if ( isource < m_sourcesCorrections . size ( ) )
{
m_sourcesCorrections [ isource ] . m_iqImbalanceCorrection = conf - > getIQImbalanceCorrection ( ) ;
if ( m_sourcesCorrections [ isource ] . m_dcOffsetCorrection ! = conf - > getDCOffsetCorrection ( ) )
{
m_sourcesCorrections [ isource ] . m_dcOffsetCorrection = conf - > getDCOffsetCorrection ( ) ;
m_sourcesCorrections [ isource ] . m_iOffset = 0 ;
m_sourcesCorrections [ isource ] . m_qOffset = 0 ;
if ( m_sourcesCorrections [ isource ] . m_iqImbalanceCorrection ! = conf - > getIQImbalanceCorrection ( ) )
{
m_sourcesCorrections [ isource ] . m_iqImbalanceCorrection = conf - > getIQImbalanceCorrection ( ) ;
m_sourcesCorrections [ isource ] . m_iRange = 1 < < 16 ;
m_sourcesCorrections [ isource ] . m_qRange = 1 < < 16 ;
m_sourcesCorrections [ isource ] . m_imbalance = 65536 ;
}
}
2019-05-19 06:54:22 -04:00
m_sourcesCorrections [ isource ] . m_iBeta . reset ( ) ;
m_sourcesCorrections [ isource ] . m_qBeta . reset ( ) ;
2019-05-15 12:51:10 -04:00
m_sourcesCorrections [ isource ] . m_avgAmp . reset ( ) ;
m_sourcesCorrections [ isource ] . m_avgII . reset ( ) ;
m_sourcesCorrections [ isource ] . m_avgII2 . reset ( ) ;
m_sourcesCorrections [ isource ] . m_avgIQ . reset ( ) ;
m_sourcesCorrections [ isource ] . m_avgPhi . reset ( ) ;
m_sourcesCorrections [ isource ] . m_avgQQ2 . reset ( ) ;
m_sourcesCorrections [ isource ] . m_iBeta . reset ( ) ;
m_sourcesCorrections [ isource ] . m_qBeta . reset ( ) ;
}
delete message ;
}
2019-06-04 10:57:27 -04:00
else if ( DSPMIMOSignalNotification : : match ( * message ) )
2019-05-15 12:51:10 -04:00
{
2019-06-04 10:57:27 -04:00
DSPMIMOSignalNotification * notif = ( DSPMIMOSignalNotification * ) message ;
2019-05-15 12:51:10 -04:00
// update DSP values
2019-05-19 04:23:18 -04:00
bool sourceElseSink = notif - > getSourceOrSink ( ) ;
2019-05-15 18:43:15 -04:00
unsigned int istream = notif - > getIndex ( ) ;
2019-05-15 12:51:10 -04:00
int sampleRate = notif - > getSampleRate ( ) ;
qint64 centerFrequency = notif - > getCenterFrequency ( ) ;
2019-06-04 10:57:27 -04:00
qDebug ( ) < < " DeviceMIMOEngine::handleInputMessages: DSPMIMOSignalNotification: "
2019-05-19 04:23:18 -04:00
< < " sourceElseSink: " < < sourceElseSink
2019-05-15 12:51:10 -04:00
< < " istream: " < < istream
< < " sampleRate: " < < sampleRate
< < " centerFrequency: " < < centerFrequency ;
2019-09-03 23:00:22 -04:00
for ( MIMOChannels : : const_iterator it = m_mimoChannels . begin ( ) ; it ! = m_mimoChannels . end ( ) ; + + it )
{
DSPMIMOSignalNotification * message = new DSPMIMOSignalNotification ( * notif ) ;
( * it ) - > handleMessage ( * message ) ;
}
2019-05-19 04:23:18 -04:00
if ( sourceElseSink )
2019-05-15 12:51:10 -04:00
{
2019-05-19 04:23:18 -04:00
if ( ( istream < m_deviceSampleMIMO - > getNbSourceStreams ( ) ) )
2019-05-15 12:51:10 -04:00
{
DSPSignalNotification * message = new DSPSignalNotification ( sampleRate , centerFrequency ) ;
// forward source changes to ancillary sinks with immediate execution (no queuing)
if ( istream < m_basebandSampleSinks . size ( ) )
{
for ( BasebandSampleSinks : : const_iterator it = m_basebandSampleSinks [ istream ] . begin ( ) ; it ! = m_basebandSampleSinks [ istream ] . end ( ) ; + + it )
{
2019-10-20 14:05:01 -04:00
qDebug ( ) < < " DSPDeviceMIMOEngine::handleInputMessages: starting " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2019-05-15 12:51:10 -04:00
( * it ) - > handleMessage ( * message ) ;
}
}
// forward source changes to channel sinks with immediate execution (no queuing)
if ( istream < m_threadedBasebandSampleSinks . size ( ) )
{
for ( ThreadedBasebandSampleSinks : : const_iterator it = m_threadedBasebandSampleSinks [ istream ] . begin ( ) ; it ! = m_threadedBasebandSampleSinks [ istream ] . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::handleSourceMessages: forward message to ThreadedSampleSink( " < < ( * it ) - > getSampleSinkObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > handleSinkMessage ( * message ) ;
}
}
2019-05-19 04:23:18 -04:00
// forward changes to MIMO GUI input queue
MessageQueue * guiMessageQueue = m_deviceSampleMIMO - > getMessageQueueToGUI ( ) ;
2019-06-04 10:57:27 -04:00
qDebug ( " DeviceMIMOEngine::handleInputMessages: DSPMIMOSignalNotification: guiMessageQueue: %p " , guiMessageQueue ) ;
2019-05-15 12:51:10 -04:00
2019-05-19 04:23:18 -04:00
if ( guiMessageQueue ) {
2019-06-04 10:57:27 -04:00
DSPMIMOSignalNotification * rep = new DSPMIMOSignalNotification ( * notif ) ; // make a copy for the MIMO GUI
2019-05-19 04:23:18 -04:00
guiMessageQueue - > push ( rep ) ;
}
2019-05-15 12:51:10 -04:00
2019-05-28 06:09:08 -04:00
// forward changes to spectrum sink if currently active
2019-05-19 04:23:18 -04:00
if ( m_spectrumSink & & m_spectrumInputSourceElseSink & & ( m_spectrumInputIndex = = istream ) )
{
DSPSignalNotification spectrumNotif ( sampleRate , centerFrequency ) ;
m_spectrumSink - > handleMessage ( spectrumNotif ) ;
}
2019-05-15 12:51:10 -04:00
}
}
else
{
2019-05-19 04:23:18 -04:00
if ( ( istream < m_deviceSampleMIMO - > getNbSinkStreams ( ) ) )
2019-05-15 12:51:10 -04:00
{
DSPSignalNotification * message = new DSPSignalNotification ( sampleRate , centerFrequency ) ;
// forward source changes to channel sources with immediate execution (no queuing)
if ( istream < m_threadedBasebandSampleSources . size ( ) )
{
for ( ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources [ istream ] . begin ( ) ; it ! = m_threadedBasebandSampleSources [ istream ] . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::handleSinkMessages: forward message to ThreadedSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > handleSourceMessage ( * message ) ;
}
}
2019-05-19 04:23:18 -04:00
// forward changes to MIMO GUI input queue
MessageQueue * guiMessageQueue = m_deviceSampleMIMO - > getMessageQueueToGUI ( ) ;
qDebug ( " DSPDeviceMIMOEngine::handleInputMessages: DSPSignalNotification: guiMessageQueue: %p " , guiMessageQueue ) ;
2019-05-15 12:51:10 -04:00
2019-05-19 04:23:18 -04:00
if ( guiMessageQueue ) {
2019-06-04 10:57:27 -04:00
DSPMIMOSignalNotification * rep = new DSPMIMOSignalNotification ( * notif ) ; // make a copy for the source GUI
2019-05-19 04:23:18 -04:00
guiMessageQueue - > push ( rep ) ;
}
2019-05-15 12:51:10 -04:00
2019-05-28 06:09:08 -04:00
// forward changes to spectrum sink if currently active
2019-05-19 04:23:18 -04:00
if ( m_spectrumSink & & ! m_spectrumInputSourceElseSink & & ( m_spectrumInputIndex = = istream ) )
{
DSPSignalNotification spectrumNotif ( sampleRate , centerFrequency ) ;
m_spectrumSink - > handleMessage ( spectrumNotif ) ;
}
}
2019-05-15 12:51:10 -04:00
}
2019-05-19 04:23:18 -04:00
delete message ;
2019-05-15 12:51:10 -04:00
}
}
}
2019-05-18 00:30:37 -04:00
void DSPDeviceMIMOEngine : : configureCorrections ( bool dcOffsetCorrection , bool iqImbalanceCorrection , int isource )
{
qDebug ( ) < < " DSPDeviceMIMOEngine::configureCorrections " ;
ConfigureCorrection * cmd = new ConfigureCorrection ( dcOffsetCorrection , iqImbalanceCorrection , isource ) ;
m_inputMessageQueue . push ( cmd ) ;
}
2019-05-19 04:23:18 -04:00
2019-05-29 16:09:19 -04:00
void DSPDeviceMIMOEngine : : iqCorrections ( SampleVector : : iterator begin , SampleVector : : iterator end , int isource , bool imbalanceCorrection )
{
for ( SampleVector : : iterator it = begin ; it < end ; it + + )
{
m_sourcesCorrections [ isource ] . m_iBeta ( it - > real ( ) ) ;
m_sourcesCorrections [ isource ] . m_qBeta ( it - > imag ( ) ) ;
if ( imbalanceCorrection )
{
# if IMBALANCE_INT
// acquisition
int64_t xi = ( it - > m_real - ( int32_t ) m_sourcesCorrections [ isource ] . m_iBeta ) < < 5 ;
int64_t xq = ( it - > m_imag - ( int32_t ) m_sourcesCorrections [ isource ] . m_qBeta ) < < 5 ;
// phase imbalance
m_sourcesCorrections [ isource ] . m_avgII ( ( xi * xi ) > > 28 ) ; // <I", I">
m_sourcesCorrections [ isource ] . m_avgIQ ( ( xi * xq ) > > 28 ) ; // <I", Q">
if ( ( int64_t ) m_sourcesCorrections [ isource ] . m_avgII ! = 0 )
{
int64_t phi = ( ( ( int64_t ) m_sourcesCorrections [ isource ] . m_avgIQ ) < < 28 ) / ( int64_t ) m_sourcesCorrections [ isource ] . m_avgII ;
m_sourcesCorrections [ isource ] . m_avgPhi ( phi ) ;
}
int64_t corrPhi = ( ( ( int64_t ) m_sourcesCorrections [ isource ] . 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_sourcesCorrections [ isource ] . m_avgII2 ( ( yi * yi ) > > 28 ) ; // <I, I>
m_sourcesCorrections [ isource ] . m_avgQQ2 ( ( yq * yq ) > > 28 ) ; // <Q, Q>
if ( ( int64_t ) m_sourcesCorrections [ isource ] . m_avgQQ2 ! = 0 )
{
int64_t a = ( ( ( int64_t ) m_sourcesCorrections [ isource ] . m_avgII2 ) < < 28 ) / ( int64_t ) m_sourcesCorrections [ isource ] . 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_sourcesCorrections [ isource ] . m_avgAmp ( sqrtA . as_internal ( ) ) ;
}
int64_t zq = ( ( ( int64_t ) m_sourcesCorrections [ isource ] . m_avgAmp ) * yq ) > > 28 ;
it - > m_real = yi > > 5 ;
it - > m_imag = zq > > 5 ;
# else
// DC correction and conversion
float xi = ( it - > m_real - ( int32_t ) m_sourcesCorrections [ isource ] . m_iBeta ) / SDR_RX_SCALEF ;
float xq = ( it - > m_imag - ( int32_t ) m_sourcesCorrections [ isource ] . m_qBeta ) / SDR_RX_SCALEF ;
// phase imbalance
m_sourcesCorrections [ isource ] . m_avgII ( xi * xi ) ; // <I", I">
m_sourcesCorrections [ isource ] . m_avgIQ ( xi * xq ) ; // <I", Q">
if ( m_sourcesCorrections [ isource ] . m_avgII . asDouble ( ) ! = 0 ) {
m_sourcesCorrections [ isource ] . m_avgPhi ( m_sourcesCorrections [ isource ] . m_avgIQ . asDouble ( ) / m_sourcesCorrections [ isource ] . m_avgII . asDouble ( ) ) ;
}
float & yi = xi ; // the in phase remains the reference
float yq = xq - m_sourcesCorrections [ isource ] . m_avgPhi . asDouble ( ) * xi ;
// amplitude I/Q imbalance
m_sourcesCorrections [ isource ] . m_avgII2 ( yi * yi ) ; // <I, I>
m_sourcesCorrections [ isource ] . m_avgQQ2 ( yq * yq ) ; // <Q, Q>
if ( m_sourcesCorrections [ isource ] . m_avgQQ2 . asDouble ( ) ! = 0 ) {
m_sourcesCorrections [ isource ] . m_avgAmp ( sqrt ( m_sourcesCorrections [ isource ] . m_avgII2 . asDouble ( ) / m_sourcesCorrections [ isource ] . m_avgQQ2 . asDouble ( ) ) ) ;
}
// final correction
float & zi = yi ; // the in phase remains the reference
float zq = m_sourcesCorrections [ isource ] . m_avgAmp . asDouble ( ) * yq ;
// convert and store
it - > m_real = zi * SDR_RX_SCALEF ;
it - > m_imag = zq * SDR_RX_SCALEF ;
# endif
}
else
{
// DC correction only
it - > m_real - = ( int32_t ) m_sourcesCorrections [ isource ] . m_iBeta ;
it - > m_imag - = ( int32_t ) m_sourcesCorrections [ isource ] . m_qBeta ;
}
}
}