Skip to content

Commit 24634ea

Browse files
author
Kyle A Logue
committed
refactor signalhound, add tests, add docs, increment to v1.8.0
1 parent 6f10206 commit 24634ea

File tree

12 files changed

+385
-847
lines changed

12 files changed

+385
-847
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ sample_rate = meta.sample_rate # get sample rate
3232
# read other formats containing RF time series as SigMF
3333
meta = sigmf.fromfile("recording.wav") # WAV
3434
meta = sigmf.fromfile("recording.cdif") # BLUE / Platinum
35+
meta = sigmf.fromfile("recording.xml") # Signal Hound Spike
3536
```
3637

3738
### Docs

docs/requirements.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
# pinned 2025-01-15
2-
sphinx==8.1.3
3-
sphinx-rtd-theme==3.0.2
1+
sphinx>=8.0
2+
sphinx-rtd-theme>=3.0

docs/source/converters.rst

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Conversion is available for:
1212

1313
* **BLUE files** - MIDAS Blue and Platinum BLUE RF recordings (usually ``.cdif``)
1414
* **WAV files** - Audio recordings (``.wav``)
15+
* **Signal Hound Spike files** - Signal Hound zero-span recordings (``.xml`` + ``.iq``)
1516

1617
All converters return a :class:`~sigmf.SigMFFile` object with converted metadata.
1718

@@ -29,6 +30,7 @@ formats and reads without writing any output files:
2930
# auto-detect and create NCD for any supported format
3031
meta = sigmf.fromfile("recording.cdif") # BLUE file
3132
meta = sigmf.fromfile("recording.wav") # WAV file
33+
meta = sigmf.fromfile("recording.xml") # Signal Hound Spike file
3234
meta = sigmf.fromfile("recording.sigmf") # SigMF archive
3335
3436
all_samples = meta.read_samples()
@@ -44,13 +46,17 @@ For programmatic access, use the individual converter functions directly:
4446
4547
from sigmf.convert.wav import wav_to_sigmf
4648
from sigmf.convert.blue import blue_to_sigmf
49+
from sigmf.convert.signalhound import signalhound_to_sigmf
4750
4851
# convert WAV to SigMF archive
4952
_ = wav_to_sigmf(wav_path="recording.wav", out_path="recording", create_archive=True)
5053
5154
# convert BLUE to SigMF pair and return metadata for new files
5255
meta = blue_to_sigmf(blue_path="recording.cdif", out_path="recording")
5356
57+
# convert Signal Hound Spike to SigMF pair
58+
meta = signalhound_to_sigmf(signalhound_path="recording.xml", out_path="recording")
59+
5460
5561
Command Line Usage
5662
~~~~~~~~~~~~~~~~~~
@@ -65,8 +71,9 @@ Converters are accessed through a unified command-line interface that automatica
6571
# examples
6672
sigmf_convert recording.cdif recording.sigmf
6773
sigmf_convert recording.wav recording.sigmf
74+
sigmf_convert recording.xml recording.sigmf
6875
69-
The converter uses magic byte detection to automatically identify BLUE and WAV file formats.
76+
The converter uses magic byte detection to automatically identify BLUE, WAV, and Signal Hound Spike file formats.
7077
No need to remember format-specific commands!
7178

7279

@@ -168,4 +175,38 @@ Examples
168175
169176
# access standard SigMF data & metadata
170177
all_samples = meta.read_samples()
171-
sample_rate_hz = meta.sample_rate
178+
sample_rate_hz = meta.sample_rate
179+
180+
181+
Signal Hound Spike Converter
182+
-----------------------------
183+
184+
The Signal Hound Spike converter handles recordings from Signal Hound devices.
185+
These recordings consist of two files: an XML metadata file (``.xml``) and a binary IQ data file (``.iq``).
186+
The converter extracts metadata from the XML file and references the IQ data file, storing Signal Hound-specific
187+
fields in the ``spike:`` namespace extension.
188+
189+
.. autofunction:: sigmf.convert.signalhound.signalhound_to_sigmf
190+
191+
Examples
192+
~~~~~~~~
193+
194+
.. code-block:: python
195+
196+
from sigmf.convert.signalhound import signalhound_to_sigmf
197+
198+
# standard conversion (provide path to XML file)
199+
meta = signalhound_to_sigmf(signalhound_path="recording.xml", out_path="recording")
200+
201+
# create NCD automatically (metadata-only, references original .iq file)
202+
meta = signalhound_to_sigmf(signalhound_path="recording.xml")
203+
204+
# access standard SigMF data & metadata
205+
all_samples = meta.read_samples()
206+
sample_rate = meta.sample_rate
207+
center_freq = meta.get_captures()[0]["core:frequency"]
208+
209+
# access Signal Hound-specific metadata in spike: namespace
210+
reference_level = meta.get_global_field("spike:reference_level")
211+
if_bandwidth = meta.get_global_field("spike:if_bandwidth")
212+
decimation = meta.get_global_field("spike:decimation")

docs/source/developers.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ To build the docs and host locally:
6060
.. code-block:: console
6161
6262
$ cd docs
63+
$ pip install -r requirements.txt
6364
$ make clean
6465
$ make html
6566
$ python3 -m http.server --directory build/html/

sigmf/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# SPDX-License-Identifier: LGPL-3.0-or-later
66

77
# version of this python module
8-
__version__ = "1.7.0"
8+
__version__ = "1.8.0"
99
# matching version of the SigMF specification
1010
__specification__ = "1.2.6"
1111

sigmf/convert/__main__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ def main() -> None:
9898
# BLUE file
9999
_ = blue_to_sigmf(blue_path=input_path, out_path=output_path, create_archive=args.archive, create_ncd=args.ncd)
100100

101-
## TODO: Determine proper way to integrate Signal Hound files.
102101
elif magic_bytes == b"<?xm": # <?xml version="1.0" encoding="UTF-8"?> <SignalHoundIQFile Version="1.0">
103102
# Signal Hound Spike 1.0 file
104103
# Of the 66 Byte string move 43 bytes in to skip the XML declaration
@@ -109,12 +108,12 @@ def main() -> None:
109108
else:
110109
raise SigMFConversionError(
111110
f"Unsupported XML file format. Expanded Magic bytes: {expanded_magic_bytes}. "
112-
f"Supported formats for conversion are WAV, BLUE/Platinum and Signal Hound Spike."
111+
f"Supported formats for conversion are WAV, BLUE/Platinum, and Signal Hound Spike."
113112
)
114113
else:
115114
raise SigMFConversionError(
116115
f"Unsupported file format. Magic bytes: {magic_bytes}. "
117-
f"Supported formats for conversion are WAV, BLUE/Platinum and Signal Hound Spike."
116+
f"Supported formats for conversion are WAV, BLUE/Platinum, and Signal Hound Spike."
118117
)
119118

120119

sigmf/convert/blue.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
import numpy as np
2626
from packaging.version import InvalidVersion, Version
2727

28-
from .. import __version__ as toolversion
2928
from ..error import SigMFConversionError
3029
from ..sigmffile import SigMFFile, fromfile, get_sigmf_filenames
3130
from ..utils import SIGMF_DATETIME_ISO8601_FMT

0 commit comments

Comments
 (0)