2021-03-22 22:26:21 +01:00
# include "live.h"
2021-03-31 18:15:26 +02:00
# ifdef BUILD_LIVE
2021-03-22 22:26:21 +01:00
# include "imgui/imgui.h"
# include "global.h"
# include "pipeline.h"
# include <cstring>
# include "logger.h"
2021-06-16 16:33:05 +02:00
# ifndef __ANDROID__
2021-03-22 22:26:21 +01:00
# include "portable-file-dialogs.h"
2021-06-16 16:33:05 +02:00
# endif
2021-03-22 22:26:21 +01:00
# include "processing.h"
# include <filesystem>
2021-03-23 22:47:59 +00:00
# include "sdr/sdr.h"
2021-03-31 18:15:26 +02:00
# include "live_run.h"
# include "sdr/sdr.h"
2021-06-06 14:11:02 +02:00
# include "settings.h"
2021-06-06 17:29:00 +02:00
# include "live_pipeline.h"
2021-06-06 14:11:02 +02:00
2021-06-16 16:33:05 +02:00
# ifdef __ANDROID__
std : : string getFilePath ( ) ;
std : : string getDirPath ( ) ;
# endif
2021-03-31 18:15:26 +02:00
std : : shared_ptr < SDRDevice > radio ;
2021-06-06 17:29:00 +02:00
extern std : : shared_ptr < dsp : : stream < std : : complex < float > > > moduleStream ;
std : : shared_ptr < LivePipeline > live_pipeline ;
2021-03-22 22:26:21 +01:00
int device_id = 0 ;
2021-05-25 21:25:42 +02:00
std : : map < std : : string , std : : string > device_parameters ;
2021-03-22 22:26:21 +01:00
2021-03-31 18:15:26 +02:00
std : : vector < std : : tuple < std : : string , sdr_device_type , uint64_t > > devices ;
2021-03-23 22:47:59 +00:00
2021-06-06 14:11:02 +02:00
bool first_init = true ;
2021-03-23 22:47:59 +00:00
void initLive ( )
{
2021-06-06 14:11:02 +02:00
if ( first_init )
{
initSDRs ( ) ;
first_init = false ;
}
2021-03-23 22:47:59 +00:00
devices = getAllDevices ( ) ;
}
2021-06-25 20:18:23 +02:00
// This is VERY temporary... I hope
# ifdef __ANDROID__
extern bool rtlsdr_device_android_ready ;
extern int rtlsdr_device_android_fd ;
extern std : : string rtlsdr_device_android_path ;
# include "sdr/rtlsdr.h"
extern bool airspy_device_android_ready ;
extern int airspy_device_android_fd ;
extern std : : string airspy_device_android_path ;
# include "sdr/airspy.h"
# endif
2021-03-22 22:26:21 +01:00
void renderLiveProcessing ( )
{
ImGui : : BeginGroup ( ) ;
{
std : : string names ;
std : : map < int , std : : string > id_table ;
2021-05-28 20:43:36 +02:00
for ( int i = 0 , y = 0 ; i < ( int ) pipelines . size ( ) ; i + + )
2021-03-22 22:26:21 +01:00
{
if ( pipelines [ i ] . live )
{
names + = pipelines [ i ] . readable_name + ' \0 ' ;
id_table . insert ( { y + + , pipelines [ i ] . name } ) ;
}
}
ImGui : : Text ( " Pipeline : " ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : Combo ( " ##pipeline " , & pipeline_id , names . c_str ( ) ) )
{
downlink_pipeline = id_table [ pipeline_id ] ;
std : : vector < Pipeline > : : iterator it = std : : find_if ( pipelines . begin ( ) ,
pipelines . end ( ) ,
2021-06-06 14:11:02 +02:00
[ ] ( const Pipeline & e )
{
2021-03-22 22:26:21 +01:00
return e . name = = downlink_pipeline ;
} ) ;
std : : memcpy ( samplerate , std : : to_string ( it - > default_samplerate ) . c_str ( ) , std : : to_string ( it - > default_samplerate ) . length ( ) ) ;
frequency = it - > frequencies [ frequency_id ] ;
}
// ImGui::EndCombo();
}
ImGui : : EndGroup ( ) ;
ImGui : : BeginGroup ( ) ;
{
ImGui : : Text ( " Output dir : " ) ;
ImGui : : SameLine ( ) ;
if ( ImGui : : Button ( " Select Output " ) )
{
logger - > debug ( " Opening file dialog " ) ;
2021-06-16 16:33:05 +02:00
# ifdef __ANDROID__
output_file = getDirPath ( ) ;
# else
2021-03-22 22:26:21 +01:00
auto result = pfd : : select_folder ( " Open output directory " , " . " ) ;
while ( result . ready ( 1000 ) )
{
}
if ( result . result ( ) . size ( ) > 0 )
output_file = result . result ( ) ;
2021-06-16 16:33:05 +02:00
# endif
2021-03-22 22:26:21 +01:00
logger - > debug ( " Dir " + output_file ) ;
}
ImGui : : SameLine ( ) ;
2021-06-16 16:33:05 +02:00
ImGui : : Text ( " %s " , output_file . c_str ( ) ) ;
2021-03-22 22:26:21 +01:00
}
ImGui : : EndGroup ( ) ;
ImGui : : Separator ( ) ;
ImGui : : BeginGroup ( ) ;
{
ImGui : : Text ( " Device : " ) ;
ImGui : : SameLine ( ) ;
{
2021-03-23 22:47:59 +00:00
std : : string names ; // = "baseband\0";
2021-05-28 20:43:36 +02:00
for ( int i = 0 ; i < ( int ) devices . size ( ) ; i + + )
2021-03-23 22:47:59 +00:00
{
2021-03-31 18:15:26 +02:00
names + = std : : get < 0 > ( devices [ i ] ) + " " + ' \0 ' ;
2021-03-23 22:47:59 +00:00
}
2021-03-22 22:26:21 +01:00
if ( ImGui : : Combo ( " ##device " , & device_id , names . c_str ( ) ) )
{
//frequency = it->frequencies[frequency_id];
}
}
2021-05-25 21:25:42 +02:00
device_parameters = drawParamsUIForID ( devices , device_id ) ;
2021-03-22 22:26:21 +01:00
ImGui : : Text ( " Frequency : " ) ;
ImGui : : SameLine ( ) ;
{
std : : string names ; // = "baseband\0";
std : : vector < Pipeline > : : iterator it = std : : find_if ( pipelines . begin ( ) ,
pipelines . end ( ) ,
2021-06-06 14:11:02 +02:00
[ ] ( const Pipeline & e )
{
2021-03-22 22:26:21 +01:00
return e . name = = downlink_pipeline ;
} ) ;
if ( it ! = pipelines . end ( ) )
2021-05-28 20:43:36 +02:00
for ( int i = 0 ; i < ( int ) it - > frequencies . size ( ) ; i + + )
2021-03-22 22:26:21 +01:00
{
names + = std : : to_string ( it - > frequencies [ i ] ) + " Mhz " + ' \0 ' ;
}
if ( ImGui : : Combo ( " ##frequency " , & frequency_id , names . c_str ( ) ) )
{
frequency = it - > frequencies [ frequency_id ] ;
}
}
ImGui : : Checkbox ( " DC Block " , & dc_block ) ;
ImGui : : Text ( " Samplerate (Hz / SPS) " ) ;
ImGui : : SameLine ( ) ;
ImGui : : InputText ( " ##samplerate " , samplerate , 100 ) ;
if ( ImGui : : Button ( " Start " ) )
{
logger - > debug ( " Starting livedemod... " ) ;
if ( output_file = = " " )
{
sprintf ( error_message , " Please select an output file! " ) ;
}
else if ( downlink_pipeline = = " " )
{
sprintf ( error_message , " Please select a pipeline! " ) ;
}
else if ( frequency < = 0 )
{
sprintf ( error_message , " Please select a frequency! " ) ;
}
else if ( std : : stoi ( samplerate ) < = 0 )
{
sprintf ( error_message , " Please select a samplerate! " ) ;
}
else
{
if ( ! std : : filesystem : : exists ( output_file ) )
std : : filesystem : : create_directory ( output_file ) ;
logger - > info ( downlink_pipeline ) ;
std : : vector < Pipeline > : : iterator it = std : : find_if ( pipelines . begin ( ) ,
pipelines . end ( ) ,
2021-06-06 14:11:02 +02:00
[ ] ( const Pipeline & e )
{
2021-03-22 22:26:21 +01:00
return e . name = = downlink_pipeline ;
} ) ;
if ( it ! = pipelines . end ( ) )
{
parameters . emplace ( " samplerate " , std : : string ( samplerate ) ) ;
parameters . emplace ( " baseband_format " , " f32 " ) ;
parameters . emplace ( " dc_block " , dc_block ? " 1 " : " 0 " ) ;
2021-06-06 17:29:00 +02:00
live_pipeline = std : : make_shared < LivePipeline > ( * it , parameters , output_file ) ;
2021-03-31 18:15:26 +02:00
logger - > debug ( " Starting SDR... " ) ;
2021-06-06 14:11:02 +02:00
std : : string devID = getDeviceIDStringByID ( devices , device_id ) ;
std : : map < std : : string , std : : string > settings_parameters = settings [ " sdr " ] . count ( devID ) > 0 ? settings [ " sdr " ] [ devID ] . get < std : : map < std : : string , std : : string > > ( ) : std : : map < std : : string , std : : string > ( ) ;
for ( const std : : pair < std : : string , std : : string > param : settings_parameters )
if ( device_parameters . count ( param . first ) > 0 )
; // Do Nothing
else
device_parameters . emplace ( param . first , param . second ) ;
logger - > debug ( " Device parameters " + devID + " : " ) ;
for ( const std : : pair < std : : string , std : : string > param : device_parameters )
logger - > debug ( " - " + param . first + " : " + param . second ) ;
2021-06-25 20:18:23 +02:00
# ifdef __ANDROID__
if ( devID = = " rtlsdr " )
radio = std : : make_shared < SDRRtlSdr > ( device_parameters , rtlsdr_device_android_fd , rtlsdr_device_android_path ) ;
if ( devID = = " airspy " )
radio = std : : make_shared < SDRAirspy > ( device_parameters , airspy_device_android_fd , airspy_device_android_path ) ;
# else
2021-05-25 21:25:42 +02:00
radio = getDeviceByID ( devices , device_parameters , device_id ) ;
2021-06-25 20:18:23 +02:00
# endif
2021-03-31 18:15:26 +02:00
radio - > setFrequency ( frequency * 1e6 ) ;
radio - > setSamplerate ( std : : stoi ( samplerate ) ) ;
radio - > start ( ) ;
startRealLive ( ) ;
live_processing = true ;
2021-03-22 22:26:21 +01:00
}
else
{
logger - > critical ( " Pipeline " + downlink_pipeline + " does not exist! " ) ;
}
}
}
ImGui : : SameLine ( ) ;
2021-06-16 16:33:05 +02:00
ImGui : : TextColored ( ImColor : : HSV ( 0 / 360.0 , 1 , 1 , 1.0 ) , " %s " , error_message ) ;
2021-05-25 21:25:42 +02:00
ImGui : : Text ( " Please keep in mind live processing support in SatDump is still Work-In-Progress. \n "
" While it should be perfectly functional and work as expected, bugs and crashes could still happen... \n "
" Please report if any of those occur! Anyway, enjoy! :-) " ) ;
ImGui : : Text ( " - Aang23 " ) ;
ImGui : : Text ( " PS : About saving settings between SatDump restarts, this is planned and will be implemented \n in the future. (Soon enough, it's in current priorities) " ) ;
ImGui : : TextColored ( ImColor : : HSV ( 0 / 360.0 , 1 , 1 , 1.0 ) , " There current is NO automatic samplerate selection \n "
" system that takes into account what the selected device can actually do. \n "
" Please ensure the selected samplerate is correct before pressing start. " ) ;
2021-03-22 22:26:21 +01:00
}
ImGui : : EndGroup ( ) ;
}
# endif