Skip to content

Commit 3a48d9b

Browse files
committed
fixed some usage edge cases with NCD files
1 parent 83a80e3 commit 3a48d9b

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

sigmf/convert/wav.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ def wav_to_sigmf(
105105
If the wav file cannot be read.
106106
"""
107107
wav_path = Path(wav_path)
108+
out_path = None if out_path is None else Path(out_path)
108109

109110
# auto-enable NCD when no output path is specified
110111
if out_path is None:
@@ -161,13 +162,21 @@ def wav_to_sigmf(
161162
global_info[SigMFFile.DATASET_KEY] = wav_path.name
162163
capture_info[SigMFFile.HEADER_BYTES_KEY] = header_bytes
163164

164-
# handle NCD case where no output files are created
165-
if create_ncd and out_path is None:
165+
if create_ncd:
166166
# create metadata-only SigMF for NCD pointing to original file
167167
meta = SigMFFile(global_info=global_info)
168168
meta.set_data_file(data_file=wav_path, offset=header_bytes)
169169
meta.data_buffer = io.BytesIO()
170170
meta.add_capture(0, metadata=capture_info)
171+
172+
# write metadata file if output path specified
173+
if out_path is not None:
174+
filenames = get_sigmf_filenames(out_path)
175+
output_dir = filenames["meta_fn"].parent
176+
output_dir.mkdir(parents=True, exist_ok=True)
177+
meta.tofile(filenames["meta_fn"], toarchive=False)
178+
log.info("wrote %s", filenames["meta_fn"])
179+
171180
log.debug("created NCD SigMF: %r", meta)
172181
return meta
173182

sigmf/sigmffile.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,8 @@ def __init__(
216216
if global_info is not None:
217217
self.set_global_info(global_info)
218218
if data_file is not None:
219-
self.set_data_file(data_file, skip_checksum=skip_checksum, map_readonly=map_readonly)
219+
offset = self._get_ncd_offset()
220+
self.set_data_file(data_file, skip_checksum=skip_checksum, map_readonly=map_readonly, offset=offset)
220221

221222
def __len__(self):
222223
return self._memmap.shape[0]
@@ -392,6 +393,30 @@ def _is_conforming_dataset(self):
392393
# if we get here, the file exists and is conforming
393394
return True
394395

396+
def _get_ncd_offset(self):
397+
"""
398+
Detect Non-Conforming Dataset files and return the appropriate header offset.
399+
400+
For NCD files that reference external non-SigMF files (e.g., WAV), the
401+
core:header_bytes field indicates how many bytes to skip to reach the
402+
actual sample data.
403+
404+
Returns
405+
-------
406+
int
407+
Byte offset to apply when reading the dataset file. 0 for conforming datasets.
408+
"""
409+
if self._is_conforming_dataset():
410+
return 0
411+
412+
# check if this is an NCD with core:dataset and header_bytes
413+
captures = self.get_captures()
414+
dataset_field = self.get_global_field(self.DATASET_KEY)
415+
if dataset_field and captures and self.HEADER_BYTES_KEY in captures[0]:
416+
return captures[0][self.HEADER_BYTES_KEY]
417+
418+
return 0
419+
395420
def get_schema(self):
396421
"""
397422
Return a schema object valid for the current metadata

0 commit comments

Comments
 (0)