Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install .[test,apps]
pip install .[test]
- name: Test with pytest
run: |
coverage run
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ __pycache__/
*.swp
*.py[cod]
.cache
.vscode

# packaging related
dist/
Expand Down
1 change: 0 additions & 1 deletion .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ python:
path: .
extra_requirements:
- test
- apps
- requirements: docs/requirements.txt

# Build documentation in the "docs/" directory with Sphinx
Expand Down
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,26 @@ freely under the terms GNU Lesser GPL v3 License.

This module follows the SigMF specification [html](https://sigmf.org/)/[pdf](https://sigmf.github.io/SigMF/sigmf-spec.pdf) from the [spec repository](https://github.com/sigmf/SigMF).

To install the latest PyPI release, install from pip:
### Install

```bash
pip install sigmf
```

**[Please visit the documentation for examples & more info.](https://sigmf.readthedocs.io/en/latest/)**
### Read SigMF

```python
import sigmf

# read SigMF recording
meta = sigmf.fromfile("recording.sigmf-meta")
samples = meta[0:1024] # get first 1024 samples

# read other formats containing RF time series as SigMF
meta = sigmf.fromfile("recording.wav") # WAV
meta = sigmf.fromfile("recording.cdif") # BLUE / Platinum
```

### Docs

**[Please visit our documentation for full API reference and more info.](https://sigmf.readthedocs.io/en/latest/)**
6 changes: 5 additions & 1 deletion docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ BUILDDIR = build
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile
clean:
rm -rf "$(BUILDDIR)"
rm -rf "$(SOURCEDIR)/_autosummary"

.PHONY: help clean Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
Expand Down
5 changes: 3 additions & 2 deletions docs/source/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ SigMF API
:template: custom-module-template.rst
:recursive:

sigmf.apps.convert_wav
sigmf.archive
sigmf.archivereader
sigmf.convert.blue
sigmf.convert.wav
sigmf.error
sigmf.schema
sigmf.sigmf_hash
sigmf.hashing
sigmf.sigmffile
sigmf.utils
sigmf.validate
151 changes: 151 additions & 0 deletions docs/source/converters.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
==========
Converters
==========

The SigMF Python library includes converters to import data from various RF recording formats into SigMF.
Converters can create standard SigMF file pairs or Non-Conforming Datasets (NCDs) that reference the original files.

Overview
--------

Conversion is available for:

* **BLUE files** - MIDAS Blue and Platinum BLUE RF recordings (usually ``.cdif``)
* **WAV files** - Audio recordings (``.wav``)

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


Fromfile Auto-Detection
~~~~~~~~~~~~~~~~~~~~~~~

The :func:`~sigmf.sigmffile.fromfile` function automatically detects file formats and creates Non-Conforming Datasets:

.. code-block:: python

import sigmf

# auto-detect and create NCD for any supported format
meta = sigmf.fromfile("recording.cdif") # BLUE file
meta = sigmf.fromfile("recording.wav") # WAV file
meta = sigmf.fromfile("recording.sigmf") # SigMF archive

all_samples = meta.read_samples()
sample_rate = meta.sample_rate


Python API
~~~~~~~~~~~

For programmatic access, use the individual converter functions directly:

.. code-block:: python

from sigmf.convert.wav import wav_to_sigmf
from sigmf.convert.blue import blue_to_sigmf

# convert WAV to SigMF archive
_ = wav_to_sigmf(wav_path="recording.wav", out_path="recording", create_archive=True)

# convert BLUE to SigMF pair and return metadata for new files
meta = blue_to_sigmf(blue_path="recording.cdif", out_path="recording")


Command Line Usage
~~~~~~~~~~~~~~~~~~

Converters are accessed through a unified command-line interface that automatically detects file formats:

.. code-block:: bash

# unified converter
sigmf_convert input_file output_file

# examples
sigmf_convert recording.cdif recording.sigmf
sigmf_convert recording.wav recording.sigmf

The converter uses magic byte detection to automatically identify BLUE and WAV file formats.
No need to remember format-specific commands!


Output Options
~~~~~~~~~~~~~~

The unified converter supports multiple output modes:

.. code-block:: bash

# standard conversion (creates out.sigmf-data and out.sigmf-meta files)
sigmf_convert in.wav out

# archive mode (creates single out.sigmf archive)
sigmf_convert in.wav out --archive

# non-conforming dataset (creates out.sigmf-meta only, references original file)
sigmf_convert in.wav out --ncd

# extra verbose output
sigmf_convert in.wav out -vv

**Important**: When using ``--ncd``, the input and output files must be in the same directory.
This ensures proper relative path references in the metadata.


BLUE Converter
--------------

The BLUE converter handles CDIF (.cdif) recordings while placing BLUE header information into the following global fields:

* ``blue:fixed`` - Fixed header information (at start of file).
* ``blue:adjunct`` - Adjunct header information (after fixed header).
* ``blue:extended`` - Extended header information (at end of file). Note any duplicate fields will have a suffix like ``_1``, ``_2``, etc appended.
* ``blue:keywords`` - User-defined key-value pairs.

.. autofunction:: sigmf.convert.blue.blue_to_sigmf

Examples
~~~~~~~~

.. code-block:: python

from sigmf.convert.blue import blue_to_sigmf

# standard conversion
meta = blue_to_sigmf(blue_path="recording.cdif", out_path="recording")

# create NCD automatically (metadata-only, references original file) but don't save any output file
meta = blue_to_sigmf(blue_path="recording.cdif")

# access standard SigMF data & metadata
all_samples = meta.read_samples()
sample_rate = meta.sample_rate

# access BLUE-specific metadata
blue_type = meta.get_global_field("blue:fixed")["type"] # e.g., 1000
blue_version = meta.get_global_field("blue:keywords")["IO"] # e.g., "X-Midas"


WAV Converter
-------------

Converts WAV audio recordings to SigMF format.

.. autofunction:: sigmf.convert.wav.wav_to_sigmf

Examples
~~~~~~~~

.. code-block:: python

from sigmf.convert.wav import wav_to_sigmf

# standard conversion
meta = wav_to_sigmf(wav_path="recording.wav", out_path="recording")

# create NCD automatically (metadata-only, references original file)
meta = wav_to_sigmf(wav_path="recording.wav")

# access standard SigMF data & metadata
all_samples = meta.read_samples()
sample_rate_hz = meta.sample_rate
4 changes: 2 additions & 2 deletions docs/source/developers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ To build the docs and host locally:
.. code-block:: console

$ cd docs
$ make clean
$ make html
$ cd build/html/
$ python3 -m http.server
$ python3 -m http.server --directory build/html/

--------------
Find an Issue?
Expand Down
4 changes: 3 additions & 1 deletion docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ It offers a *simple* and *intuitive* API for Python developers.

..
Note: The toolversion & specversion below are replaced dynamically during build.
The root __init__.py file is used as the sole source of truth for these values.

This documentation is for version |toolversion| of the library, which is
compatible with version |specversion| of the SigMF specification.

To get started, see the :doc:`quickstart` section or learn how to :ref:`install` the library.
To get started, see `quickstart`.

-----

Expand All @@ -23,6 +24,7 @@ To get started, see the :doc:`quickstart` section or learn how to :ref:`install`

quickstart
advanced
converters
developers

.. toctree::
Expand Down
7 changes: 2 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,14 @@ dependencies = [

[project.scripts]
sigmf_validate = "sigmf.validate:main"
sigmf_convert_wav = "sigmf.apps.convert_wav:main [apps]"
sigmf_convert = "sigmf.convert.__main__:main"
[project.optional-dependencies]
test = [
"pylint",
"pytest",
"pytest-cov",
"hypothesis", # next-gen testing framework
]
apps = [
"scipy", # for wav i/o
]

[tool.setuptools]
packages = ["sigmf"]
Expand Down Expand Up @@ -106,6 +103,6 @@ legacy_tox_ini = '''

[testenv]
usedevelop = True
deps = .[test,apps]
deps = .[test]
commands = coverage run
'''
2 changes: 1 addition & 1 deletion sigmf/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# SPDX-License-Identifier: LGPL-3.0-or-later

# version of this python module
__version__ = "1.5.0"
__version__ = "1.6.0"
# matching version of the SigMF specification
__specification__ = "1.2.6"

Expand Down
Loading