diff --git a/config_webrx.py b/config_webrx.py index e956b9b..da1f5ed 100644 --- a/config_webrx.py +++ b/config_webrx.py @@ -151,6 +151,23 @@ sdrs = { }, }, }, + "file_player": { + "name": "file_player", + "type": "file_player", + "profiles": { + "40m": { + "name": "40m CQWW-CW 2005 loop", + "center_freq": 7040000, + "rf_gain": "auto", + "samp_rate": 96000, + "start_freq": 7040000, + "start_mod": "lsb", + "file": "samples/CQWW_CW_2005.full.fs96k.cf7040.iq.s16.dat.xz", + "bytes_per_sample": 4, + "format_conversion": "csdr convert_s16_f --bigendian | csdr iq_swap_ff", + }, + }, + }, "airspy": { "name": "Airspy HF+", "type": "airspyhf", diff --git a/owrx/command.py b/owrx/command.py index 871e414..58721ca 100644 --- a/owrx/command.py +++ b/owrx/command.py @@ -12,6 +12,7 @@ class CommandMapper(object): args = [a for a in args if a != ""] options = " ".join(args) command = "{0} {1}".format(self.base, options) + command = command.format(p=values) if self.static is not None: command += " " + self.static return command diff --git a/owrx/feature.py b/owrx/feature.py index b6d83b8..34eb560 100644 --- a/owrx/feature.py +++ b/owrx/feature.py @@ -30,6 +30,7 @@ class FeatureDetector(object): "airspyhf": ["soapy_connector", "soapy_airspyhf"], "lime_sdr": ["soapy_connector", "soapy_lime_sdr"], "fifi_sdr": ["alsa", "rockprog"], + "file_player": ["xzcat"], "pluto_sdr": ["soapy_connector", "soapy_pluto_sdr"], "soapy_remote": ["soapy_connector", "soapy_remote"], "uhd": ["soapy_connector", "soapy_uhd"], @@ -392,3 +393,11 @@ class FeatureDetector(object): You can find instructions and downloads [here](https://o28.sischa.net/fifisdr/trac/wiki/De%3Arockprog). """ return self.command_is_runnable("rockprog") + + def has_xzcat(self): + """ + The "xzcat" executable is required to use the file player. It needs to be installed separately. + + Install it from a system package manager, e.g. "sudo apt-get install xz-utils". + """ + return self.command_is_runnable("xzcat") diff --git a/owrx/source/file_player.py b/owrx/source/file_player.py new file mode 100644 index 0000000..0d8bc5f --- /dev/null +++ b/owrx/source/file_player.py @@ -0,0 +1,9 @@ +from .direct import DirectSource + +class FilePlayerSource(DirectSource): + def getCommandMapper(self): + cmd = "(while true; do xzcat {p[file]}; done) | csdr flowcontrol $(csdr ={p[samp_rate]}*{p[bytes_per_sample]}*1.05) 20 | {p[format_conversion]}" + return super().getCommandMapper().setBase(cmd) + + def getEventNames(self): + return super().getEventNames() + ["file", "bytes_per_sample", "format_conversion"] diff --git a/samples/CQWW_CW_2005.fs96k.cf7040.iq.s16.dat.xz b/samples/CQWW_CW_2005.fs96k.cf7040.iq.s16.dat.xz new file mode 100644 index 0000000..3d7f42d Binary files /dev/null and b/samples/CQWW_CW_2005.fs96k.cf7040.iq.s16.dat.xz differ diff --git a/samples/CQWW_CW_2005.full.fs96k.cf7040.iq.s16.dat.xz b/samples/CQWW_CW_2005.full.fs96k.cf7040.iq.s16.dat.xz new file mode 100644 index 0000000..fa4e544 Binary files /dev/null and b/samples/CQWW_CW_2005.full.fs96k.cf7040.iq.s16.dat.xz differ