2019-01-30 23:24:33 -05:00
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
# include "SessionMgr.h"
# include "CubicSDR.h"
void SessionMgr : : saveSession ( std : : string fileName ) {
DataTree s ( " cubicsdr_session " ) ;
DataNode * header = s . rootNode ( ) - > newChild ( " header " ) ;
//save as wstring to prevent problems
header - > newChild ( " version " ) - > element ( ) - > set ( wxString ( CUBICSDR_VERSION ) . ToStdWstring ( ) ) ;
* header - > newChild ( " center_freq " ) = wxGetApp ( ) . getFrequency ( ) ;
* header - > newChild ( " sample_rate " ) = wxGetApp ( ) . getSampleRate ( ) ;
* header - > newChild ( " solo_mode " ) = wxGetApp ( ) . getSoloMode ( ) ? 1 : 0 ;
WaterfallCanvas * waterfallCanvas = wxGetApp ( ) . getAppFrame ( ) - > getWaterfallCanvas ( ) ;
if ( waterfallCanvas - > getViewState ( ) ) {
DataNode * viewState = header - > newChild ( " view_state " ) ;
* viewState - > newChild ( " center_freq " ) = waterfallCanvas - > getCenterFrequency ( ) ;
* viewState - > newChild ( " bandwidth " ) = waterfallCanvas - > getBandwidth ( ) ;
}
DataNode * demods = s . rootNode ( ) - > newChild ( " demodulators " ) ;
//make a local copy snapshot of the list
std : : vector < DemodulatorInstancePtr > instances = wxGetApp ( ) . getDemodMgr ( ) . getDemodulators ( ) ;
for ( const auto & instance : instances ) {
DataNode * demod = demods - > newChild ( " demodulator " ) ;
wxGetApp ( ) . getDemodMgr ( ) . saveInstance ( demod , instance ) ;
} //end for demodulators
// Make sure the file name actually ends in .xml
std : : string lcFileName = fileName ;
std : : transform ( lcFileName . begin ( ) , lcFileName . end ( ) , lcFileName . begin ( ) , : : tolower ) ;
if ( lcFileName . find_last_of ( " .xml " ) ! = lcFileName . length ( ) - 1 ) {
fileName . append ( " .xml " ) ;
}
s . SaveToFileXML ( fileName ) ;
}
2021-04-04 22:22:16 -04:00
bool SessionMgr : : loadSession ( const std : : string & fileName ) {
2019-01-30 23:24:33 -05:00
DataTree l ;
if ( ! l . LoadFromFileXML ( fileName ) ) {
return false ;
}
//Check if it is a session file, read the root node.
if ( l . rootNode ( ) - > getName ( ) ! = " cubicsdr_session " ) {
return false ;
}
wxGetApp ( ) . getDemodMgr ( ) . setActiveDemodulator ( nullptr , false ) ;
wxGetApp ( ) . getDemodMgr ( ) . terminateAll ( ) ;
WaterfallCanvas * waterfallCanvas = wxGetApp ( ) . getAppFrame ( ) - > getWaterfallCanvas ( ) ;
SpectrumCanvas * spectrumCanvas = wxGetApp ( ) . getAppFrame ( ) - > getSpectrumCanvas ( ) ;
try {
if ( ! l . rootNode ( ) - > hasAnother ( " header " ) ) {
return false ;
}
DataNode * header = l . rootNode ( ) - > getNext ( " header " ) ;
if ( header - > hasAnother ( " version " ) ) {
2021-12-29 13:54:03 -05:00
//"Force" the retrieving of the value as string, even if it looks like a number internally ! (ex: "0.2.0")
2019-01-30 23:24:33 -05:00
DataNode * versionNode = header - > getNext ( " version " ) ;
std : : wstring version ;
try {
versionNode - > element ( ) - > get ( version ) ;
std : : cout < < " Loading session file version: ' " < < version < < " '... " < < std : : endl ;
}
catch ( DataTypeMismatchException & e ) {
//this is for managing the old session format NOT encoded as std:wstring,
//force current version
std : : cout < < " Warning while Loading session file version, probably old format :' " < < e . what ( ) < < " ' please consider re-saving the current session... " < < std : : endl < < std : : flush ;
version = wxString ( CUBICSDR_VERSION ) . ToStdWstring ( ) ;
}
}
if ( header - > hasAnother ( " sample_rate " ) ) {
2021-04-04 22:22:16 -04:00
long sample_rate = ( long ) * header - > getNext ( " sample_rate " ) ;
2019-01-30 23:24:33 -05:00
SDRDeviceInfo * dev = wxGetApp ( ) . getSDRThread ( ) - > getDevice ( ) ;
if ( dev ) {
2021-12-29 13:54:03 -05:00
//retrieve the available sample rates. A valid previously chosen manual
2019-01-30 23:24:33 -05:00
//value is constrained within these limits. If it doesn't behave, lets the device choose
//for us.
long minRate = MANUAL_SAMPLE_RATE_MIN ;
long maxRate = MANUAL_SAMPLE_RATE_MAX ;
std : : vector < long > sampleRates = dev - > getSampleRates ( SOAPY_SDR_RX , 0 ) ;
if ( ! sampleRates . empty ( ) ) {
minRate = sampleRates . front ( ) ;
maxRate = sampleRates . back ( ) ;
}
//If it is beyond limits, make device choose a reasonable value
if ( sample_rate < minRate | | sample_rate > maxRate ) {
sample_rate = dev - > getSampleRateNear ( SOAPY_SDR_RX , 0 , sample_rate ) ;
}
//update applied value
wxGetApp ( ) . setSampleRate ( sample_rate ) ;
} else {
wxGetApp ( ) . setSampleRate ( sample_rate ) ;
}
}
if ( header - > hasAnother ( " solo_mode " ) ) {
2021-04-04 22:22:16 -04:00
int solo_mode_activated = ( int ) * header - > getNext ( " solo_mode " ) ;
2019-01-30 23:24:33 -05:00
wxGetApp ( ) . setSoloMode ( solo_mode_activated > 0 ) ;
}
else {
wxGetApp ( ) . setSoloMode ( false ) ;
}
DemodulatorInstancePtr loadedActiveDemod = nullptr ;
DemodulatorInstancePtr newDemod = nullptr ;
if ( l . rootNode ( ) - > hasAnother ( " demodulators " ) ) {
DataNode * demodulators = l . rootNode ( ) - > getNext ( " demodulators " ) ;
std : : vector < DemodulatorInstancePtr > demodsLoaded ;
while ( demodulators - > hasAnother ( " demodulator " ) ) {
DataNode * demod = demodulators - > getNext ( " demodulator " ) ;
if ( ! demod - > hasAnother ( " bandwidth " ) | | ! demod - > hasAnother ( " frequency " ) ) {
continue ;
}
newDemod = wxGetApp ( ) . getDemodMgr ( ) . loadInstance ( demod ) ;
if ( demod - > hasAnother ( " active " ) ) {
loadedActiveDemod = newDemod ;
}
newDemod - > run ( ) ;
newDemod - > setActive ( true ) ;
demodsLoaded . push_back ( newDemod ) ;
}
if ( ! demodsLoaded . empty ( ) ) {
wxGetApp ( ) . notifyDemodulatorsChanged ( ) ;
}
} // if l.rootNode()->hasAnother("demodulators")
if ( header - > hasAnother ( " center_freq " ) ) {
2021-04-04 22:22:16 -04:00
long long center_freq = ( long long ) * header - > getNext ( " center_freq " ) ;
2019-01-30 23:24:33 -05:00
wxGetApp ( ) . setFrequency ( center_freq ) ;
// std::cout << "\tCenter Frequency: " << center_freq << std::endl;
}
if ( header - > hasAnother ( " view_state " ) ) {
DataNode * viewState = header - > getNext ( " view_state " ) ;
if ( viewState - > hasAnother ( " center_freq " ) & & viewState - > hasAnother ( " bandwidth " ) ) {
2021-04-04 22:22:16 -04:00
auto center_freq = ( long long ) * viewState - > getNext ( " center_freq " ) ;
auto bandwidth = ( int ) * viewState - > getNext ( " bandwidth " ) ;
2019-01-30 23:24:33 -05:00
spectrumCanvas - > setView ( center_freq , bandwidth ) ;
waterfallCanvas - > setView ( center_freq , bandwidth ) ;
}
} else {
spectrumCanvas - > disableView ( ) ;
waterfallCanvas - > disableView ( ) ;
spectrumCanvas - > setCenterFrequency ( wxGetApp ( ) . getFrequency ( ) ) ;
waterfallCanvas - > setCenterFrequency ( wxGetApp ( ) . getFrequency ( ) ) ;
}
if ( loadedActiveDemod | | newDemod ) {
wxGetApp ( ) . getDemodMgr ( ) . setActiveDemodulator ( loadedActiveDemod ? loadedActiveDemod : newDemod , false ) ;
}
} catch ( DataTypeMismatchException & e ) {
std : : cout < < e . what ( ) < < std : : endl ;
return false ;
}
return true ;
}