2016-10-23 17:27:19 -04:00
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2016 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/>. //
///////////////////////////////////////////////////////////////////////////////////
# include <stdio.h>
# include <QDebug>
# include <QThread>
# include "dspdevicesinkengine.h"
# include "dsp/basebandsamplesource.h"
# include "dsp/basebandsamplesink.h"
# include "dsp/devicesamplesink.h"
# include "dsp/dspcommands.h"
# include "samplesourcefifo.h"
# include "threadedbasebandsamplesource.h"
2016-12-26 06:45:19 -05:00
DSPDeviceSinkEngine : : DSPDeviceSinkEngine ( uint32_t uid , QObject * parent ) :
2016-10-23 17:27:19 -04:00
QThread ( parent ) ,
2017-05-25 14:13:34 -04:00
m_uid ( uid ) ,
2016-10-23 17:27:19 -04:00
m_state ( StNotStarted ) ,
m_deviceSampleSink ( 0 ) ,
m_sampleSinkSequence ( 0 ) ,
m_basebandSampleSources ( ) ,
2016-10-24 12:06:44 -04:00
m_spectrumSink ( 0 ) ,
2016-10-23 17:27:19 -04:00
m_sampleRate ( 0 ) ,
2016-12-26 06:45:19 -05:00
m_centerFrequency ( 0 ) ,
m_multipleSourcesDivisionFactor ( 1 )
2016-10-23 17:27:19 -04:00
{
connect ( & m_inputMessageQueue , SIGNAL ( messageEnqueued ( ) ) , this , SLOT ( handleInputMessages ( ) ) , Qt : : QueuedConnection ) ;
connect ( & m_syncMessenger , SIGNAL ( messageSent ( ) ) , this , SLOT ( handleSynchronousMessages ( ) ) , Qt : : QueuedConnection ) ;
moveToThread ( this ) ;
}
DSPDeviceSinkEngine : : ~ DSPDeviceSinkEngine ( )
{
wait ( ) ;
}
void DSPDeviceSinkEngine : : run ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::run " ;
m_state = StIdle ;
m_syncMessenger . done ( ) ; // Release start() that is waiting in main thread
exec ( ) ;
}
void DSPDeviceSinkEngine : : start ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::start " ;
QThread : : start ( ) ;
}
void DSPDeviceSinkEngine : : stop ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::stop " ;
DSPExit cmd ;
m_syncMessenger . sendWait ( cmd ) ;
}
bool DSPDeviceSinkEngine : : initGeneration ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::initGeneration " ;
DSPGenerationInit cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StReady ;
}
bool DSPDeviceSinkEngine : : startGeneration ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::startGeneration " ;
DSPGenerationStart cmd ;
return m_syncMessenger . sendWait ( cmd ) = = StRunning ;
}
void DSPDeviceSinkEngine : : stopGeneration ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::stopGeneration " ;
DSPGenerationStop cmd ;
m_syncMessenger . storeMessage ( cmd ) ;
handleSynchronousMessages ( ) ;
}
void DSPDeviceSinkEngine : : setSink ( DeviceSampleSink * sink )
{
qDebug ( ) < < " DSPDeviceSinkEngine::setSink " ;
DSPSetSink cmd ( sink ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceSinkEngine : : setSinkSequence ( int sequence )
{
qDebug ( " DSPDeviceSinkEngine::setSinkSequence: seq: %d " , sequence ) ;
m_sampleSinkSequence = sequence ;
}
void DSPDeviceSinkEngine : : addSource ( BasebandSampleSource * source )
{
qDebug ( ) < < " DSPDeviceSinkEngine::addSource: " < < source - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPAddSource cmd ( source ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceSinkEngine : : removeSource ( BasebandSampleSource * source )
{
qDebug ( ) < < " DSPDeviceSinkEngine::removeSource: " < < source - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPRemoveSource cmd ( source ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceSinkEngine : : addThreadedSource ( ThreadedBasebandSampleSource * source )
{
qDebug ( ) < < " DSPDeviceSinkEngine::addThreadedSource: " < < source - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPAddThreadedSampleSource cmd ( source ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
void DSPDeviceSinkEngine : : removeThreadedSource ( ThreadedBasebandSampleSource * source )
{
qDebug ( ) < < " DSPDeviceSinkEngine::removeThreadedSource: " < < source - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPRemoveThreadedSampleSource cmd ( source ) ;
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-24 12:06:44 -04:00
void DSPDeviceSinkEngine : : addSpectrumSink ( BasebandSampleSink * spectrumSink )
2016-10-23 17:27:19 -04:00
{
2016-10-24 12:06:44 -04:00
qDebug ( ) < < " DSPDeviceSinkEngine::addSpectrumSink: " < < spectrumSink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPAddSpectrumSink cmd ( spectrumSink ) ;
2016-10-23 17:27:19 -04:00
m_syncMessenger . sendWait ( cmd ) ;
}
2016-10-24 12:06:44 -04:00
void DSPDeviceSinkEngine : : removeSpectrumSink ( BasebandSampleSink * spectrumSink )
2016-10-23 17:27:19 -04:00
{
2016-10-24 12:06:44 -04:00
qDebug ( ) < < " DSPDeviceSinkEngine::removeSpectrumSink: " < < spectrumSink - > objectName ( ) . toStdString ( ) . c_str ( ) ;
DSPRemoveSpectrumSink cmd ( spectrumSink ) ;
2016-10-23 17:27:19 -04:00
m_syncMessenger . sendWait ( cmd ) ;
}
QString DSPDeviceSinkEngine : : errorMessage ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::errorMessage " ;
DSPGetErrorMessage cmd ;
m_syncMessenger . sendWait ( cmd ) ;
return cmd . getErrorMessage ( ) ;
}
QString DSPDeviceSinkEngine : : sinkDeviceDescription ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::sinkDeviceDescription " ;
DSPGetSinkDeviceDescription cmd ;
m_syncMessenger . sendWait ( cmd ) ;
return cmd . getDeviceDescription ( ) ;
}
2016-12-20 20:24:49 -05:00
void DSPDeviceSinkEngine : : work ( int nbWriteSamples )
2016-10-23 17:27:19 -04:00
{
SampleSourceFifo * sampleFifo = m_deviceSampleSink - > getSampleFifo ( ) ;
2016-12-20 20:24:49 -05:00
//unsigned int nbWriteSamples = sampleFifo->getChunkSize();
2016-10-23 17:27:19 -04:00
2016-12-22 17:39:06 -05:00
// single channel source handling
if ( ( m_threadedBasebandSampleSources . size ( ) + m_basebandSampleSources . size ( ) ) = = 1 )
2016-10-23 17:27:19 -04:00
{
2016-12-26 06:11:51 -05:00
// qDebug("DSPDeviceSinkEngine::work: single channel source handling");
2016-12-25 19:39:34 -05:00
for ( ThreadedBasebandSampleSources : : iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; + + it )
2016-12-22 17:39:06 -05:00
{
( * it ) - > feed ( sampleFifo , nbWriteSamples ) ;
}
for ( BasebandSampleSources : : iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; + + it )
{
( * it ) - > feed ( sampleFifo , nbWriteSamples ) ;
}
}
// multiple channel sources handling
else if ( ( m_threadedBasebandSampleSources . size ( ) + m_basebandSampleSources . size ( ) ) > 1 )
{
2016-12-26 06:45:19 -05:00
// qDebug("DSPDeviceSinkEngine::work: multiple channel sources handling: %u", m_multipleSourcesDivisionFactor);
2016-12-26 06:11:51 -05:00
2016-12-26 06:45:19 -05:00
// SampleVector::iterator writeBegin;
// sampleFifo->getWriteIterator(writeBegin);
// SampleVector::iterator writeAt = writeBegin;
// Sample s;
// int sourceOccurence = 0;
//
// // Read a chunk of data from the sources
//
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
// {
// ((*it)->getSampleSourceFifo()).readAdvance(m_threadedBasebandSampleSourcesIteratorMap[*it], nbWriteSamples);
// m_threadedBasebandSampleSourcesIteratorMap[*it] -= nbWriteSamples;
// }
//
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
// {
// ((*it)->getSampleSourceFifo()).readAdvance(m_basebandSampleSourcesIteratorMap[*it], nbWriteSamples);
// m_basebandSampleSourcesIteratorMap[*it] -= nbWriteSamples;
// }
//
// // Process sample by sample
//
// for (int is = 0; is < nbWriteSamples; is++)
// {
// // pull data from threaded sources and merge them in the device sample FIFO
// for (ThreadedBasebandSampleSources::iterator it = m_threadedBasebandSampleSources.begin(); it != m_threadedBasebandSampleSources.end(); ++it)
// {
// s = *m_threadedBasebandSampleSourcesIteratorMap[*it];
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
//
// if (sourceOccurence == 0) {
// (*writeAt) = s;
// } else {
// (*writeAt) += s;
// }
//
// sourceOccurence++;
// m_threadedBasebandSampleSourcesIteratorMap[*it]++;
// }
//
// // pull data from direct sources and merge them in the device sample FIFO
// for (BasebandSampleSources::iterator it = m_basebandSampleSources.begin(); it != m_basebandSampleSources.end(); ++it)
// {
// s = *m_basebandSampleSourcesIteratorMap[*it];
// s /= (m_threadedBasebandSampleSources.size() + m_basebandSampleSources.size());
//
// if (sourceOccurence == 0) {
// (*writeAt) = s;
// } else {
// (*writeAt) += s;
// }
//
// sourceOccurence++;
// m_basebandSampleSourcesIteratorMap[*it]++;
// }
//
// sampleFifo->bumpIndex(writeAt);
// sourceOccurence = 0;
// }
SampleVector : : iterator writeBegin ;
sampleFifo - > getWriteIterator ( writeBegin ) ;
SampleVector : : iterator writeAt = writeBegin ;
2016-12-26 06:11:51 -05:00
Sample s ;
int sourceOccurence = 0 ;
for ( ThreadedBasebandSampleSources : : iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; + + it )
2016-12-25 19:39:34 -05:00
{
2016-12-26 06:45:19 -05:00
( * it ) - > pullAudio ( nbWriteSamples ) ;
2016-12-25 19:39:34 -05:00
}
2016-12-26 06:11:51 -05:00
2016-12-26 06:45:19 -05:00
for ( BasebandSampleSources : : iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; + + it )
{
( * it ) - > pullAudio ( nbWriteSamples ) ;
}
2016-12-26 06:11:51 -05:00
2016-12-26 06:45:19 -05:00
for ( int is = 0 ; is < nbWriteSamples ; is + + )
{
// pull data from threaded sources and merge them in the device sample FIFO
for ( ThreadedBasebandSampleSources : : iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; + + it )
{
( * it ) - > pull ( s ) ;
s / = m_multipleSourcesDivisionFactor ;
if ( sourceOccurence = = 0 ) {
( * writeAt ) = s ;
} else {
( * writeAt ) + = s ;
}
sourceOccurence + + ;
}
// pull data from direct sources and merge them in the device sample FIFO
for ( BasebandSampleSources : : iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; + + it )
{
( * it ) - > pull ( s ) ;
s / = m_multipleSourcesDivisionFactor ;
2016-12-26 06:11:51 -05:00
if ( sourceOccurence = = 0 ) {
( * writeAt ) = s ;
} else {
( * writeAt ) + = s ;
}
sourceOccurence + + ;
2016-12-26 06:45:19 -05:00
}
2016-12-26 06:11:51 -05:00
2016-12-26 06:45:19 -05:00
sampleFifo - > bumpIndex ( writeAt ) ;
2016-12-26 06:11:51 -05:00
sourceOccurence = 0 ;
2016-12-26 06:45:19 -05:00
}
2016-10-23 17:27:19 -04:00
2016-10-24 12:06:44 -04:00
// feed the mix to the main spectrum sink
2016-10-24 12:31:14 -04:00
// if (m_spectrumSink)
// {
// m_spectrumSink->feed(writeBegin, writeBegin + nbWriteSamples, false);
// }
2016-10-23 17:27:19 -04:00
}
}
// notStarted -> idle -> init -> running -+
// ^ |
// +-----------------------+
DSPDeviceSinkEngine : : State DSPDeviceSinkEngine : : gotoIdle ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoIdle " ;
switch ( m_state ) {
case StNotStarted :
return StNotStarted ;
case StIdle :
case StError :
return StIdle ;
case StReady :
case StRunning :
break ;
}
if ( m_deviceSampleSink = = 0 )
{
return StIdle ;
}
// stop everything
for ( BasebandSampleSources : : const_iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; it + + )
{
2016-12-25 15:26:37 -05:00
qDebug ( ) < < " DSPDeviceSinkEngine::gotoIdle: stopping " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2016-10-23 17:27:19 -04:00
( * it ) - > stop ( ) ;
}
for ( ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; it + + )
{
2016-12-25 15:26:37 -05:00
qDebug ( ) < < " DSPDeviceSinkEngine::gotoIdle: stopping ThreadedSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
2016-10-23 17:27:19 -04:00
( * it ) - > stop ( ) ;
}
2016-10-24 12:31:14 -04:00
disconnect ( m_deviceSampleSink - > getSampleFifo ( ) , SIGNAL ( dataRead ( int ) ) , this , SLOT ( handleForwardToSpectrumSink ( int ) ) ) ;
2016-10-24 12:06:44 -04:00
m_spectrumSink - > stop ( ) ;
2016-10-23 17:27:19 -04:00
m_deviceSampleSink - > stop ( ) ;
m_deviceDescription . clear ( ) ;
m_sampleRate = 0 ;
return StIdle ;
}
DSPDeviceSinkEngine : : State DSPDeviceSinkEngine : : gotoInit ( )
{
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 ;
}
if ( m_deviceSampleSink = = 0 )
{
return gotoError ( " DSPDeviceSinkEngine::gotoInit: 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_deviceDescription = m_deviceSampleSink - > getDeviceDescription ( ) ;
m_centerFrequency = m_deviceSampleSink - > getCenterFrequency ( ) ;
m_sampleRate = m_deviceSampleSink - > getSampleRate ( ) ;
2017-12-25 03:10:19 -05:00
qDebug ( ) < < " DSPDeviceSinkEngine::gotoInit: "
< < " m_deviceDescription: " < < m_deviceDescription . toStdString ( ) . c_str ( )
2016-10-23 17:27:19 -04:00
< < " sampleRate: " < < m_sampleRate
< < " centerFrequency: " < < m_centerFrequency ;
DSPSignalNotification notif ( m_sampleRate , m_centerFrequency ) ;
for ( BasebandSampleSources : : const_iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoInit: initializing " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > handleMessage ( notif ) ;
}
for ( ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoInit: initializing ThreadedSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > handleSourceMessage ( notif ) ;
}
2016-10-24 12:06:44 -04:00
m_spectrumSink - > handleMessage ( notif ) ;
2016-10-23 17:27:19 -04:00
// pass data to listeners
2017-09-17 11:35:03 -04:00
if ( m_deviceSampleSink - > getMessageQueueToGUI ( ) )
{
DSPSignalNotification * rep = new DSPSignalNotification ( notif ) ; // make a copy for the output queue
m_deviceSampleSink - > getMessageQueueToGUI ( ) - > push ( rep ) ;
}
2016-10-23 17:27:19 -04:00
return StReady ;
}
DSPDeviceSinkEngine : : State DSPDeviceSinkEngine : : gotoRunning ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoRunning " ;
switch ( m_state )
{
case StNotStarted :
return StNotStarted ;
case StIdle :
return StIdle ;
case StRunning :
return StRunning ;
case StReady :
case StError :
break ;
}
if ( m_deviceSampleSink = = 0 ) {
return gotoError ( " DSPDeviceSinkEngine::gotoRunning: No sample source configured " ) ;
}
qDebug ( ) < < " DSPDeviceSinkEngine::gotoRunning: " < < m_deviceDescription . toStdString ( ) . c_str ( ) < < " started " ;
// Start everything
2017-04-13 21:44:49 -04:00
if ( ! m_deviceSampleSink - > start ( ) )
2016-10-23 17:27:19 -04:00
{
return gotoError ( " DSPDeviceSinkEngine::gotoRunning: Could not start sample source " ) ;
}
2016-12-26 06:45:19 -05:00
uint32_t nbSources = m_basebandSampleSources . size ( ) + m_threadedBasebandSampleSources . size ( ) ;
if ( nbSources = = 0 ) {
m_multipleSourcesDivisionFactor = 1 ;
} else if ( nbSources < 3 ) {
m_multipleSourcesDivisionFactor = nbSources ;
} else {
m_multipleSourcesDivisionFactor = 1 < < nbSources ;
}
2016-10-23 17:27:19 -04:00
for ( BasebandSampleSources : : const_iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; it + + )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoRunning: starting " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
2016-12-26 08:52:59 -05:00
// not used with sample by sample processing
// (*it)->getSampleSourceFifo().resize(2*m_deviceSampleSink->getSampleFifo()->size()); // Equalize channel source FIFO size with device sink FIFO size
2016-10-23 17:27:19 -04:00
( * it ) - > start ( ) ;
}
for ( ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoRunning: starting ThreadedSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
2016-12-26 08:52:59 -05:00
// not used with sample by sample processing
// (*it)->getSampleSourceFifo().resize(2*m_deviceSampleSink->getSampleFifo()->size()); // Equalize channel source FIFO size with device sink FIFO size
2016-10-23 17:27:19 -04:00
( * it ) - > start ( ) ;
}
2016-10-24 12:31:14 -04:00
connect ( m_deviceSampleSink - > getSampleFifo ( ) , SIGNAL ( dataRead ( int ) ) , this , SLOT ( handleForwardToSpectrumSink ( int ) ) ) ;
2016-10-24 12:06:44 -04:00
m_spectrumSink - > start ( ) ;
2016-10-23 17:27:19 -04:00
qDebug ( ) < < " DSPDeviceSinkEngine::gotoRunning: input message queue pending: " < < m_inputMessageQueue . size ( ) ;
return StRunning ;
}
DSPDeviceSinkEngine : : State DSPDeviceSinkEngine : : gotoError ( const QString & errorMessage )
{
qDebug ( ) < < " DSPDeviceSinkEngine::gotoError " ;
m_errorMessage = errorMessage ;
m_deviceDescription . clear ( ) ;
m_state = StError ;
return StError ;
}
void DSPDeviceSinkEngine : : handleSetSink ( DeviceSampleSink * sink )
{
gotoIdle ( ) ;
// if(m_sampleSource != 0)
// {
// disconnect(m_sampleSource->getSampleFifo(), SIGNAL(dataReady()), this, SLOT(handleData()));
// }
m_deviceSampleSink = sink ;
if ( m_deviceSampleSink ! = 0 )
{
qDebug ( " DSPDeviceSinkEngine::handleSetSink: set %s " , qPrintable ( sink - > getDeviceDescription ( ) ) ) ;
2016-12-20 20:24:49 -05:00
connect ( m_deviceSampleSink - > getSampleFifo ( ) , SIGNAL ( dataWrite ( int ) ) , this , SLOT ( handleData ( int ) ) , Qt : : QueuedConnection ) ;
2016-10-23 17:27:19 -04:00
}
else
{
qDebug ( " DSPDeviceSinkEngine::handleSetSource: set none " ) ;
}
}
2016-12-20 20:24:49 -05:00
void DSPDeviceSinkEngine : : handleData ( int nbSamples )
2016-10-23 17:27:19 -04:00
{
if ( m_state = = StRunning )
{
2016-12-20 20:24:49 -05:00
work ( nbSamples ) ;
2016-10-23 17:27:19 -04:00
}
}
void DSPDeviceSinkEngine : : handleSynchronousMessages ( )
{
Message * message = m_syncMessenger . getMessage ( ) ;
qDebug ( ) < < " DSPDeviceSinkEngine::handleSynchronousMessages: " < < message - > getIdentifier ( ) ;
if ( DSPExit : : match ( * message ) )
{
gotoIdle ( ) ;
m_state = StNotStarted ;
exit ( ) ;
}
else if ( DSPGenerationInit : : match ( * message ) )
{
m_state = gotoIdle ( ) ;
if ( m_state = = StIdle ) {
m_state = gotoInit ( ) ; // State goes ready if init is performed
}
}
else if ( DSPGenerationStart : : match ( * message ) )
{
if ( m_state = = StReady ) {
m_state = gotoRunning ( ) ;
}
}
else if ( DSPGenerationStop : : match ( * message ) )
{
m_state = gotoIdle ( ) ;
}
else if ( DSPGetSinkDeviceDescription : : match ( * message ) )
{
( ( DSPGetSinkDeviceDescription * ) message ) - > setDeviceDescription ( m_deviceDescription ) ;
}
else if ( DSPGetErrorMessage : : match ( * message ) )
{
( ( DSPGetErrorMessage * ) message ) - > setErrorMessage ( m_errorMessage ) ;
}
else if ( DSPSetSink : : match ( * message ) ) {
handleSetSink ( ( ( DSPSetSink * ) message ) - > getSampleSink ( ) ) ;
}
2016-10-24 12:06:44 -04:00
else if ( DSPAddSpectrumSink : : match ( * message ) )
2016-10-23 17:27:19 -04:00
{
2016-10-24 12:06:44 -04:00
m_spectrumSink = ( ( DSPAddSpectrumSink * ) message ) - > getSampleSink ( ) ;
2016-10-23 17:27:19 -04:00
}
2016-10-24 12:06:44 -04:00
else if ( DSPRemoveSpectrumSink : : match ( * message ) )
2016-10-23 17:27:19 -04:00
{
2016-10-24 12:06:44 -04:00
BasebandSampleSink * spectrumSink = ( ( DSPRemoveSpectrumSink * ) message ) - > getSampleSink ( ) ;
2016-10-23 17:27:19 -04:00
if ( m_state = = StRunning ) {
2016-10-24 12:06:44 -04:00
spectrumSink - > stop ( ) ;
2016-10-23 17:27:19 -04:00
}
2016-10-24 12:06:44 -04:00
m_spectrumSink = 0 ;
2016-10-23 17:27:19 -04:00
}
else if ( DSPAddSource : : match ( * message ) )
{
BasebandSampleSource * source = ( ( DSPAddSource * ) message ) - > getSampleSource ( ) ;
m_basebandSampleSources . push_back ( source ) ;
2016-12-26 08:52:59 -05:00
// not used with sample by sample processing
// BasebandSampleSourcesIteratorMapKV kv;
// kv.first = source;
// (source->getSampleSourceFifo()).getReadIterator(kv.second);
// m_basebandSampleSourcesIteratorMap.insert(kv);
2016-10-23 17:27:19 -04:00
}
else if ( DSPRemoveSource : : match ( * message ) )
{
BasebandSampleSource * source = ( ( DSPRemoveSource * ) message ) - > getSampleSource ( ) ;
if ( m_state = = StRunning ) {
source - > stop ( ) ;
}
2016-12-26 08:52:59 -05:00
// not used with sample by sample processing
// m_basebandSampleSourcesIteratorMap.erase(source);
2016-10-23 17:27:19 -04:00
m_basebandSampleSources . remove ( source ) ;
}
else if ( DSPAddThreadedSampleSource : : match ( * message ) )
{
ThreadedBasebandSampleSource * threadedSource = ( ( DSPAddThreadedSampleSource * ) message ) - > getThreadedSampleSource ( ) ;
m_threadedBasebandSampleSources . push_back ( threadedSource ) ;
2016-12-26 08:52:59 -05:00
// not used with sample by sample processing
// ThreadedBasebandSampleSourcesIteratorMapKV kv;
// kv.first = threadedSource;
// (threadedSource->getSampleSourceFifo()).getReadIterator(kv.second);
// m_threadedBasebandSampleSourcesIteratorMap.insert(kv);
2017-10-17 17:41:30 -04:00
// threadedSource->start();
2016-10-23 17:27:19 -04:00
}
else if ( DSPRemoveThreadedSampleSource : : match ( * message ) )
{
ThreadedBasebandSampleSource * threadedSource = ( ( DSPRemoveThreadedSampleSource * ) message ) - > getThreadedSampleSource ( ) ;
2017-10-17 17:41:30 -04:00
if ( m_state = = StRunning ) {
threadedSource - > stop ( ) ;
}
2016-12-26 08:52:59 -05:00
// not used with sample by sample processing
// m_threadedBasebandSampleSourcesIteratorMap.erase(threadedSource);
2016-10-23 17:27:19 -04:00
m_threadedBasebandSampleSources . remove ( threadedSource ) ;
}
m_syncMessenger . done ( m_state ) ;
}
void DSPDeviceSinkEngine : : handleInputMessages ( )
{
qDebug ( ) < < " DSPDeviceSinkEngine::handleInputMessages " ;
Message * message ;
while ( ( message = m_inputMessageQueue . pop ( ) ) ! = 0 )
{
qDebug ( " DSPDeviceSinkEngine::handleInputMessages: message: %s " , message - > getIdentifier ( ) ) ;
if ( DSPSignalNotification : : match ( * message ) )
{
DSPSignalNotification * notif = ( DSPSignalNotification * ) message ;
// update DSP values
m_sampleRate = notif - > getSampleRate ( ) ;
m_centerFrequency = notif - > getCenterFrequency ( ) ;
qDebug ( ) < < " DSPDeviceSinkEngine::handleInputMessages: DSPSignalNotification( " < < m_sampleRate < < " , " < < m_centerFrequency < < " ) " ;
// forward source changes to sources with immediate execution
for ( BasebandSampleSources : : const_iterator it = m_basebandSampleSources . begin ( ) ; it ! = m_basebandSampleSources . end ( ) ; it + + )
{
qDebug ( ) < < " DSPDeviceSinkEngine::handleInputMessages: forward message to " < < ( * it ) - > objectName ( ) . toStdString ( ) . c_str ( ) ;
( * it ) - > handleMessage ( * message ) ;
}
for ( ThreadedBasebandSampleSources : : const_iterator it = m_threadedBasebandSampleSources . begin ( ) ; it ! = m_threadedBasebandSampleSources . end ( ) ; + + it )
{
qDebug ( ) < < " DSPDeviceSinkEngine::handleSourceMessages: forward message to ThreadedSampleSource( " < < ( * it ) - > getSampleSourceObjectName ( ) . toStdString ( ) . c_str ( ) < < " ) " ;
( * it ) - > handleSourceMessage ( * message ) ;
}
// forward changes to listeners on DSP output queue
2017-09-17 11:35:03 -04:00
if ( m_deviceSampleSink - > getMessageQueueToGUI ( ) )
{
DSPSignalNotification * rep = new DSPSignalNotification ( * notif ) ; // make a copy for the output queue
m_deviceSampleSink - > getMessageQueueToGUI ( ) - > push ( rep ) ;
}
2016-10-23 17:27:19 -04:00
delete message ;
}
}
}
2016-10-24 12:31:14 -04:00
void DSPDeviceSinkEngine : : handleForwardToSpectrumSink ( int nbSamples )
{
if ( m_spectrumSink )
{
SampleSourceFifo * sampleFifo = m_deviceSampleSink - > getSampleFifo ( ) ;
SampleVector : : iterator readUntil ;
sampleFifo - > getReadIterator ( readUntil ) ;
m_spectrumSink - > feed ( readUntil - nbSamples , readUntil , false ) ;
}
}