2020-10-27 16:22:10 +00:00
///////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2019 Edouard Griffiths, F4EXB //
// Copyright (C) 2020 Jon Beniston, M7RCE //
// //
// 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>
# include "dsp/dspengine.h"
# include "dsp/dspcommands.h"
# include "dsp/downchannelizer.h"
# include "adsbdemodbaseband.h"
# include "adsb.h"
MESSAGE_CLASS_DEFINITION ( ADSBDemodBaseband : : MsgConfigureADSBDemodBaseband , Message )
ADSBDemodBaseband : : ADSBDemodBaseband ( ) :
m_mutex ( QMutex : : Recursive )
{
m_sampleFifo . setSize ( SampleSinkFifo : : getSizePolicy ( 8000000 ) ) ;
m_channelizer = new DownChannelizer ( & m_sink ) ;
qDebug ( " ADSBDemodBaseband::ADSBDemodBaseband " ) ;
QObject : : connect (
& m_sampleFifo ,
& SampleSinkFifo : : dataReady ,
this ,
& ADSBDemodBaseband : : handleData ,
Qt : : QueuedConnection
) ;
connect ( & m_inputMessageQueue , SIGNAL ( messageEnqueued ( ) ) , this , SLOT ( handleInputMessages ( ) ) ) ;
}
ADSBDemodBaseband : : ~ ADSBDemodBaseband ( )
{
delete m_channelizer ;
}
void ADSBDemodBaseband : : reset ( )
{
QMutexLocker mutexLocker ( & m_mutex ) ;
m_sampleFifo . reset ( ) ;
}
2020-11-06 22:33:16 +00:00
void ADSBDemodBaseband : : startWork ( )
{
m_sink . startWorker ( ) ;
}
void ADSBDemodBaseband : : stopWork ( )
{
m_sink . stopWorker ( ) ;
}
2020-10-27 16:22:10 +00:00
void ADSBDemodBaseband : : feed ( const SampleVector : : const_iterator & begin , const SampleVector : : const_iterator & end )
{
m_sampleFifo . write ( begin , end ) ;
}
void ADSBDemodBaseband : : handleData ( )
{
QMutexLocker mutexLocker ( & m_mutex ) ;
while ( ( m_sampleFifo . fill ( ) > 0 ) & & ( m_inputMessageQueue . size ( ) = = 0 ) )
{
SampleVector : : iterator part1begin ;
SampleVector : : iterator part1end ;
SampleVector : : iterator part2begin ;
SampleVector : : iterator part2end ;
std : : size_t count = m_sampleFifo . readBegin ( m_sampleFifo . fill ( ) , & part1begin , & part1end , & part2begin , & part2end ) ;
// first part of FIFO data
if ( part1begin ! = part1end ) {
m_channelizer - > feed ( part1begin , part1end ) ;
}
// second part of FIFO data (used when block wraps around)
if ( part2begin ! = part2end ) {
m_channelizer - > feed ( part2begin , part2end ) ;
}
m_sampleFifo . readCommit ( ( unsigned int ) count ) ;
}
}
void ADSBDemodBaseband : : handleInputMessages ( )
{
Message * message ;
while ( ( message = m_inputMessageQueue . pop ( ) ) ! = nullptr )
{
if ( handleMessage ( * message ) ) {
delete message ;
}
}
}
bool ADSBDemodBaseband : : handleMessage ( const Message & cmd )
{
if ( MsgConfigureADSBDemodBaseband : : match ( cmd ) )
{
QMutexLocker mutexLocker ( & m_mutex ) ;
MsgConfigureADSBDemodBaseband & cfg = ( MsgConfigureADSBDemodBaseband & ) cmd ;
qDebug ( ) < < " ADSBDemodBaseband::handleMessage: MsgConfigureADSBDemodBaseband " ;
applySettings ( cfg . getSettings ( ) , cfg . getForce ( ) ) ;
return true ;
}
else if ( DSPSignalNotification : : match ( cmd ) )
{
QMutexLocker mutexLocker ( & m_mutex ) ;
DSPSignalNotification & notif = ( DSPSignalNotification & ) cmd ;
qDebug ( ) < < " ADSBDemodBaseband::handleMessage: DSPSignalNotification: basebandSampleRate: " < < notif . getSampleRate ( ) ;
m_sampleFifo . setSize ( SampleSinkFifo : : getSizePolicy ( 8 * notif . getSampleRate ( ) ) ) ; // Need a large FIFO otherwise we get overflows - revist after better upsampling
m_channelizer - > setBasebandSampleRate ( notif . getSampleRate ( ) ) ;
m_sink . applyChannelSettings ( m_channelizer - > getChannelSampleRate ( ) , m_channelizer - > getChannelFrequencyOffset ( ) ) ;
return true ;
}
else
{
return false ;
}
}
void ADSBDemodBaseband : : applySettings ( const ADSBDemodSettings & settings , bool force )
{
if ( ( settings . m_inputFrequencyOffset ! = m_settings . m_inputFrequencyOffset )
| | ( settings . m_samplesPerBit ! = m_settings . m_samplesPerBit ) | | force )
{
int requestedRate = ADS_B_BITS_PER_SECOND * settings . m_samplesPerBit ;
m_channelizer - > setChannelization ( requestedRate , settings . m_inputFrequencyOffset ) ;
m_sink . applyChannelSettings ( m_channelizer - > getChannelSampleRate ( ) , m_channelizer - > getChannelFrequencyOffset ( ) ) ;
}
m_sink . applySettings ( settings , force ) ;
m_settings = settings ;
}
int ADSBDemodBaseband : : getChannelSampleRate ( ) const
{
return m_channelizer - > getChannelSampleRate ( ) ;
}
void ADSBDemodBaseband : : setBasebandSampleRate ( int sampleRate )
{
m_channelizer - > setBasebandSampleRate ( sampleRate ) ;
m_sink . applyChannelSettings ( m_channelizer - > getChannelSampleRate ( ) , m_channelizer - > getChannelFrequencyOffset ( ) ) ;
}