From c30960b1a3ac22721f041d3707bda8593e1981da Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F" Date: Thu, 9 Jul 2020 09:45:08 +0200 Subject: [PATCH] Added method to import measurement data from a wave file --- lasp/lasp_avstream.py | 2 +- lasp/lasp_measurement.py | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/lasp/lasp_avstream.py b/lasp/lasp_avstream.py index 168d443..aaa08f7 100644 --- a/lasp/lasp_avstream.py +++ b/lasp/lasp_avstream.py @@ -73,7 +73,7 @@ class AvStream: rtaudio_inputparams = None rtaudio_outputparams = None - self.nframes_per_block = 512 + self.nframes_per_block = 1024 if self.duplex_mode or avtype == AvType.audio_output: rtaudio_outputparams = {'deviceid': device.index, diff --git a/lasp/lasp_measurement.py b/lasp/lasp_measurement.py index 02418c6..1b5d532 100644 --- a/lasp/lasp_measurement.py +++ b/lasp/lasp_measurement.py @@ -489,6 +489,8 @@ class Measurement: firstcoltime: If true, the first column is the treated as the sample time. """ + if os.path.splitext(mfn)[1] != '.h5': + mfn += '.h5' if os.path.exists(mfn): raise ValueError(f'File {mfn} already exist.') if timestamp is None: @@ -497,6 +499,13 @@ class Measurement: if data.ndim != 2: data = data[:, np.newaxis] + try: + len(sensitivity) + except: + raise ValueError('Sensitivity should be given as array-like data type') + sensitivity = np.asarray(sensitivity) + + nchannels = data.shape[1] if nchannels != sensitivity.shape[0]: raise ValueError( @@ -514,3 +523,45 @@ class Measurement: compression='gzip') ad[0] = data return Measurement(mfn) + + @staticmethod + def fromWaveFile(fn, newfn=None, force=False, timestamp=None): + """Convert a measurement file to a wave file, and return the + measurement handle.""" + if timestamp is None: + timestamp = int(time.time()) + + base_fn = os.path.splitext(fn)[0] + if newfn is None: + newfn = base_fn + '.h5' + if os.path.exists(newfn) and not force: + raise RuntimeError(f'Measurement file name {newfn} already exists in path, set "force" to true to overwrite') + + with wave.open(fn, 'r') as wf: + nchannels = wf.getnchannels() + samplerate = wf.getframerate() + sensitivity = np.ones(nchannels) + sampwidth = wf.getsampwidth() + nframes = wf.getnframes() + if sampwidth == 2: + dtype = np.int16 + elif sampwidth == 1: + dtype = np.int8 + elif sampwidth == 4: + dtype = np.int32 + + with h5.File(newfn, 'w') as hf: + hf.attrs['samplerate'] = samplerate + hf.attrs['nchannels'] = nchannels + hf.attrs['time'] = timestamp + hf.attrs['blocksize'] = 1 + hf.attrs['sensitivity'] = sensitivity + data = np.frombuffer( + wf.readframes(nframes), dtype=dtype).reshape(nframes, nchannels) + ad = hf.create_dataset('audio', (1, data.shape[0], data.shape[1]), + dtype=dtype, + maxshape=(1, data.shape[0], data.shape[1]), + compression='gzip') + ad[0] = data + + return Measurement(newfn)