2017-01-02 21:07:43 -05:00
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
2014-11-22 22:33:32 -05:00
# include <DemodulatorMgr.h>
2014-12-10 00:34:27 -05:00
# include <sstream>
# include <algorithm>
2014-12-11 20:50:58 -05:00
# include <string>
# include <sstream>
2016-02-11 00:08:56 -05:00
# include <algorithm>
2016-09-13 22:59:21 -04:00
# include "DemodulatorMgr.h"
2017-01-03 12:41:38 -05:00
# include "CubicSDR.h"
2016-09-13 22:59:21 -04:00
2016-02-29 23:14:23 -05:00
# if USE_HAMLIB
# include "RigThread.h"
# endif
2016-09-13 22:59:21 -04:00
# include "DataTree.h"
2016-02-11 00:08:56 -05:00
bool demodFreqCompare ( DemodulatorInstance * i , DemodulatorInstance * j ) { return ( i - > getFrequency ( ) < j - > getFrequency ( ) ) ; }
bool inactiveCompare ( DemodulatorInstance * i , DemodulatorInstance * j ) { return ( i - > isActive ( ) < j - > isActive ( ) ) ; }
2014-11-22 22:33:32 -05:00
2016-05-31 19:58:37 -04:00
DemodulatorMgr : : DemodulatorMgr ( ) {
activeDemodulator = NULL ;
lastActiveDemodulator = NULL ;
activeVisualDemodulator = NULL ;
lastBandwidth = DEFAULT_DEMOD_BW ;
lastDemodType = DEFAULT_DEMOD_TYPE ;
lastSquelchEnabled = false ;
lastSquelch = - 100 ;
lastGain = 1.0 ;
lastMuted = false ;
lastDeltaLock = false ;
2014-11-22 22:33:32 -05:00
}
DemodulatorMgr : : ~ DemodulatorMgr ( ) {
2014-12-16 21:30:03 -05:00
terminateAll ( ) ;
2014-11-22 22:33:32 -05:00
}
DemodulatorInstance * DemodulatorMgr : : newThread ( ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2014-12-16 21:30:03 -05:00
DemodulatorInstance * newDemod = new DemodulatorInstance ;
2014-12-10 00:34:27 -05:00
2014-12-16 21:30:03 -05:00
std : : stringstream label ;
label < < demods . size ( ) ;
newDemod - > setLabel ( label . str ( ) ) ;
2016-05-31 19:58:37 -04:00
demods . push_back ( newDemod ) ;
2014-12-16 21:30:03 -05:00
return newDemod ;
2014-11-22 22:33:32 -05:00
}
2014-11-23 19:39:27 -05:00
void DemodulatorMgr : : terminateAll ( ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2014-12-16 21:30:03 -05:00
while ( demods . size ( ) ) {
2016-06-02 17:56:31 -04:00
2014-12-16 21:30:03 -05:00
DemodulatorInstance * d = demods . back ( ) ;
2015-01-10 22:45:39 -05:00
demods . pop_back ( ) ;
2015-01-10 12:27:03 -05:00
wxGetApp ( ) . removeDemodulator ( d ) ;
2014-12-16 21:30:03 -05:00
deleteThread ( d ) ;
}
2014-11-23 19:39:27 -05:00
}
2014-11-26 21:05:19 -05:00
std : : vector < DemodulatorInstance * > & DemodulatorMgr : : getDemodulators ( ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2014-12-16 21:30:03 -05:00
return demods ;
2014-11-26 21:05:19 -05:00
}
2014-11-30 18:54:13 -05:00
2016-02-11 00:08:56 -05:00
std : : vector < DemodulatorInstance * > DemodulatorMgr : : getOrderedDemodulators ( bool actives ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-02-11 00:08:56 -05:00
std : : vector < DemodulatorInstance * > demods_ordered = demods ;
if ( actives ) {
std : : sort ( demods_ordered . begin ( ) , demods_ordered . end ( ) , inactiveCompare ) ;
std : : vector < DemodulatorInstance * > : : iterator i ;
for ( i = demods_ordered . begin ( ) ; i ! = demods_ordered . end ( ) ; i + + ) {
if ( ( * i ) - > isActive ( ) ) {
break ;
}
}
if ( i = = demods_ordered . end ( ) ) {
demods_ordered . erase ( demods_ordered . begin ( ) , demods_ordered . end ( ) ) ;
} else if ( ( * i ) ! = demods_ordered . front ( ) ) {
demods_ordered . erase ( demods_ordered . begin ( ) , i ) ;
}
}
2016-06-02 17:56:31 -04:00
//if by chance they have the same frequency, keep their relative order
std : : stable_sort ( demods_ordered . begin ( ) , demods_ordered . end ( ) , demodFreqCompare ) ;
2016-02-11 00:08:56 -05:00
return demods_ordered ;
}
DemodulatorInstance * DemodulatorMgr : : getPreviousDemodulator ( DemodulatorInstance * demod , bool actives ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-02-11 00:08:56 -05:00
if ( ! getLastActiveDemodulator ( ) ) {
return nullptr ;
}
std : : vector < DemodulatorInstance * > demods_ordered = getOrderedDemodulators ( actives ) ;
std : : vector < DemodulatorInstance * > : : iterator p = std : : find ( demods_ordered . begin ( ) , demods_ordered . end ( ) , demod ) ;
if ( p = = demods_ordered . end ( ) ) {
return nullptr ;
}
if ( * p = = demods_ordered . front ( ) ) {
return demods_ordered . back ( ) ;
}
return * ( - - p ) ;
}
DemodulatorInstance * DemodulatorMgr : : getNextDemodulator ( DemodulatorInstance * demod , bool actives ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-02-11 00:08:56 -05:00
if ( ! getLastActiveDemodulator ( ) ) {
return nullptr ;
}
std : : vector < DemodulatorInstance * > demods_ordered = getOrderedDemodulators ( actives ) ;
std : : vector < DemodulatorInstance * > : : iterator p = std : : find ( demods_ordered . begin ( ) , demods_ordered . end ( ) , demod ) ;
if ( actives ) {
}
if ( p = = demods_ordered . end ( ) ) {
return nullptr ;
}
if ( * p = = demods_ordered . back ( ) ) {
return demods_ordered . front ( ) ;
}
return * ( + + p ) ;
}
DemodulatorInstance * DemodulatorMgr : : getLastDemodulator ( ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-02-11 00:08:56 -05:00
std : : vector < DemodulatorInstance * > demods_ordered = getOrderedDemodulators ( ) ;
return * ( demods_ordered . end ( ) ) ;
}
DemodulatorInstance * DemodulatorMgr : : getFirstDemodulator ( ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-02-11 00:08:56 -05:00
std : : vector < DemodulatorInstance * > demods_ordered = getOrderedDemodulators ( ) ;
return * ( demods_ordered . begin ( ) ) ;
}
2014-12-10 21:22:13 -05:00
void DemodulatorMgr : : deleteThread ( DemodulatorInstance * demod ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-10-05 19:10:01 -04:00
wxGetApp ( ) . getBookmarkMgr ( ) . addRecent ( demod ) ;
2016-06-02 17:56:31 -04:00
2014-12-16 21:30:03 -05:00
std : : vector < DemodulatorInstance * > : : iterator i ;
2014-12-10 21:22:13 -05:00
2014-12-16 21:30:03 -05:00
i = std : : find ( demods . begin ( ) , demods . end ( ) , demod ) ;
2014-12-10 21:22:13 -05:00
2014-12-16 21:30:03 -05:00
if ( activeDemodulator = = demod ) {
2016-07-06 15:23:59 -04:00
activeDemodulator = nullptr ;
2014-12-16 21:30:03 -05:00
}
if ( lastActiveDemodulator = = demod ) {
2016-07-06 15:23:59 -04:00
lastActiveDemodulator = nullptr ;
2014-12-16 21:30:03 -05:00
}
if ( activeVisualDemodulator = = demod ) {
2016-07-06 15:23:59 -04:00
activeVisualDemodulator = nullptr ;
2014-12-16 21:30:03 -05:00
}
2014-12-10 21:22:13 -05:00
2014-12-16 21:30:03 -05:00
if ( i ! = demods . end ( ) ) {
demods . erase ( i ) ;
}
2016-07-03 03:47:28 -04:00
//Ask for termination
2016-07-06 15:23:59 -04:00
demod - > setActive ( false ) ;
2015-01-10 12:27:03 -05:00
demod - > terminate ( ) ;
2014-12-11 19:07:21 -05:00
2016-07-03 03:47:28 -04:00
//Do not cleanup immediatly
2017-05-24 12:55:37 -04:00
std : : lock_guard < std : : mutex > lock_deleted ( deleted_demods_busy ) ;
2014-12-16 21:30:03 -05:00
demods_deleted . push_back ( demod ) ;
2014-12-10 21:22:13 -05:00
}
2016-07-03 03:47:28 -04:00
std : : vector < DemodulatorInstance * > DemodulatorMgr : : getDemodulatorsAt ( long long freq , int bandwidth ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-07-03 03:47:28 -04:00
std : : vector < DemodulatorInstance * > foundDemods ;
2014-11-30 18:54:13 -05:00
2014-12-16 21:30:03 -05:00
for ( int i = 0 , iMax = demods . size ( ) ; i < iMax ; i + + ) {
DemodulatorInstance * testDemod = demods [ i ] ;
2014-11-30 18:54:13 -05:00
2015-02-02 18:24:04 -05:00
long long freqTest = testDemod - > getFrequency ( ) ;
long long bandwidthTest = testDemod - > getBandwidth ( ) ;
2015-01-04 17:11:20 -05:00
long long halfBandwidthTest = bandwidthTest / 2 ;
2014-11-30 18:54:13 -05:00
2015-01-04 17:11:20 -05:00
long long halfBuffer = bandwidth / 2 ;
2014-11-30 18:54:13 -05:00
2015-11-17 18:57:42 -05:00
if ( ( freq < = ( freqTest + ( ( testDemod - > getDemodulatorType ( ) ! = " LSB " ) ? halfBandwidthTest : 0 ) + halfBuffer ) ) & & ( freq > = ( freqTest - ( ( testDemod - > getDemodulatorType ( ) ! = " USB " ) ? halfBandwidthTest : 0 ) - halfBuffer ) ) ) {
2016-07-03 03:47:28 -04:00
foundDemods . push_back ( testDemod ) ;
2014-12-16 21:30:03 -05:00
}
}
2014-11-30 18:54:13 -05:00
2014-12-16 21:30:03 -05:00
return foundDemods ;
2014-11-30 18:54:13 -05:00
}
2014-12-10 00:34:27 -05:00
2016-01-13 21:29:26 -05:00
bool DemodulatorMgr : : anyDemodulatorsAt ( long long freq , int bandwidth ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-01-13 21:29:26 -05:00
for ( int i = 0 , iMax = demods . size ( ) ; i < iMax ; i + + ) {
DemodulatorInstance * testDemod = demods [ i ] ;
long long freqTest = testDemod - > getFrequency ( ) ;
long long bandwidthTest = testDemod - > getBandwidth ( ) ;
long long halfBandwidthTest = bandwidthTest / 2 ;
long long halfBuffer = bandwidth / 2 ;
if ( ( freq < = ( freqTest + ( ( testDemod - > getDemodulatorType ( ) ! = " LSB " ) ? halfBandwidthTest : 0 ) + halfBuffer ) ) & & ( freq > = ( freqTest - ( ( testDemod - > getDemodulatorType ( ) ! = " USB " ) ? halfBandwidthTest : 0 ) - halfBuffer ) ) ) {
2016-06-02 17:56:31 -04:00
2016-01-13 21:29:26 -05:00
return true ;
}
}
2016-06-02 17:56:31 -04:00
2016-01-13 21:29:26 -05:00
return false ;
}
2014-12-10 00:34:27 -05:00
void DemodulatorMgr : : setActiveDemodulator ( DemodulatorInstance * demod , bool temporary ) {
2016-07-06 15:23:59 -04:00
2014-12-16 21:30:03 -05:00
if ( ! temporary ) {
2016-07-06 15:23:59 -04:00
if ( activeDemodulator . load ( ) ! = nullptr ) {
lastActiveDemodulator = activeDemodulator . load ( ) ;
2015-11-26 01:54:54 -05:00
updateLastState ( ) ;
2014-12-16 21:30:03 -05:00
} else {
lastActiveDemodulator = demod ;
}
2015-02-02 20:10:55 -05:00
updateLastState ( ) ;
2016-02-29 23:14:23 -05:00
# if USE_HAMLIB
2016-07-06 15:23:59 -04:00
if ( wxGetApp ( ) . rigIsActive ( ) & & wxGetApp ( ) . getRigThread ( ) - > getFollowModem ( ) & & lastActiveDemodulator . load ( ) ) {
wxGetApp ( ) . getRigThread ( ) - > setFrequency ( lastActiveDemodulator . load ( ) - > getFrequency ( ) , true ) ;
2016-02-29 23:14:23 -05:00
}
# endif
2016-09-29 20:47:38 -04:00
wxGetApp ( ) . getBookmarkMgr ( ) . updateActiveList ( ) ;
2017-05-24 12:55:37 -04:00
}
2014-12-16 21:30:03 -05:00
2016-07-06 15:23:59 -04:00
if ( activeVisualDemodulator . load ( ) ) {
activeVisualDemodulator . load ( ) - > setVisualOutputQueue ( nullptr ) ;
2014-12-16 21:30:03 -05:00
}
if ( demod ) {
demod - > setVisualOutputQueue ( wxGetApp ( ) . getAudioVisualQueue ( ) ) ;
activeVisualDemodulator = demod ;
} else {
DemodulatorInstance * last = getLastActiveDemodulator ( ) ;
if ( last ) {
last - > setVisualOutputQueue ( wxGetApp ( ) . getAudioVisualQueue ( ) ) ;
}
activeVisualDemodulator = last ;
}
activeDemodulator = demod ;
2016-06-02 17:56:31 -04:00
2014-12-10 00:34:27 -05:00
}
DemodulatorInstance * DemodulatorMgr : : getActiveDemodulator ( ) {
2016-07-06 15:23:59 -04:00
if ( activeDemodulator . load ( ) & & ! activeDemodulator . load ( ) - > isActive ( ) ) {
2015-02-05 20:54:04 -05:00
activeDemodulator = getLastActiveDemodulator ( ) ;
}
2014-12-16 21:30:03 -05:00
return activeDemodulator ;
2014-12-10 00:34:27 -05:00
}
DemodulatorInstance * DemodulatorMgr : : getLastActiveDemodulator ( ) {
2014-12-16 21:30:03 -05:00
return lastActiveDemodulator ;
2014-12-10 00:34:27 -05:00
}
2014-12-11 19:07:21 -05:00
2017-04-01 13:38:08 -04:00
DemodulatorInstance * DemodulatorMgr : : getLastDemodulatorWith ( const std : : string & type ,
const std : : wstring & userLabel ,
long long frequency ,
int bandwidth ) {
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
//backwards search:
for ( std : : vector < DemodulatorInstance * > : : reverse_iterator it = demods . rbegin ( ) ; it ! = demods . rend ( ) ; it + + ) {
if ( ( * it ) - > getDemodulatorType ( ) = = type & &
( * it ) - > getDemodulatorUserLabel ( ) = = userLabel & &
( * it ) - > getFrequency ( ) = = frequency & &
( * it ) - > getBandwidth ( ) = = bandwidth ) {
return ( * it ) ;
}
}
return nullptr ;
}
2017-08-13 06:11:14 -04:00
bool DemodulatorMgr : : garbageCollect ( bool forcedGC , int maxWaitForTerminationMs ) {
2017-05-24 12:55:37 -04:00
2017-08-12 05:30:32 -04:00
# define SPIN_WAIT_SLEEP_MS 5
//this is a stupid busy plus sleep loop
int nbCyclesToWait = 0 ;
if ( maxWaitForTerminationMs < = 0 ) {
nbCyclesToWait = std : : numeric_limits < int > : : max ( ) ;
}
else {
nbCyclesToWait = ( maxWaitForTerminationMs / SPIN_WAIT_SLEEP_MS ) + 1 ;
}
int currentWaitCycle = 0 ;
2017-05-24 12:55:37 -04:00
std : : lock_guard < std : : mutex > lock ( deleted_demods_busy ) ;
2014-12-11 19:07:21 -05:00
2017-06-01 13:56:33 -04:00
while ( ! demods_deleted . empty ( ) ) {
2014-12-11 19:07:21 -05:00
2017-06-01 13:56:33 -04:00
std : : vector < DemodulatorInstance * > : : iterator it = demods_deleted . begin ( ) ;
//make 1 pass over
while ( it ! = demods_deleted . end ( ) ) {
2014-12-11 19:07:21 -05:00
2017-06-01 13:56:33 -04:00
if ( ( * it ) - > isTerminated ( ) ) {
2017-05-24 06:24:36 -04:00
2017-06-01 13:56:33 -04:00
DemodulatorInstance * deleted = ( * it ) ;
2017-05-24 12:55:37 -04:00
2017-06-01 13:56:33 -04:00
std : : cout < < " Garbage collected demodulator instance ' " < < deleted - > getLabel ( ) < < " '... " < < std : : endl < < std : : flush ;
it = demods_deleted . erase ( it ) ;
delete deleted ;
//only garbage collect 1 demod at a time.
if ( ! forcedGC ) {
2017-08-13 06:11:14 -04:00
return true ;
2017-06-01 13:56:33 -04:00
}
}
else {
it + + ;
}
} //end while
//stupid busy-wait loop
2017-08-12 05:30:32 -04:00
std : : this_thread : : sleep_for ( std : : chrono : : milliseconds ( SPIN_WAIT_SLEEP_MS ) ) ;
currentWaitCycle + + ;
if ( currentWaitCycle > = nbCyclesToWait ) {
std : : cout < < " ERROR: DemodulatorMgr::garbageCollect() has not terminated in time ! (> " < < ( currentWaitCycle * SPIN_WAIT_SLEEP_MS ) < < " ms) " < < std : : endl < < std : : flush ;
2017-08-13 06:11:14 -04:00
return false ;
2017-08-12 05:30:32 -04:00
}
2017-06-01 13:56:33 -04:00
} //end while not empty
2017-08-13 06:11:14 -04:00
return true ;
2014-12-11 19:07:21 -05:00
}
2015-02-02 20:10:55 -05:00
void DemodulatorMgr : : updateLastState ( ) {
2016-06-02 17:56:31 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-07-06 15:23:59 -04:00
2015-02-02 20:10:55 -05:00
if ( std : : find ( demods . begin ( ) , demods . end ( ) , lastActiveDemodulator ) = = demods . end ( ) ) {
2016-07-06 15:23:59 -04:00
if ( activeDemodulator . load ( ) & & activeDemodulator . load ( ) - > isActive ( ) ) {
lastActiveDemodulator = activeDemodulator . load ( ) ;
} else if ( activeDemodulator . load ( ) & & ! activeDemodulator . load ( ) - > isActive ( ) ) {
activeDemodulator = nullptr ;
lastActiveDemodulator = nullptr ;
2015-02-05 20:54:04 -05:00
}
}
2016-07-06 15:23:59 -04:00
if ( lastActiveDemodulator . load ( ) & & ! lastActiveDemodulator . load ( ) - > isActive ( ) ) {
lastActiveDemodulator = nullptr ;
2015-02-02 20:10:55 -05:00
}
2016-07-06 15:23:59 -04:00
if ( lastActiveDemodulator . load ( ) ) {
lastBandwidth = lastActiveDemodulator . load ( ) - > getBandwidth ( ) ;
lastDemodType = lastActiveDemodulator . load ( ) - > getDemodulatorType ( ) ;
lastDemodLock = lastActiveDemodulator . load ( ) - > getDemodulatorLock ( ) ? true : false ;
lastSquelchEnabled = lastActiveDemodulator . load ( ) - > isSquelchEnabled ( ) ;
lastSquelch = lastActiveDemodulator . load ( ) - > getSquelchLevel ( ) ;
lastGain = lastActiveDemodulator . load ( ) - > getGain ( ) ;
lastModemSettings [ lastDemodType ] = lastActiveDemodulator . load ( ) - > readModemSettings ( ) ;
2015-02-02 20:10:55 -05:00
}
}
int DemodulatorMgr : : getLastBandwidth ( ) const {
return lastBandwidth ;
}
void DemodulatorMgr : : setLastBandwidth ( int lastBandwidth ) {
2015-12-01 00:59:11 -05:00
if ( lastBandwidth < MIN_BANDWIDTH ) {
lastBandwidth = MIN_BANDWIDTH ;
2015-02-02 20:10:55 -05:00
} else if ( lastBandwidth > wxGetApp ( ) . getSampleRate ( ) ) {
lastBandwidth = wxGetApp ( ) . getSampleRate ( ) ;
}
this - > lastBandwidth = lastBandwidth ;
}
2015-11-17 18:57:42 -05:00
std : : string DemodulatorMgr : : getLastDemodulatorType ( ) const {
2015-02-02 20:10:55 -05:00
return lastDemodType ;
}
2015-11-17 18:57:42 -05:00
void DemodulatorMgr : : setLastDemodulatorType ( std : : string lastDemodType ) {
2015-02-02 20:10:55 -05:00
this - > lastDemodType = lastDemodType ;
}
float DemodulatorMgr : : getLastGain ( ) const {
return lastGain ;
}
void DemodulatorMgr : : setLastGain ( float lastGain ) {
this - > lastGain = lastGain ;
}
2016-02-15 17:43:10 -05:00
bool DemodulatorMgr : : getLastDeltaLock ( ) const {
return lastDeltaLock ;
}
void DemodulatorMgr : : setLastDeltaLock ( bool lock ) {
lastDeltaLock = lock ;
}
2015-02-02 20:10:55 -05:00
float DemodulatorMgr : : getLastSquelchLevel ( ) const {
return lastSquelch ;
}
void DemodulatorMgr : : setLastSquelchLevel ( float lastSquelch ) {
this - > lastSquelch = lastSquelch ;
}
bool DemodulatorMgr : : isLastSquelchEnabled ( ) const {
return lastSquelchEnabled ;
}
void DemodulatorMgr : : setLastSquelchEnabled ( bool lastSquelchEnabled ) {
this - > lastSquelchEnabled = lastSquelchEnabled ;
}
2015-08-19 17:06:06 -04:00
bool DemodulatorMgr : : isLastMuted ( ) const {
return lastMuted ;
}
void DemodulatorMgr : : setLastMuted ( bool lastMuted ) {
this - > lastMuted = lastMuted ;
}
2015-11-26 01:54:54 -05:00
ModemSettings DemodulatorMgr : : getLastModemSettings ( std : : string modemType ) {
return lastModemSettings [ modemType ] ;
}
void DemodulatorMgr : : setLastModemSettings ( std : : string modemType , ModemSettings settings ) {
lastModemSettings [ modemType ] = settings ;
}
2016-09-13 22:59:21 -04:00
void DemodulatorMgr : : setOutputDevices ( std : : map < int , RtAudio : : DeviceInfo > devs ) {
outputDevices = devs ;
}
void DemodulatorMgr : : saveInstance ( DataNode * node , DemodulatorInstance * inst ) {
* node - > newChild ( " bandwidth " ) = inst - > getBandwidth ( ) ;
2017-02-18 04:48:56 -05:00
* node - > newChild ( " frequency " ) = inst - > getFrequency ( ) ;
2016-09-13 22:59:21 -04:00
* node - > newChild ( " type " ) = inst - > getDemodulatorType ( ) ;
node - > newChild ( " user_label " ) - > element ( ) - > set ( inst - > getDemodulatorUserLabel ( ) ) ;
* node - > newChild ( " squelch_level " ) = inst - > getSquelchLevel ( ) ;
* node - > newChild ( " squelch_enabled " ) = inst - > isSquelchEnabled ( ) ? 1 : 0 ;
* node - > newChild ( " output_device " ) = outputDevices [ inst - > getOutputDevice ( ) ] . name ;
* node - > newChild ( " gain " ) = inst - > getGain ( ) ;
* node - > newChild ( " muted " ) = inst - > isMuted ( ) ? 1 : 0 ;
if ( inst - > isDeltaLock ( ) ) {
* node - > newChild ( " delta_lock " ) = inst - > isDeltaLock ( ) ? 1 : 0 ;
* node - > newChild ( " delta_ofs " ) = inst - > getDeltaLockOfs ( ) ;
}
if ( inst = = getLastActiveDemodulator ( ) ) {
* node - > newChild ( " active " ) = 1 ;
}
ModemSettings saveSettings = inst - > readModemSettings ( ) ;
if ( saveSettings . size ( ) ) {
DataNode * settingsNode = node - > newChild ( " settings " ) ;
for ( ModemSettings : : const_iterator msi = saveSettings . begin ( ) ; msi ! = saveSettings . end ( ) ; msi + + ) {
* settingsNode - > newChild ( msi - > first . c_str ( ) ) = msi - > second ;
}
}
}
DemodulatorInstance * DemodulatorMgr : : loadInstance ( DataNode * node ) {
2017-04-01 13:38:08 -04:00
std : : lock_guard < std : : recursive_mutex > lock ( demods_busy ) ;
2016-09-13 22:59:21 -04:00
DemodulatorInstance * newDemod = nullptr ;
2017-04-01 13:38:08 -04:00
2016-10-05 19:10:01 -04:00
node - > rewindAll ( ) ;
2016-09-13 22:59:21 -04:00
long bandwidth = * node - > getNext ( " bandwidth " ) ;
long long freq = * node - > getNext ( " frequency " ) ;
float squelch_level = node - > hasAnother ( " squelch_level " ) ? ( float ) * node - > getNext ( " squelch_level " ) : 0 ;
int squelch_enabled = node - > hasAnother ( " squelch_enabled " ) ? ( int ) * node - > getNext ( " squelch_enabled " ) : 0 ;
int muted = node - > hasAnother ( " muted " ) ? ( int ) * node - > getNext ( " muted " ) : 0 ;
int delta_locked = node - > hasAnother ( " delta_lock " ) ? ( int ) * node - > getNext ( " delta_lock " ) : 0 ;
int delta_ofs = node - > hasAnother ( " delta_ofs " ) ? ( int ) * node - > getNext ( " delta_ofs " ) : 0 ;
std : : string output_device = node - > hasAnother ( " output_device " ) ? string ( * ( node - > getNext ( " output_device " ) ) ) : " " ;
float gain = node - > hasAnother ( " gain " ) ? ( float ) * node - > getNext ( " gain " ) : 1.0 ;
std : : string type = " FM " ;
DataNode * demodTypeNode = node - > hasAnother ( " type " ) ? node - > getNext ( " type " ) : nullptr ;
if ( demodTypeNode & & demodTypeNode - > element ( ) - > getDataType ( ) = = DATA_INT ) {
int legacyType = * demodTypeNode ;
int legacyStereo = node - > hasAnother ( " stereo " ) ? ( int ) * node - > getNext ( " stereo " ) : 0 ;
switch ( legacyType ) { // legacy demod ID
case 1 : type = legacyStereo ? " FMS " : " FM " ; break ;
case 2 : type = " AM " ; break ;
case 3 : type = " LSB " ; break ;
case 4 : type = " USB " ; break ;
case 5 : type = " DSB " ; break ;
case 6 : type = " ASK " ; break ;
case 7 : type = " APSK " ; break ;
case 8 : type = " BPSK " ; break ;
case 9 : type = " DPSK " ; break ;
case 10 : type = " PSK " ; break ;
case 11 : type = " OOK " ; break ;
case 12 : type = " ST " ; break ;
case 13 : type = " SQAM " ; break ;
case 14 : type = " QAM " ; break ;
case 15 : type = " QPSK " ; break ;
case 16 : type = " I/Q " ; break ;
default : type = " FM " ; break ;
}
} else if ( demodTypeNode & & demodTypeNode - > element ( ) - > getDataType ( ) = = DATA_STRING ) {
demodTypeNode - > element ( ) - > get ( type ) ;
}
//read the user label associated with the demodulator
std : : wstring user_label = L " " ;
DataNode * demodUserLabel = node - > hasAnother ( " user_label " ) ? node - > getNext ( " user_label " ) : nullptr ;
if ( demodUserLabel ) {
demodUserLabel - > element ( ) - > get ( user_label ) ;
}
ModemSettings mSettings ;
if ( node - > hasAnother ( " settings " ) ) {
DataNode * modemSettings = node - > getNext ( " settings " ) ;
for ( int msi = 0 , numSettings = modemSettings - > numChildren ( ) ; msi < numSettings ; msi + + ) {
DataNode * settingNode = modemSettings - > child ( msi ) ;
std : : string keyName = settingNode - > getName ( ) ;
std : : string strSettingValue = settingNode - > element ( ) - > toString ( ) ;
if ( keyName ! = " " & & strSettingValue ! = " " ) {
mSettings [ keyName ] = strSettingValue ;
}
}
}
2017-04-01 13:38:08 -04:00
newDemod = newThread ( ) ;
2016-09-13 22:59:21 -04:00
newDemod - > setDemodulatorType ( type ) ;
newDemod - > setDemodulatorUserLabel ( user_label ) ;
newDemod - > writeModemSettings ( mSettings ) ;
newDemod - > setBandwidth ( bandwidth ) ;
newDemod - > setFrequency ( freq ) ;
newDemod - > setGain ( gain ) ;
newDemod - > updateLabel ( freq ) ;
newDemod - > setMuted ( muted ? true : false ) ;
if ( delta_locked ) {
newDemod - > setDeltaLock ( true ) ;
newDemod - > setDeltaLockOfs ( delta_ofs ) ;
}
if ( squelch_enabled ) {
newDemod - > setSquelchEnabled ( true ) ;
newDemod - > setSquelchLevel ( squelch_level ) ;
}
2017-04-01 13:38:08 -04:00
//Attach to sound output:
2016-09-13 22:59:21 -04:00
std : : map < int , RtAudio : : DeviceInfo > : : iterator i ;
for ( i = outputDevices . begin ( ) ; i ! = outputDevices . end ( ) ; i + + ) {
if ( i - > second . name = = output_device ) {
newDemod - > setOutputDevice ( i - > first ) ;
2017-04-01 13:38:08 -04:00
break ;
2016-09-13 22:59:21 -04:00
}
}
return newDemod ;
}