Merge remote-tracking branch 'origin/develop' into develop
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
3844827505
@ -274,7 +274,6 @@ class Measurement:
|
|||||||
self._qtys = [SIQtys.default() for i in range(self.nchannels)]
|
self._qtys = [SIQtys.default() for i in range(self.nchannels)]
|
||||||
logging.debug(f'Physical quantity data not available in measurement file. Assuming {SIQtys.default}')
|
logging.debug(f'Physical quantity data not available in measurement file. Assuming {SIQtys.default}')
|
||||||
|
|
||||||
|
|
||||||
def setAttribute(self, atrname, value):
|
def setAttribute(self, atrname, value):
|
||||||
"""
|
"""
|
||||||
Set an attribute in the measurement file, and keep a local copy in
|
Set an attribute in the measurement file, and keep a local copy in
|
||||||
@ -632,8 +631,8 @@ class Measurement:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def exportAsWave(self, fn=None, force=False, newsampwidth=None,
|
def exportAsWave(self, fn=None, force=False, dtype=None,
|
||||||
normalize=True, **kwargs):
|
normalize=False, **kwargs):
|
||||||
"""Export measurement file as wave. In case the measurement data is
|
"""Export measurement file as wave. In case the measurement data is
|
||||||
stored as floats, the values are scaled to the proper integer (PCM)
|
stored as floats, the values are scaled to the proper integer (PCM)
|
||||||
data format.
|
data format.
|
||||||
@ -645,9 +644,8 @@ class Measurement:
|
|||||||
force: If True, overwrites any existing files with the given name
|
force: If True, overwrites any existing files with the given name
|
||||||
, otherwise a RuntimeError is raised.
|
, otherwise a RuntimeError is raised.
|
||||||
|
|
||||||
newsampwidth: sample width in bytes with which to export the data.
|
dtype: if not None, convert data to this data type.
|
||||||
This should only be given in case the measurement data is stored as
|
Options are 'int16', 'int32', 'float32'.
|
||||||
floating point values, otherwise an error is thrown
|
|
||||||
|
|
||||||
normalize: If set: normalize the level to something sensible.
|
normalize: If set: normalize the level to something sensible.
|
||||||
"""
|
"""
|
||||||
@ -661,39 +659,49 @@ class Measurement:
|
|||||||
if os.path.exists(fn) and not force:
|
if os.path.exists(fn) and not force:
|
||||||
raise RuntimeError(f'File already exists: {fn}')
|
raise RuntimeError(f'File already exists: {fn}')
|
||||||
|
|
||||||
|
|
||||||
if not np.isclose(self.samplerate%1,0):
|
if not np.isclose(self.samplerate%1,0):
|
||||||
raise RuntimeError(f'Sample rates should be approximately integer for exporting to Wave to work')
|
raise RuntimeError(f'Sample rates should be approximately integer for exporting to Wave to work')
|
||||||
|
|
||||||
# TODO: With VERY large measurment files, this is not possible! Is this
|
# TODO: With VERY large measurment files, this is not possible! Is this
|
||||||
# a theoretical case?
|
# a theoretical case?
|
||||||
|
# TODO: add sensitivity? Then use self.data() instead of self.rawData()
|
||||||
data = self.rawData(**kwargs)
|
data = self.rawData(**kwargs)
|
||||||
if np.issubdtype(data.dtype, np.floating) and newsampwidth is None:
|
|
||||||
raise ValueError('Newsampwidth parameter should be given for floating point raw data')
|
|
||||||
|
|
||||||
if normalize:
|
if normalize:
|
||||||
# Scale back to maximum of absolute value
|
# Scale back to maximum of absolute value
|
||||||
maxabs = np.max(np.abs(data))
|
maxabs = np.max(np.abs(data))
|
||||||
data = data / maxabs # "data /= maxabs" fails if dtpyes differ
|
data = data / maxabs # "data /= maxabs" fails if dtpyes differ
|
||||||
|
|
||||||
if newsampwidth is not None:
|
if dtype==None:
|
||||||
# Convert to floats, then to new sample width
|
dtype = data.dtype # keep existing
|
||||||
|
logging.debug(f"dtype not passed as arg; using dtype = {dtype}")
|
||||||
|
|
||||||
|
# dtype conversion
|
||||||
|
if dtype=='int16':
|
||||||
|
newtype = np.int16
|
||||||
|
newsampwidth = 2
|
||||||
|
elif dtype=='int32':
|
||||||
|
newtype = np.int32
|
||||||
|
newsampwidth = 4
|
||||||
|
elif dtype=='float32':
|
||||||
|
newtype = np.float32
|
||||||
|
elif dtype=='float64':
|
||||||
|
newtype = np.float64
|
||||||
|
else:
|
||||||
|
logging.debug(f"cannot handle this dtype {dtype}")
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Convert range to [-1, 1]
|
||||||
|
# TODO: this is wrong for float data where full scale > 1
|
||||||
sensone = np.ones_like(self.sensitivity)
|
sensone = np.ones_like(self.sensitivity)
|
||||||
data = scaleBlockSens(data, sensone)
|
data = scaleBlockSens(data, sensone)
|
||||||
|
|
||||||
if newsampwidth == 2:
|
if dtype=='int16' or dtype=='int32':
|
||||||
newtype = np.int16
|
# Scale data to integer range and convert to integers
|
||||||
elif newsampwidth == 4:
|
|
||||||
newtype = np.int32
|
|
||||||
else:
|
|
||||||
raise ValueError('Invalid sample width, should be 2 or 4')
|
|
||||||
|
|
||||||
scalefac = 2**(8*newsampwidth-1)-1
|
scalefac = 2**(8*newsampwidth-1)-1
|
||||||
|
|
||||||
# Scale data to integer range, and then convert to integers
|
|
||||||
data = (data*scalefac).astype(newtype)
|
data = (data*scalefac).astype(newtype)
|
||||||
|
|
||||||
wavfile.write(fn, int(self.samplerate), data)
|
wavfile.write(fn, int(self.samplerate), data.astype(newtype))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def fromtxt(fn,
|
def fromtxt(fn,
|
||||||
|
Loading…
Reference in New Issue
Block a user