diff --git a/include/fileformat.h b/include/fileformat.h index a53993af..4911de29 100644 --- a/include/fileformat.h +++ b/include/fileformat.h @@ -82,12 +82,57 @@ typedef struct { FILE *file; } file_info_t; -int parse_file_info(const char *filename, file_info_t *info); +/// Clear all file info. +/// +/// @param[in,out] info the file info to clear +void file_info_clear(file_info_t *info); -void check_read_file_info(file_info_t *info); +/// Parse file info from a filename, optionally prefixed with overrides. +/// +/// Detects tags in the file name delimited by non-alphanum +/// and prefixes delimited with a colon. +/// +/// Parse "[0-9]+(\.[0-9]+)?[A-Za-z]" +/// - as frequency (suffix "M" or "[kMG]?Hz") +/// - or sample rate (suffix "k" or "[kMG]?sps") +/// +/// Parse "[A-Za-z][0-9A-Za-z]+" as format or content specifier: +/// - 2ch formats: "cu8", "cs8", "cs16", "cs32", "cf32" +/// - 1ch formats: "u8", "s8", "s16", "u16", "s32", "u32", "f32" +/// - text formats: "vcd", "ook" +/// - content types: "iq", "i", "q", "am", "fm", "logic" +/// +/// Parses left to right, with the exception of a prefix up to the last colon ":" +/// This prefix is the forced override, parsed last and removed from the filename. +/// +/// All matches are case-insensitive. +/// +/// - default detection, e.g.: path/filename.am.s16 +/// - overrides, e.g.: am:s16:path/filename.ext +/// - other styles are detected but discouraged, e.g.: +/// am-s16:path/filename.ext, am.s16:path/filename.ext, path/filename.am_s16 +/// +/// @param[in,out] info the file info to parse into +/// @param filename a file name with optional override prefix to parse +/// @return the detected file format, 0 otherwise +int file_info_parse_filename(file_info_t *info, const char *filename); -void check_write_file_info(file_info_t *info); +/// Check if the format in this file info is supported for reading, +/// print a warning and exit otherwise. +/// +/// @param info the file info to check +void file_info_check_read(file_info_t *info); +/// Check if the format in this file info is supported for reading, +/// print a warning and exit otherwise. +/// +/// @param info the file info to check +void file_info_check_write(file_info_t *info); + +/// Return a string describing the format in this file info. +/// +/// @param info the file info to check +/// @return a string describing the format char const *file_info_string(file_info_t *info); #endif /* INCLUDE_FILEFORMAT_H_ */ diff --git a/src/fileformat.c b/src/fileformat.c index af1f0738..9aed3409 100644 --- a/src/fileformat.c +++ b/src/fileformat.c @@ -36,7 +36,14 @@ char const *file_basename(char const *path) return path; } -void check_read_file_info(file_info_t *info) +void file_info_clear(file_info_t *info) +{ + if (info) { + *info = (file_info_t const){0}; + } +} + +void file_info_check_read(file_info_t *info) { if (info->format != CU8_IQ && info->format != CS16_IQ @@ -48,7 +55,7 @@ void check_read_file_info(file_info_t *info) } } -void check_write_file_info(file_info_t *info) +void file_info_check_write(file_info_t *info) { if (info->format != CU8_IQ && info->format != CS8_IQ @@ -241,7 +248,7 @@ overrides, e.g.: am:s16:path/filename.ext other styles are detected but discouraged, e.g.: am-s16:path/filename.ext, am.s16:path/filename.ext, path/filename.am_s16 */ -int parse_file_info(char const *filename, file_info_t *info) +int file_info_parse_filename(file_info_t *info, char const *filename) { if (!filename) { return 0; @@ -273,7 +280,7 @@ int parse_file_info(char const *filename, file_info_t *info) static void assert_file_type(int check, char const *spec) { file_info_t info = {0}; - int ret = parse_file_info(spec, &info); + int ret = file_info_parse_filename(&info, spec); if (check != ret) { fprintf(stderr, "\nTEST failed: determine_file_type(\"%s\", &foo) = %8x == %8x\n", spec, ret, check); } else { diff --git a/src/r_api.c b/src/r_api.c index 97c5e5ff..9c8be859 100644 --- a/src/r_api.c +++ b/src/r_api.c @@ -1043,7 +1043,7 @@ void add_dumper(r_cfg_t *cfg, char const *spec, int overwrite) FATAL_CALLOC("add_dumper()"); list_push(&cfg->demod->dumper, dumper); - parse_file_info(spec, dumper); + file_info_parse_filename(dumper, spec); if (strcmp(dumper->path, "-") == 0) { /* Write samples to stdout */ dumper->file = stdout; #ifdef _WIN32 diff --git a/src/rtl_433.c b/src/rtl_433.c index 7bb23ae4..ef6adb36 100644 --- a/src/rtl_433.c +++ b/src/rtl_433.c @@ -905,7 +905,7 @@ static void parse_conf_option(r_cfg_t *cfg, int opt, char *arg) help_read(); add_infile(cfg, arg); - // TODO: check_read_file_info() + // TODO: file_info_check_read() break; case 'w': if (!arg) @@ -1343,6 +1343,8 @@ int main(int argc, char **argv) { if (cfg->frequencies > 1 && cfg->hop_times == 0) { cfg->hop_time[cfg->hop_times++] = DEFAULT_HOP_TIME; } + // save sample rate, this should be a hop config too + uint32_t sample_rate_0 = cfg->samp_rate; // add all remaining positional arguments as input files while (argc > optind) { @@ -1561,8 +1563,13 @@ int main(int argc, char **argv) { for (void **iter = cfg->in_files.elems; iter && *iter; ++iter) { cfg->in_filename = *iter; - parse_file_info(cfg->in_filename, &demod->load_info); - if (strcmp(demod->load_info.path, "-") == 0) { /* read samples from stdin */ + file_info_clear(&demod->load_info); // reset all info + file_info_parse_filename(&demod->load_info, cfg->in_filename); + // apply file info or default + cfg->samp_rate = demod->load_info.sample_rate ? demod->load_info.sample_rate : sample_rate_0; + cfg->center_frequency = demod->load_info.center_frequency ? demod->load_info.center_frequency : cfg->frequency[0]; + + if (strcmp(demod->load_info.path, "-") == 0) { // read samples from stdin in_file = stdin; cfg->in_filename = "<stdin>"; } else {