From 99b855323590998b8eb335599d85f829a6429075 Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Thu, 29 Apr 2021 20:48:21 +0200 Subject: [PATCH] Bugfix in exportAsWave, with normalize --- lasp/lasp_measurement.py | 44 +++++++++++++++------------------------- 1 file changed, 16 insertions(+), 28 deletions(-) diff --git a/lasp/lasp_measurement.py b/lasp/lasp_measurement.py index a44ba4d..1e86a24 100644 --- a/lasp/lasp_measurement.py +++ b/lasp/lasp_measurement.py @@ -96,6 +96,9 @@ class IterRawData: Args: f: Audio dataset in the h5 file, accessed as f['audio'] + channels: list of channel indices to use + istart: index of first sample + istop: index of last sample (not including istop) """ assert isinstance(channels, list) @@ -173,22 +176,6 @@ class IterData(IterRawData): return scaleBlockSens(nextraw, self.sens) - -def exportAsWave(fn, fs, data, force=False): - if '.wav' not in fn[-4:]: - fn += '.wav' - - nchannels = data.shape[1] - sampwidth = getSampWidth(data.dtype) - - if os.path.exists(fn) and not force: - raise RuntimeError('File already exists: %s', fn) - - with wave.open(fn, 'w') as wf: - wf.setparams((nchannels, sampwidth, fs, 0, 'NONE', 'NONE')) - wf.writeframes(np.asfortranarray(data).tobytes()) - - class Measurement: """Provides access to measurement data stored in the h5 measurement file format.""" @@ -594,7 +581,7 @@ class Measurement: def exportAsWave(self, fn=None, force=False, newsampwidth=None, - normalize=True, channels=None): + normalize=True, **kwargs): """Export measurement file as wave. In case the measurement data is stored as floats, the values are scaled to the proper integer (PCM) data format. @@ -626,20 +613,21 @@ class Measurement: if not np.isclose(self.samplerate%1,0): raise RuntimeError(f'Sample rates should be approximately integer for exporting to Wave to work') - # TODO: With VERY large files, this is not possible! - data = self.rawData() - if np.issubdtype(data.dtype, np.floating): - if newsampwidth is None: - raise ValueError('Newsampwidth parameter should be given for floating point raw data') - + # TODO: With VERY large measurment files, this is not possible! Is this + # a theoretical case? + 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: - maxabs = np.max(np.abs(data), axis=0) - data /= maxabs[np.newaxis, :] + # Scale back to maximum of absolute value + maxabs = np.max(np.abs(data)) + data /= maxabs if newsampwidth is not None: # Convert to floats, then to new sample width - data = scaleBlockSens(data, self.sensitivity**0) + sensone = np.ones_like(self.sensitivity) + data = scaleBlockSens(data, sensone) if newsampwidth == 2: newtype = np.int16 @@ -648,11 +636,11 @@ class Measurement: 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) - wavfile.write(fn, int(self.samplerate), data) @staticmethod