1515import numpy as np
1616
1717import sigmf
18- from sigmf .utils import SIGMF_DATETIME_ISO8601_FMT
1918from sigmf .convert .blue import TYPE_MAP , blue_to_sigmf
19+ from sigmf .utils import SIGMF_DATETIME_ISO8601_FMT
2020
2121from .test_convert_wav import _validate_ncd
2222from .testdata import get_nonsigmf_path
@@ -33,21 +33,27 @@ def setUp(self) -> None:
3333 self .format_tolerance = [
3434 ("SB" , 1e-1 ), # scalar int8
3535 ("CB" , 1e-1 ), # complex int8
36+ ("SU" , 1e-4 ), # scalar uint16
37+ ("CU" , 1e-4 ), # complex uint16
3638 ("SI" , 1e-4 ), # scalar int16
3739 ("CI" , 1e-4 ), # complex int16
38- ("SL" , 1e-4 ), # scalar int32
39- ("CL" , 1e-4 ), # complex int32
40+ ("SV" , 1e-7 ), # scalar uint32
41+ ("CV" , 1e-7 ), # complex uint32
42+ ("SL" , 1e-8 ), # scalar int32
43+ ("CL" , 1e-8 ), # complex int32
44+ # ("SX", 1e-8), # scalar int64, should work but not allowed by SigMF spec
45+ # ("CX", 1e-8), # complex int64, should work but not allowed by SigMF spec
4046 ("SF" , 1e-8 ), # scalar float32
4147 ("CF" , 1e-8 ), # complex float32
42- ("SD" , 1e-8 ), # scalar float64
43- ("CD" , 1e-8 ), # complex float64
48+ ("SD" , 0 ), # scalar float64
49+ ("CD" , 0 ), # complex float64
4450 ]
4551
4652 self .samp_rate = 192e3
4753 num_samples = 1024
4854 ttt = np .linspace (0 , num_samples / self .samp_rate , num_samples , endpoint = False )
4955 freq = 3520 # A7 note
50- self .iq_data = ( 0.5 * np .exp (2j * np .pi * freq * ttt )). astype ( np . complex64 )
56+ self .iq_data = 0.5 * np .exp (2j * np .pi * freq * ttt ) # complex64
5157 time_now = datetime .now (timezone .utc )
5258 self .datetime = time_now .strftime (SIGMF_DATETIME_ISO8601_FMT )
5359 self .timecode = (time_now - datetime (1950 , 1 , 1 , tzinfo = timezone .utc )).total_seconds ()
@@ -63,15 +69,26 @@ def write_minimal(self, format: bytes = b"CF") -> None:
6369 dtype = TYPE_MAP [chr (format [1 ])]
6470
6571 if np .issubdtype (dtype , np .integer ):
66- multiplier = 2 ** (np .dtype (dtype ).itemsize * 8 - 1 )
72+ scale = 2 ** (np .dtype (dtype ).itemsize * 8 - 1 )
6773 if is_complex :
68- ci_real = (self .iq_data .real * multiplier ).astype (dtype )
69- ci_imag = (self .iq_data .imag * multiplier ).astype (dtype )
74+ if np .dtype (dtype ).kind == "u" :
75+ # unsigned
76+ ci_real = (self .iq_data .real * scale + scale ).astype (dtype )
77+ ci_imag = (self .iq_data .imag * scale + scale ).astype (dtype )
78+ else :
79+ # signed
80+ ci_real = (self .iq_data .real * scale ).astype (dtype )
81+ ci_imag = (self .iq_data .imag * scale ).astype (dtype )
7082 iq_converted = np .empty ((self .iq_data .size * 2 ,), dtype = dtype )
7183 iq_converted [0 ::2 ] = ci_real
7284 iq_converted [1 ::2 ] = ci_imag
7385 else :
74- iq_converted = (self .iq_data .real * multiplier ).astype (dtype )
86+ if np .dtype (dtype ).kind == "u" :
87+ # unsigned
88+ iq_converted = (self .iq_data .real * scale + scale ).astype (dtype )
89+ else :
90+ # signed
91+ iq_converted = (self .iq_data .real * scale ).astype (dtype )
7592 elif np .issubdtype (dtype , np .floating ):
7693 if is_complex :
7794 ci_real = self .iq_data .real .astype (dtype )
@@ -186,7 +203,6 @@ def test_create_ncd(self):
186203 for blue_path in self .blue_paths :
187204 meta = blue_to_sigmf (blue_path = blue_path )
188205 _validate_ncd (self , meta , blue_path )
189- print (len (meta ), blue_path )
190206 if len (meta ):
191207 # check sample read consistency
192208 np .testing .assert_allclose (meta .read_samples (count = 10 ), meta [0 :10 ], atol = 1e-6 )
0 commit comments