Porównaj commity

...

3 Commity

Autor SHA1 Wiadomość Data
Ewald de Wit 5260360bb7 Fix whitespace 2022-11-22 09:46:26 +01:00
Ewald de Wit f90a6e06ee Small optimization for smoothing 2022-11-22 09:44:04 +01:00
Ewald de Wit b487b17019 write_correction function added 2022-11-22 09:43:09 +01:00
2 zmienionych plików z 19 dodań i 10 usunięć

Wyświetl plik

@ -175,8 +175,8 @@ class Analyzer:
db = a[1] db = a[1]
freq = self.frequency() freq = self.frequency()
interp = np.empty_like(freq) interp = np.empty_like(freq)
interp[1:] = np.interp(np.log(freq[1:]), logF, db)
interp[0] = 0 interp[0] = 0
interp[1:] = np.interp(np.log(freq[1:]), logF, db)
return interp return interp
def X(self) -> np.ndarray: def X(self) -> np.ndarray:
@ -288,12 +288,12 @@ class Analyzer:
t = np.linspace(0, z.size / self.rate, z.size) t = np.linspace(0, z.size / self.rate, z.size)
return XY(t, z) return XY(t, z)
def correctionFactor(self, invResp: np.ndarray) -> XY: def correctionFactor(self, h_inv: np.ndarray) -> XY:
""" """
Calculate correction factor for each frequency, given the Calculate correction factor for each frequency, given the
inverse impulse response. inverse impulse response.
""" """
Z = np.abs(rfft(invResp)) Z = np.abs(rfft(h_inv))
Z /= Z.max() Z /= Z.max()
freq = np.linspace(0, self.rate / 2, Z.size) freq = np.linspace(0, self.rate / 2, Z.size)
return XY(freq, Z) return XY(freq, Z)
@ -392,7 +392,7 @@ def smooth(freq: np.ndarray, data: np.ndarray, smoothing: float) -> np.ndarray:
""" """
if not smoothing: if not smoothing:
return data return data
weight = 1 / (1 + freq * 2 ** (smoothing / 2 - 15)) weight = 1 / (1 + 2 ** (smoothing / 2 - 15) * freq)
smoothed = np.empty_like(data) smoothed = np.empty_like(data)
prev = data[-1] prev = data[-1]
for i, w in enumerate(np.flip(weight), 1): for i, w in enumerate(np.flip(weight), 1):
@ -421,8 +421,8 @@ def transform_causality(x: np.ndarray, causality: float = 1) -> np.ndarray:
the given impulse. the given impulse.
Params: Params:
causality: 0 = linear-phase, 1 = minimum-phase and causality: 0 = linear-phase, 1 = minimum-phase,
in-between values smoothly transition between these two. in-between values smoothly transition between the two.
https://www.rle.mit.edu/dspg/documents/AVOHomoorphic75.pdf https://www.rle.mit.edu/dspg/documents/AVOHomoorphic75.pdf
https://www.katjaas.nl/minimumphase/minimumphase.html https://www.katjaas.nl/minimumphase/minimumphase.html

Wyświetl plik

@ -6,12 +6,15 @@ import numpy.typing as npt
class Sound(NamedTuple): class Sound(NamedTuple):
"""Audio sample- and meta- data."""
data: np.ndarray data: np.ndarray
rate: int rate: int
width: int = 4 width: int = 4
Correction = List[Tuple[float, float]] Correction = List[Tuple[float, float]]
"""List of (frequency, db) tuples."""
def write_wav(path: str, data: npt.ArrayLike, rate: int, width: int = 4): def write_wav(path: str, data: npt.ArrayLike, rate: int, width: int = 4):
@ -51,9 +54,7 @@ def write_wav(path: str, data: npt.ArrayLike, rate: int, width: int = 4):
def read_wav(path: str) -> Sound: def read_wav(path: str) -> Sound:
""" """Read WAV file and return float32 arrays between -1 and 1."""
Read WAV file and return float32 arrays between -1 and 1.
"""
with wave.open(path, 'rb') as wav: with wave.open(path, 'rb') as wav:
ch, width, rate, n, _, _ = wav.getparams() ch, width, rate, n, _, _ = wav.getparams()
frames = wav.readframes(n) frames = wav.readframes(n)
@ -79,12 +80,20 @@ def read_wav(path: str) -> Sound:
return Sound(data, rate, width) return Sound(data, rate, width)
def write_correction(path: str, correction: Correction):
"""Write (frequency, db) tuples to a space-separated file."""
txt = '\n'.join(f'{freq} {db}' for freq, db in correction)
with open(path, 'w') as f:
f.write(txt)
def read_correction(path: str) -> Correction: def read_correction(path: str) -> Correction:
"""Read (frequency, db) tuples from comma- or space-separated file."""
corr = [] corr = []
with open(path, 'r') as f: with open(path, 'r') as f:
for line in f.readlines(): for line in f.readlines():
try: try:
freq, db = line.split() freq, db = line.split(',' if ',' in line else None)
corr.append((float(freq), float(db))) corr.append((float(freq), float(db)))
except ValueError: except ValueError:
pass pass