Skip to content

Commit

Permalink
Allow specifying frequencies in kHz, MHz or GHz
Browse files Browse the repository at this point in the history
  • Loading branch information
szpajder committed Jul 28, 2024
1 parent 37837c9 commit 54ff5de
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 12 deletions.
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,14 @@ bit to the side of the desired channel frequency, like this:
./dumpvdl2 --rtlsdr 0 --gain 40 --correction 42 --centerfreq 137100000 <channel freqs here...>
```

Frequencies might be specified in Hertz (as integer numbers) or in kHz, MHz, GHz
(as integer or floating-point numbers followed by any of the following suffixes:
k, K, m, M, g, G).

```
./dumpvdl2 --rtlsdr 0 --gain 40 --centerfreq 136M 136.725M 136975k 0.136875G
```

### Mirics

Mirics is similar, however `libmirisdr-4` library currently lacks support for
Expand Down Expand Up @@ -465,15 +473,15 @@ as an "expert mode" knob, which is hardly ever needed.
Example 1: use SDRplay device ID=0, with auto gain and three VDL2 channels:

```
./dumpvdl2 --sdrplay 0 136975000 136875000 136775000
./dumpvdl2 --sdrplay 0 136.975M 136.875M 136.775M
```

Example 2: use SDRplay device with serial number 35830222, set gain reduction to
40 dB, use antenna A port, disable Bias-T, enable AM/FM notch filter, set
frequency correction to -1ppm:

```
./dumpvdl2 --sdrplay 35830222 --gr 40 --correction -1 --antenna A --biast 0 --notch-filter 1 136975000
./dumpvdl2 --sdrplay 35830222 --gr 40 --correction -1 --antenna A --biast 0 --notch-filter 1 136.975M
```

### SDRplay RSP native driver, version 3
Expand Down Expand Up @@ -1062,7 +1070,7 @@ dumpvdl2 --iq-file <file_name> --centerfreq 136955000 136975000
Putting it all together:

```
dumpvdl2 --iq-file iq.dat --sample-format S16_LE --oversample 13 --centerfreq 136955000 136975000 136725000
dumpvdl2 --iq-file iq.dat --sample-format S16_LE --oversample 13 --centerfreq 136.955M 136.975M 136.725M
```

processes `iq.dat` file recorded at 1365000 samples/sec using 16-bit signed
Expand Down
77 changes: 68 additions & 9 deletions src/dumpvdl2.c
Original file line number Diff line number Diff line change
Expand Up @@ -399,15 +399,15 @@ void usage() {
describe_option("--debug <filter_spec>", "Debug message classes to display (default: none) (\"--debug help\" for details)", 1);
#endif
fprintf(stderr, "common options:\n");
describe_option("<freq_1> [<freq_2> [...]]", "VDL2 channel frequencies, in Hz", 1);
describe_option("<freq_1> [<freq_2> [...]]", "VDL2 channel frequencies", 1);
fprintf(stderr, "If channel frequencies are omitted, VDL2 Common Signalling Channel (%u Hz) will be used as default.\n\n", CSC_FREQ);

#ifdef WITH_RTLSDR
fprintf(stderr, "rtlsdr_options:\n");
describe_option("--rtlsdr <device_id>", "Use RTL device with specified ID or serial number (default: ID=0)", 1);
describe_option("--gain <gain>", "Set gain (decibels)", 1);
describe_option("--correction <correction>", "Set freq correction (ppm)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency in Hz (default: auto)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency (default: auto)", 1);
describe_option("--bias <bias>", "Enable(1) or Disable(0) bias tee (default: 0)", 1);
#endif
#ifdef WITH_MIRISDR
Expand All @@ -416,7 +416,7 @@ void usage() {
describe_option("--hw-type <device_type>", "0 - default, 1 - SDRPlay", 1);
describe_option("--gain <gain>", "Set gain (in decibels, from 0 to 102 dB)", 1);
describe_option("--correction <correction>", "Set freq correction (in Hertz)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency in Hz (default: auto)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency (default: auto)", 1);
describe_option("--usb-mode <usb_transfer_mode>", "0 - isochronous (default), 1 - bulk", 1);
#endif
#ifdef WITH_SDRPLAY
Expand All @@ -425,7 +425,7 @@ void usage() {
describe_option("--gr <gr>", "Set system gain reduction, in dB, positive (if omitted, auto gain is enabled)", 1);
describe_option("--agc <AGC_set_point>", "Auto gain set point in dBFS, negative (default: -30)", 1);
describe_option("--correction <correction>", "Set freq correction (ppm)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency in Hz (default: auto)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency (default: auto)", 1);
describe_option("--antenna <A/B>", "RSP2 antenna port selection (default: A)", 1);
describe_option("--biast <0/1>", "RSP2/1a/duo Bias-T control: 0 - off (default), 1 - on", 1);
describe_option("--notch-filter <0/1>", "RSP2/1a/duo AM/FM/bcast notch filter control: 0 - off (default), 1 - on", 1);
Expand All @@ -439,7 +439,7 @@ void usage() {
describe_option("", "(if omitted, auto gain is enabled)", 1);
describe_option("--agc <AGC_set_point>", "Auto gain set point in dBFS, negative (default: -30)", 1);
describe_option("--correction <correction>", "Set freq correction (ppm)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency in Hz (default: auto)", 1);
describe_option("--centerfreq <center_frequency>", "Set center frequency (default: auto)", 1);
describe_option("--antenna <A/B/C>", "RSP2/dx antenna port selection (default: A)", 1);
describe_option("--biast <0/1>", "RSP2/1a/duo/dx Bias-T control: 0 - off (default), 1 - on", 1);
describe_option("--notch-filter <0/1>", "RSP2/1a/duo/dx AM/FM/bcast notch filter control: 0 - off (default), 1 - on", 1);
Expand All @@ -457,7 +457,7 @@ void usage() {
#endif
fprintf(stderr, "\nfile_options:\n");
describe_option("--iq-file <input_file>", "Read I/Q samples from a file (use \"-\" to read from standard input)", 1);
describe_option("--centerfreq <center_frequency>", "Center frequency of the input data, in Hz (default: 0)", 1);
describe_option("--centerfreq <center_frequency>", "Center frequency of the input data, (default: 0)", 1);
describe_option("--oversample <oversample_rate>", "Oversampling rate for recorded data", 1);
fprintf(stderr, "%*s(sampling rate will be set to %u * oversample_rate)\n", USAGE_OPT_NAME_COLWIDTH, "", SYMBOL_RATE * SPS);
fprintf(stderr, "%*sDefault: %u\n", USAGE_OPT_NAME_COLWIDTH, "", FILE_OVERSAMPLE);
Expand Down Expand Up @@ -493,6 +493,11 @@ void usage() {
describe_option("--extended-header", "Print additional fields in message header", 1);
describe_option("--prettify-xml", "Pretty-print XML payloads in ACARS and MIAM CORE PDUs", 1);
describe_option("--prettify-json", "Pretty-print JSON payloads in OHMA messages", 1);

fprintf(stderr, "\nFrequencies might be specified in Hz (as integer numbers) or in kHz, MHz, GHz (as integer\n");
fprintf(stderr, "or floating-point numbers followed by any of the following suffixes: k, K, m, M, g, G).\n");
fprintf(stderr, "Examples: 136975000, 136975k, 136.975M, 0.136975G\n");

_exit(0);
}

Expand Down Expand Up @@ -620,10 +625,60 @@ static uint32_t parse_msg_filterspec(msg_filterspec_t const *filters, void (*hel
return fmask;
}

static bool parse_frequency(char const *str, uint32_t *result) {
ASSERT(str != NULL);
ASSERT(result != NULL);

char *endptr = NULL;
double val = strtod(str, &endptr);
if(endptr == str) {
fprintf(stderr, "Cannot parse '%s' as frequency: not a valid floating-point number\n", str);
return false;
} else if(errno == ERANGE) {
fprintf(stderr, "Cannot parse '%s' as frequency: value too large\n", str);
return false;
}

switch(endptr[0]) {
case 'k':
case 'K':
val *= 1e3;
endptr++;
break;
case 'm':
case 'M':
val *= 1e6;
endptr++;
break;
case 'g':
case 'G':
val *= 1e9;
endptr++;
break;
case '\0':
break;
default:
fprintf(stderr, "Cannot parse '%s' as frequency: '%c' is not a valid suffix\n", str, endptr[0]);
return false;
}
if(endptr[0] != '\0') {
fprintf(stderr, "Cannot parse '%s' as frequency: invalid trailing characters after value\n", str);
return false;
}
if(val < 0 || val > UINT32_MAX) {
fprintf(stderr, "Cannot parse '%s' as frequency: value is negative or too large\n", str);
return false;
}
*result = (uint32_t)val;
debug_print(D_MISC, "str: %s val: %u\n", str, *result);
return true;
}


int main(int argc, char **argv) {
vdl2_state_t ctx;
uint32_t centerfreq = 0, sample_rate = 0, oversample = 0;
uint32_t *freqs;
uint32_t *freqs = NULL;
int num_channels = 0;
enum input_types input = INPUT_UNDEF;
enum sample_formats sample_fmt = SFMT_UNDEF;
Expand Down Expand Up @@ -832,7 +887,9 @@ int main(int argc, char **argv) {
Config.station_id = strndup(optarg, STATION_ID_LEN_MAX);
break;
case __OPT_CENTERFREQ:
centerfreq = strtoul(optarg, NULL, 10);
if(parse_frequency(optarg, &centerfreq) == false) {
_exit(1);
}
break;
#ifdef WITH_MIRISDR
case __OPT_MIRISDR:
Expand Down Expand Up @@ -979,7 +1036,9 @@ int main(int argc, char **argv) {
num_channels = argc - optind;
freqs = XCALLOC(num_channels, sizeof(uint32_t));
for(int i = 0; i < num_channels; i++)
freqs[i] = strtoul(argv[optind+i], NULL, 10);
if(parse_frequency(argv[optind + i], &freqs[i]) == false) {
return 1;
}
} else {
fprintf(stderr, "Warning: frequency not set - using VDL2 Common Signalling Channel as a default (%u Hz)\n", CSC_FREQ);
num_channels = 1;
Expand Down

0 comments on commit 54ff5de

Please sign in to comment.