@@ -314,50 +314,59 @@ def __next__(self):
314314 raise StopIteration
315315
316316 def __getitem__ (self , sli ):
317- mem = self ._memmap [sli ] # matches behavior of numpy.ndarray.__getitem__()
317+ """
318+ Enable slicing and indexing into the dataset samples.
318319
319- # apply _return_type conversion if set
320- if self ._return_type is None :
321- # no special conversion needed
322- if not self .autoscale :
323- return mem
324- else :
325- # apply autoscaling for fixed-point data when autoscale=True
326- dtype = dtype_info (self .get_global_field (self .DATATYPE_KEY ))
327- is_fixedpoint_data = dtype ["is_fixedpoint" ]
328-
329- if is_fixedpoint_data :
330- # apply scaling for fixed-point data
331- is_unsigned_data = dtype ["is_unsigned" ]
332- component_size = dtype ["component_size" ]
333- data_type_out = np .dtype ("f4" ) if not self .is_complex_data else np .dtype ("f4, f4" )
334-
335- data = mem .astype (data_type_out )
336- data = data .view (np .dtype ("f4" ))
320+ Should match behavior of ndarray.__getitem__() and apply autoscaling similar to read_samples().
321+ """
322+ mem = self ._memmap [sli ]
323+
324+ # apply autoscaling for fixed-point data when autoscale=True
325+ if self .autoscale :
326+ dtype = dtype_info (self .get_global_field (self .DATATYPE_KEY ))
327+ if dtype ["is_fixedpoint" ]:
328+ # extract scaling parameters
329+ is_unsigned_data = dtype ["is_unsigned" ]
330+ component_size = dtype ["component_size" ]
331+
332+ # convert to float and apply scaling
333+ if self .is_complex_data :
334+ # for complex data, mem is shaped (..., 2) where last dim is [real, imag]
335+ real_part = mem [..., 0 ].astype (np .float32 )
336+ imag_part = mem [..., 1 ].astype (np .float32 )
337+
338+ # apply scaling to both parts
339+ if is_unsigned_data :
340+ real_part -= 2 ** (component_size * 8 - 1 )
341+ imag_part -= 2 ** (component_size * 8 - 1 )
342+ real_part *= 2 ** - (component_size * 8 - 1 )
343+ imag_part *= 2 ** - (component_size * 8 - 1 )
344+
345+ # combine into complex numbers
346+ data = real_part + 1.0j * imag_part
347+ else :
348+ # for real data, direct scaling
349+ data = mem .astype (np .float32 )
337350 if is_unsigned_data :
338351 data -= 2 ** (component_size * 8 - 1 )
339352 data *= 2 ** - (component_size * 8 - 1 )
340- data = data .view (data_type_out )
341- if self .is_complex_data :
342- data = data .view (np .complex64 )
343- # for single-channel complex data, flatten the last dimension
344- if data .ndim > 1 and self .num_channels == 1 :
345- data = data .flatten ()
346- return data [0 ] if isinstance (sli , int ) else data
347- else :
348- # floating-point data, no scaling needed
349- return mem
350-
351- # handle complex data type conversion
352- if self ._memmap .ndim == 2 :
353- # num_channels == 1
354- ray = mem [:, 0 ].astype (self ._return_type ) + 1.0j * mem [:, 1 ].astype (self ._return_type )
355- elif self ._memmap .ndim == 3 :
356- # num_channels > 1
357- ray = mem [:, :, 0 ].astype (self ._return_type ) + 1.0j * mem [:, :, 1 ].astype (self ._return_type )
358- else :
359- raise ValueError ("unhandled ndim in SigMFFile.__getitem__(); this shouldn't happen" )
360- return ray [0 ] if isinstance (sli , int ) else ray # return element instead of 1-element array
353+
354+ return data
355+
356+ # handle complex data type conversion if _return_type is set (no autoscaling was applied)
357+ if self ._return_type is not None :
358+ if self ._memmap .ndim == 2 :
359+ # num_channels == 1
360+ ray = mem [:, 0 ].astype (self ._return_type ) + 1.0j * mem [:, 1 ].astype (self ._return_type )
361+ elif self ._memmap .ndim == 3 :
362+ # num_channels > 1
363+ ray = mem [:, :, 0 ].astype (self ._return_type ) + 1.0j * mem [:, :, 1 ].astype (self ._return_type )
364+ else :
365+ raise ValueError ("unhandled ndim in SigMFFile.__getitem__(); this shouldn't happen" )
366+ return ray [0 ] if isinstance (sli , int ) else ray # return element instead of 1-element array
367+
368+ # return raw data (no autoscaling, no complex conversion needed)
369+ return mem
361370
362371 def get_num_channels (self ):
363372 """Return integer number of channels."""
0 commit comments