|
1 | 1 | import itertools |
2 | 2 | import matplotlib.pyplot as plt |
3 | 3 | import numpy as np |
4 | | -from scipy.io import wavfile |
5 | 4 | from scipy.signal import detrend, lfilter, bilinear, spectrogram, filtfilt, resample, fftconvolve |
| 5 | +import soundfile as sf |
6 | 6 | import acoustics |
7 | 7 |
|
8 | 8 | from acoustics.standards.iso_tr_25417_2007 import REFERENCE_PRESSURE |
@@ -1019,35 +1019,32 @@ def normalize(self, gap=6.0, inplace=False): |
1019 | 1019 | else: |
1020 | 1020 | return self / factor[..., None] |
1021 | 1021 |
|
1022 | | - def to_wav(self, filename, depth=16): |
| 1022 | + def to_wav(self, filename, depth=16, format="WAV"): |
1023 | 1023 | """Save signal as WAV file. |
1024 | 1024 |
|
1025 | 1025 | :param filename: Name of file to save to. |
1026 | 1026 | :param depth: If given, convert to integer with specified depth. Else, try to store using the original data type. |
| 1027 | + :param format: It can be either WAV or FLAC |
1027 | 1028 |
|
1028 | | - By default, this function saves a normalized 16-bit version of the signal with at least 6 dB range till clipping occurs. |
| 1029 | + Note that the floating point samples are not yet supported. |
1029 | 1030 |
|
1030 | 1031 | """ |
1031 | | - data = self |
1032 | | - dtype = data.dtype if not depth else 'int' + str(depth) |
1033 | | - if depth: |
1034 | | - data = (data * 2**(depth - 1) - 1).astype(dtype) |
1035 | | - wavfile.write(filename, int(self.fs), data.T) |
1036 | | - #wavfile.write(filename, int(self.fs), self._data/np.abs(self._data).max() * 0.5) |
1037 | | - #wavfile.write(filename, int(self.fs), np.int16(self._data/(np.abs(self._data).max()) * 32767) ) |
| 1032 | + subtype = "PCM_{}".format(depth) |
| 1033 | + sf.write(filename, self.T, int(self.fs), format=format, subtype=subtype) |
1038 | 1034 |
|
1039 | 1035 | @classmethod |
1040 | | - def from_wav(cls, filename): |
| 1036 | + def from_wav(cls, filename, normalize=True): |
1041 | 1037 | """ |
1042 | 1038 | Create an instance of `Signal` from a WAV file. |
1043 | 1039 |
|
1044 | 1040 | :param filename: Filename |
| 1041 | + :param normalize: Optionally normalize the input samples |
1045 | 1042 |
|
1046 | 1043 | """ |
1047 | | - fs, data = wavfile.read(filename) |
1048 | | - data = data.astype(np.float32, copy=False).T |
1049 | | - data /= np.max(np.abs(data)) |
1050 | | - return cls(data, fs=fs) |
| 1044 | + data, fs = sf.read(filename) |
| 1045 | + if normalize: |
| 1046 | + data /= np.max(np.abs(data)) |
| 1047 | + return cls(data.T, fs=fs) |
1051 | 1048 |
|
1052 | 1049 |
|
1053 | 1050 | _PLOTTING_PARAMS = { |
|
0 commit comments