Hi, This is a starter patch to produce a .sigmf-meta file for each recording. It contains the minimum useful info that is usually coded into the filename.
I'm not sure if anyone thinks this is worthwhile. There is a lot more that could be recorded in the .sigmf-meta file like e.g. current gain values, current bandwidth or antenna settings (if available), but i wanted to see if there is any interest for this at all. It would maybe also nice to add the actual sdr device name that was used, but as far as I can see there is no way in python to query which device/driver is used by a specific osmosdr.source()? CU, Sec >From 916dd8732302d8d052432a5deb27f132521d0be3 Mon Sep 17 00:00:00 2001 From: Stefan `Sec` Zehl <s...@42.org> Date: Sun, 10 Oct 2021 16:59:32 +0200 Subject: [PATCH] implement simple sigmf support for recording --- apps/osmocom_fft | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/apps/osmocom_fft b/apps/osmocom_fft index f829192cd6..2cdfd3ae35 100755 --- a/apps/osmocom_fft +++ b/apps/osmocom_fft @@ -103,8 +103,8 @@ class app_top_block(gr.top_block, Qt.QMainWindow): help="Set gain in dB (default is midpoint)") parser.add_option("-G", "--gains", type="string", default=None, help="Set named gain in dB, name:gain,name:gain,...") - parser.add_option("-r", "--record", type="string", default="/tmp/name-f%F-s%S-t%T.cfile", - help="Filename to record to, available wildcards: %S: sample rate, %F: center frequency, %T: timestamp, Example: /tmp/name-f%F-s%S-t%T.cfile") + parser.add_option("-r", "--record", type="string", default="/tmp/name-f%F-s%S-t%T.sigmf-data", + help="Filename to record to, available wildcards: %S: sample rate, %F: center frequency, %T: timestamp, Example: /tmp/name-f%F-s%S-t%T.sigmf-data") parser.add_option("", "--dc-offset-mode", type="int", default=None, help="Set the RX frontend DC offset correction mode") parser.add_option("", "--iq-balance-mode", type="int", default=None, @@ -342,6 +342,24 @@ class app_top_block(gr.top_block, Qt.QMainWindow): s = s.replace('%T', datetime.datetime.now().strftime('%Y%m%d%H%M%S')) return s + def record_sigmf_metadata(self): + return { + "global": { + "core:datatype": "cf32_le", + "core:sample_rate": self.src.get_sample_rate(), + "core:version": "1.0.0", + "core:num_channels": 1, + "core:recorder": "osmocom_fft" + }, + "captures": [ + { + "core:sample_start": 0, + "core:frequency": self.src.get_center_freq(), + "core:datetime": datetime.datetime.utcnow().isoformat()+"Z" + } + ] + } + def _set_status_msg(self, msg, timeout=0): self.status.showMessage(msg, timeout) @@ -498,6 +516,14 @@ class app_top_block(gr.top_block, Qt.QMainWindow): print("Recording samples to ", self.rec_file_name) self.file_sink.open(self.rec_file_name); + if self.rec_file_name.endswith('.sigmf-data'): + try: + import json + self.meta_file_name=self.rec_file_name[:-4]+'meta' + with open(self.meta_file_name, 'w') as outfile: + json.dump(self.record_sigmf_metadata(), outfile, indent=4) + except ModuleNotFoundError as e: + print("Could not write sigmf-meta: ",e) else: self._srw.setDisabled(False) self._fre.setDisabled(False) -- 2.30.2 CU, Sec -- A bureaucracy is like a computer program. Usually, the question is how to arrange it so that what you want is composed of operations that the bureaucracy supports. In addition, in any bureaucracy, there is always *someone* whose job is to approve violations of the rules.