Skip to content
This repository was archived by the owner on Feb 7, 2024. It is now read-only.

Commit 4a19451

Browse files
adrian-stepienFRidh
authored andcommitted
acoustics.Signal Loading backend switched to pysoundfile
Thanks to pysoundfile it's possible to laod WAV and FLAC files with integer samples. (Floating point is there out of the box, but requires a bit of API refactoring). Things removed: - When saving, samples are no-longer normalized - Normalization is optional during loading - by default it's on
1 parent e1cc8fe commit 4a19451

5 files changed

Lines changed: 20 additions & 17 deletions

File tree

‎acoustics/_signal.py‎

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import itertools
22
import matplotlib.pyplot as plt
33
import numpy as np
4-
from scipy.io import wavfile
54
from scipy.signal import detrend, lfilter, bilinear, spectrogram, filtfilt, resample, fftconvolve
5+
import soundfile as sf
66
import acoustics
77

88
from acoustics.standards.iso_tr_25417_2007 import REFERENCE_PRESSURE
@@ -1019,35 +1019,32 @@ def normalize(self, gap=6.0, inplace=False):
10191019
else:
10201020
return self / factor[..., None]
10211021

1022-
def to_wav(self, filename, depth=16):
1022+
def to_wav(self, filename, depth=16, format="WAV"):
10231023
"""Save signal as WAV file.
10241024
10251025
:param filename: Name of file to save to.
10261026
: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
10271028
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.
10291030
10301031
"""
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)
10381034

10391035
@classmethod
1040-
def from_wav(cls, filename):
1036+
def from_wav(cls, filename, normalize=True):
10411037
"""
10421038
Create an instance of `Signal` from a WAV file.
10431039
10441040
:param filename: Filename
1041+
:param normalize: Optionally normalize the input samples
10451042
10461043
"""
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)
10511048

10521049

10531050
_PLOTTING_PARAMS = {

‎default.nix‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
, bootstrapped-pip
2424
, stdenv
2525
, python
26+
, pysoundfile
2627
, development ? false
2728
}:
2829

@@ -52,7 +53,7 @@ in buildPythonPackage rec {
5253

5354
checkInputs = [ pytest glibcLocales ];
5455
nativeBuildInputs = lib.optionals development [ sphinx pylint yapf ];
55-
propagatedBuildInputs = [ cytoolz numpy scipy matplotlib pandas six tabulate ];
56+
propagatedBuildInputs = [ cytoolz numpy scipy matplotlib pandas six tabulate pysoundfile ];
5657

5758
meta = {
5859
description = "Acoustics module for Python";

‎requirements.txt‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ matplotlib
44
six
55
pandas
66
tabulate
7+
pysoundfile

‎setup.cfg‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ install_requires =
2424
six >= 1.4.1
2525
pandas >= 0.15
2626
tabulate
27+
pysoundfile
2728
tests_require =
2829
pytest
2930

‎tests/test__signal.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,14 @@ class test_wav():
2020
fs = 10025
2121
samples = int(fs * duration)
2222
channels = 3
23+
values = np.random.randn(channels, samples)
2324

24-
signal = Signal(np.random.randn(channels, samples), fs)
25+
signal = Signal(values, fs)
26+
signal.normalize(inplace=True)
2527

2628
with tempfile.TemporaryFile() as file:
2729
signal.to_wav(file)
30+
file.seek(0)
2831
signal = Signal.from_wav(file)
2932
assert signal.samples == samples
3033
assert signal.fs == fs

0 commit comments

Comments
 (0)