diff --git a/README.md b/README.md index 1a9c601..80bb2b5 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,6 @@ It is also possible to read WAV files. This is compatible with any WAV file, 16 ./rffft -i recording.wav -f 97400000 -s 48000 -F wav -T "YYYY-MM-DDTHH:MM:SS" -For WAV files exported from SatDump the `-P` options will automatically extract the correct parameters from the filename. +For WAV files exported from SatDump and SDR Console the `-P` options will automatically extract the correct parameters from the filename. The output spectrograms can be viewed and analysed using `rfplot`. diff --git a/rffft_internal.c b/rffft_internal.c index 4add8e6..84d1f92 100644 --- a/rffft_internal.c +++ b/rffft_internal.c @@ -20,12 +20,14 @@ // - GQRX: // - gqrx_20230806_151838_428000000_200000_fc.raw // format always float32 +// - SDR Console: +// - 07-Aug-2023 181711.798 401.774MHz.wav int rffft_params_from_filename(char * filename, double * samplerate, double * frequency, char * format, char * starttime) { // Temp vars to hold parsed values int p_year, p_month, p_day, p_hours, p_minutes, p_seconds, p_fractal_seconds; int p_dummy_int; double p_samplerate, p_frequency; - char p_format[16]; + char p_month_string[16], p_format[16]; char p_dummy_string[128]; int parsed_tokens; @@ -166,5 +168,59 @@ int rffft_params_from_filename(char * filename, double * samplerate, double * fr return 0; } + // SDR Console + parsed_tokens = sscanf( + base_filename, + "%02d-%3s-%04d %02d%02d%02d.%03d %lfMHz.wav", + &p_day, + p_month_string, + &p_year, + &p_hours, + &p_minutes, + &p_seconds, + &p_fractal_seconds, + &p_frequency); + + if (parsed_tokens == 8) { + *samplerate = 0; // Will be set when opening the wav + *frequency = p_frequency * 1e6; + *format = 'w'; + + int month; + + if ((strlen(p_month_string) == 3) && (strncmp("Jan", p_month_string, 3) == 0)) { + month = 1; + } else if ((strlen(p_month_string) == 3) && (strncmp("Feb", p_month_string, 3) == 0)) { + month = 2; + } else if ((strlen(p_month_string) == 3) && (strncmp("Mar", p_month_string, 3) == 0)) { + month = 3; + } else if ((strlen(p_month_string) == 3) && (strncmp("Apr", p_month_string, 3) == 0)) { + month = 4; + } else if ((strlen(p_month_string) == 3) && (strncmp("May", p_month_string, 3) == 0)) { + month = 5; + } else if ((strlen(p_month_string) == 3) && (strncmp("Jun", p_month_string, 3) == 0)) { + month = 6; + } else if ((strlen(p_month_string) == 3) && (strncmp("Jul", p_month_string, 3) == 0)) { + month = 7; + } else if ((strlen(p_month_string) == 3) && (strncmp("Aug", p_month_string, 3) == 0)) { + month = 8; + } else if ((strlen(p_month_string) == 3) && (strncmp("Sep", p_month_string, 3) == 0)) { + month = 9; + } else if ((strlen(p_month_string) == 3) && (strncmp("Oct", p_month_string, 3) == 0)) { + month = 10; + } else if ((strlen(p_month_string) == 3) && (strncmp("Nov", p_month_string, 3) == 0)) { + month = 11; + } else if ((strlen(p_month_string) == 3) && (strncmp("Dec", p_month_string, 3) == 0)) { + month = 12; + } else { + printf("Unparsable month in SDR Console format %s\n", p_format); + return -1; + } + + snprintf(starttime, 32, "%04d-%02d-%02dT%02d:%02d:%02d.%03d", p_year, month, p_day, p_hours, p_minutes, p_seconds, p_fractal_seconds); + + return 0; + } + return -1; } diff --git a/tests/tests_rffft_internal.c b/tests/tests_rffft_internal.c index be4272e..145d949 100644 --- a/tests/tests_rffft_internal.c +++ b/tests/tests_rffft_internal.c @@ -73,11 +73,31 @@ void rffft_internal_parse_gqrx_filenames(void **state) { assert_int_equal(-1, rffft_params_from_filename("gqrx_2023-08-06_15:18:38_428000000_200000_fc.raw", &samplerate, &frequency, &format, starttime)); } +// Test SDR Console filenames +void rffft_internal_parse_sdrconsole_filenames(void **state) { + double samplerate = 0; + double frequency = 0; + char format = '\0'; + char starttime[] = "YYYY-mm-ddTHH:MM:SS.sss"; + char ref_format = '\0'; + + ref_format = 'w'; + assert_int_equal(0, rffft_params_from_filename("07-Aug-2023 181711.798 401.774MHz.wav", &samplerate, &frequency, &format, starttime)); + // assert_double_equal has been introduced in cmocka 1.1.6 not available on most distribs yet + assert_float_equal(0, samplerate, 1e-12); + assert_float_equal(401.774e6, frequency, 1e-12); + assert_memory_equal(&ref_format, &format, 1); + assert_string_equal("2023-08-07T18:17:11.798", starttime); + + assert_int_equal(-1, rffft_params_from_filename("07-Yol-2023 181711.798 401.774MHz.wav", &samplerate, &frequency, &format, starttime)); +} + // Entry point to run all tests int run_rffft_internal_tests() { const struct CMUnitTest tests[] = { cmocka_unit_test(rffft_internal_parse_satdump_filenames), cmocka_unit_test(rffft_internal_parse_gqrx_filenames), + cmocka_unit_test(rffft_internal_parse_sdrconsole_filenames), }; return cmocka_run_group_tests_name("rffft internal", tests, NULL, NULL);