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 {