Allow multiple input files, positional args are input files

This commit is contained in:
Christian W. Zuckschwerdt
2018-11-23 08:46:43 +00:00
committed by Christian W. Zuckschwerdt
parent dfc1d79479
commit 4c80e60c97
3 changed files with 85 additions and 60 deletions

View File

@@ -55,9 +55,11 @@ Usage: = General options =
[-r <filename>] Read data from input file instead of a receiver
[-w <filename>] Save data stream to output file (a '-' dumps samples to stdout)
[-W <filename>] Save data stream to output file, overwrite existing file
= Data output options =
[-F] kv|json|csv|syslog|null Produce decoded output in given format. Not yet supported by all drivers.
Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout.
Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514
[-K] FILE|PATH|<tag> Add an expanded token or fixed tag to every output line.
[-C] native|si|customary Convert units in decoded output.
[-T] Specify number of seconds to run
[-U] Print timestamps in UTC (this may also be accomplished by invocation with TZ environment variable set).

View File

@@ -302,6 +302,9 @@ data_t *data_prepend(data_t *first, const char *key, const char *pretty_key, ...
data_t *result = vdata_make(NULL, key, pretty_key, ap);
va_end(ap);
if (!result)
return first;
data_t *prev = result;
while (prev && prev->next)
prev = prev->next;

View File

@@ -38,6 +38,7 @@
#define MAX_DATA_OUTPUTS 32
#define MAX_DUMP_OUTPUTS 8
#define MAX_IN_FILES 100
#ifdef GIT_VERSION
#define STR_VALUE(arg) #arg
@@ -61,6 +62,8 @@ struct app_cfg {
int ppm_error;
uint32_t out_block_size;
char const *test_data;
unsigned in_files;
char const *in_file[MAX_IN_FILES];
char const *in_filename;
int do_exit;
int do_exit_async;
@@ -175,9 +178,11 @@ static void usage(r_device *devices, unsigned num_devices, int exit_code)
"\t[-r <filename>] Read data from input file instead of a receiver\n"
"\t[-w <filename>] Save data stream to output file (a '-' dumps samples to stdout)\n"
"\t[-W <filename>] Save data stream to output file, overwrite existing file\n"
"\t= Data output options =\n"
"\t[-F] kv|json|csv|syslog|null Produce decoded output in given format. Not yet supported by all drivers.\n"
"\t\t Append output to file with :<filename> (e.g. -F csv:log.csv), defaults to stdout.\n"
"\t\t Specify host/port for syslog with e.g. -F syslog:127.0.0.1:1514\n"
"\t[-K] FILE|PATH|<tag> Add an expanded token or fixed tag to every output line.\n"
"\t[-C] native|si|customary Convert units in decoded output.\n"
"\t[-T] Specify number of seconds to run\n"
"\t[-U] Print timestamps in UTC (this may also be accomplished by invocation with TZ environment variable set).\n"
@@ -940,6 +945,15 @@ static void add_dumper(char const *spec, file_info_t *dumper, int overwrite)
}
}
static void add_infile(char const *in_file)
{
if (cfg.in_files >= MAX_IN_FILES) {
fprintf(stderr, "Max input files reached, ignoring \"%s\"!\n", in_file);
return;
}
cfg.in_file[cfg.in_files++] = in_file;
}
/// string to bool with default
int atobv(char *arg, int def)
{
@@ -1146,7 +1160,7 @@ static void parse_conf_option(struct app_cfg *cfg, int opt, char *arg)
if (!arg)
help_read();
cfg->in_filename = arg;
add_infile(arg);
// TODO: check_read_file_info()
break;
case 'w':
@@ -1350,6 +1364,11 @@ int main(int argc, char **argv) {
parse_conf_args(&cfg, argc, argv);
// add all remaining positional arguments as input files
while (argc > optind) {
add_infile(argv[optind++]);
}
if (demod->am_analyze) {
demod->am_analyze->level_limit = &demod->level_limit;
demod->am_analyze->frequency = &cfg.center_frequency;
@@ -1357,12 +1376,6 @@ int main(int argc, char **argv) {
demod->am_analyze->sample_size = &demod->sample_size;
}
if (argc <= optind - 1) {
usage(NULL, 0, 1);
} else {
out_filename = argv[optind]; // deprecated
}
if (cfg.last_output_handler < 1) {
add_kv_output(NULL);
}
@@ -1409,7 +1422,7 @@ int main(int argc, char **argv) {
exit(!r);
}
if (!cfg.in_filename) {
if (!cfg.in_files) {
r = sdr_open(&cfg.dev, &demod->sample_size, cfg.dev_query, !cfg.quiet_mode);
if (r < 0) {
exit(1);
@@ -1442,8 +1455,7 @@ int main(int argc, char **argv) {
add_dumper(out_filename, demod->dumper, 0); // deprecated
}
if (cfg.in_filename) {
parse_file_info(cfg.in_filename, &demod->load_info);
if (cfg.in_files) {
unsigned char *test_mode_buf = malloc(DEFAULT_BUF_LENGTH * sizeof(unsigned char));
float *test_mode_float_buf = malloc(DEFAULT_BUF_LENGTH / sizeof(int16_t) * sizeof(float));
if (!test_mode_buf || !test_mode_float_buf)
@@ -1451,62 +1463,70 @@ int main(int argc, char **argv) {
fprintf(stderr, "Couldn't allocate read buffers!\n");
exit(1);
}
if (strcmp(demod->load_info.path, "-") == 0) { /* read samples from stdin */
in_file = stdin;
cfg.in_filename = "<stdin>";
} else {
in_file = fopen(demod->load_info.path, "rb");
if (!in_file) {
fprintf(stderr, "Opening file: %s failed!\n", cfg.in_filename);
goto out;
}
}
fprintf(stderr, "Test mode active. Reading samples from file: %s\n", cfg.in_filename); // Essential information (not quiet)
if (demod->load_info.format == CU8_IQ
|| demod->load_info.format == S16_AM
|| demod->load_info.format == S16_FM) {
demod->sample_size = sizeof(uint8_t); // CU8, AM, FM
} else {
demod->sample_size = sizeof(int16_t); // CF32, CS16
}
if (!cfg.quiet_mode) {
fprintf(stderr, "Input format: %s\n", file_info_string(&demod->load_info));
}
sample_file_pos = 0.0;
int n_blocks = 0;
unsigned long n_read;
do {
if (demod->load_info.format == CF32_IQ) {
n_read = fread(test_mode_float_buf, sizeof(float), DEFAULT_BUF_LENGTH / 2, in_file);
// clamp float to [-1,1] and scale to Q0.15
for(unsigned long n = 0; n < n_read; n++) {
int s_tmp = test_mode_float_buf[n] * INT16_MAX;
if (s_tmp < -INT16_MAX)
s_tmp = -INT16_MAX;
else if (s_tmp > INT16_MAX)
s_tmp = INT16_MAX;
test_mode_buf[n] = (int16_t)s_tmp;
}
for (i = 0; i < cfg.in_files; ++i) {
cfg.in_filename = cfg.in_file[i];
parse_file_info(cfg.in_filename, &demod->load_info);
if (strcmp(demod->load_info.path, "-") == 0) { /* read samples from stdin */
in_file = stdin;
cfg.in_filename = "<stdin>";
} else {
n_read = fread(test_mode_buf, 1, DEFAULT_BUF_LENGTH, in_file);
in_file = fopen(demod->load_info.path, "rb");
if (!in_file) {
fprintf(stderr, "Opening file: %s failed!\n", cfg.in_filename);
goto out;
}
}
if (n_read == 0) break; // sdr_callback() will Segmentation Fault with len=0
sdr_callback(test_mode_buf, n_read, demod);
n_blocks++;
sample_file_pos = (float)n_blocks * n_read / cfg.samp_rate / 2 / demod->sample_size;
} while (n_read != 0);
fprintf(stderr, "Test mode active. Reading samples from file: %s\n", cfg.in_filename); // Essential information (not quiet)
if (demod->load_info.format == CU8_IQ
|| demod->load_info.format == S16_AM
|| demod->load_info.format == S16_FM) {
demod->sample_size = sizeof(uint8_t); // CU8, AM, FM
} else {
demod->sample_size = sizeof(int16_t); // CF32, CS16
}
if (!cfg.quiet_mode) {
fprintf(stderr, "Input format: %s\n", file_info_string(&demod->load_info));
}
sample_file_pos = 0.0;
// Call a last time with cleared samples to ensure EOP detection
memset(test_mode_buf, 128, DEFAULT_BUF_LENGTH); // 128 is 0 in unsigned data
sdr_callback(test_mode_buf, DEFAULT_BUF_LENGTH, demod);
int n_blocks = 0;
unsigned long n_read;
do {
if (demod->load_info.format == CF32_IQ) {
n_read = fread(test_mode_float_buf, sizeof(float), DEFAULT_BUF_LENGTH / 2, in_file);
// clamp float to [-1,1] and scale to Q0.15
for(unsigned long n = 0; n < n_read; n++) {
int s_tmp = test_mode_float_buf[n] * INT16_MAX;
if (s_tmp < -INT16_MAX)
s_tmp = -INT16_MAX;
else if (s_tmp > INT16_MAX)
s_tmp = INT16_MAX;
test_mode_buf[n] = (int16_t)s_tmp;
}
} else {
n_read = fread(test_mode_buf, 1, DEFAULT_BUF_LENGTH, in_file);
}
if (n_read == 0) break; // sdr_callback() will Segmentation Fault with len=0
sdr_callback(test_mode_buf, n_read, demod);
n_blocks++;
sample_file_pos = (float)n_blocks * n_read / cfg.samp_rate / 2 / demod->sample_size;
} while (n_read != 0);
// Call a last time with cleared samples to ensure EOP detection
memset(test_mode_buf, 128, DEFAULT_BUF_LENGTH); // 128 is 0 in unsigned data
sdr_callback(test_mode_buf, DEFAULT_BUF_LENGTH, demod);
//Always classify a signal at the end of the file
if (demod->am_analyze)
am_analyze_classify(demod->am_analyze);
if (!cfg.quiet_mode) {
fprintf(stderr, "Test mode file issued %d packets\n", n_blocks);
}
//Always classify a signal at the end of the file
if (demod->am_analyze)
am_analyze_classify(demod->am_analyze);
if (!cfg.quiet_mode) {
fprintf(stderr, "Test mode file issued %d packets\n", n_blocks);
}
free(test_mode_buf);
free(test_mode_float_buf);
exit(0);