Tran Dang Khoa
Add application file
cafad09
Raw
History Blame Contribute Delete
2.71 kB
"""Small DSP helpers needed by model definitions."""
from __future__ import annotations
import numpy as np
def hz_to_midi(hz):
"""Convert frequencies in Hz to MIDI note numbers."""
hz = np.asarray(hz)
return 69.0 + 12.0 * np.log2(hz / 440.0)
def midi_to_hz(midi):
"""Convert MIDI note numbers to frequencies in Hz."""
midi = np.asarray(midi)
return 440.0 * np.power(2.0, (midi - 69.0) / 12.0)
def _hz_to_mel(frequencies, *, htk=False):
frequencies = np.asarray(frequencies, dtype=np.float64)
if htk:
return 2595.0 * np.log10(1.0 + frequencies / 700.0)
f_sp = 200.0 / 3
mels = frequencies / f_sp
min_log_hz = 1000.0
min_log_mel = min_log_hz / f_sp
logstep = np.log(6.4) / 27.0
log_t = frequencies >= min_log_hz
mels = np.array(mels, copy=True)
mels[log_t] = min_log_mel + np.log(frequencies[log_t] / min_log_hz) / logstep
return mels
def _mel_to_hz(mels, *, htk=False):
mels = np.asarray(mels, dtype=np.float64)
if htk:
return 700.0 * (np.power(10.0, mels / 2595.0) - 1.0)
f_sp = 200.0 / 3
freqs = f_sp * mels
min_log_hz = 1000.0
min_log_mel = min_log_hz / f_sp
logstep = np.log(6.4) / 27.0
log_t = mels >= min_log_mel
freqs = np.array(freqs, copy=True)
freqs[log_t] = min_log_hz * np.exp(logstep * (mels[log_t] - min_log_mel))
return freqs
def mel_frequencies(n_mels, *, fmin=0.0, fmax=11025.0, htk=False):
"""Return center frequencies on the mel scale, including endpoints."""
min_mel = _hz_to_mel(fmin, htk=htk)
max_mel = _hz_to_mel(fmax, htk=htk)
return _mel_to_hz(np.linspace(min_mel, max_mel, int(n_mels)), htk=htk)
def fft_frequencies(*, sr, n_fft):
"""Return FFT bin center frequencies."""
return np.linspace(0.0, float(sr) / 2.0, int(1 + n_fft // 2), endpoint=True)
def mel_filterbank(sr, n_fft, n_mels=128, fmin=0.0, fmax=None, htk=False, norm="slaney", dtype=np.float32):
"""Create a triangular mel filterbank for model initialization."""
if fmax is None:
fmax = float(sr) / 2.0
mel_f = mel_frequencies(int(n_mels) + 2, fmin=fmin, fmax=fmax, htk=htk)
fft_f = fft_frequencies(sr=sr, n_fft=n_fft)
fdiff = np.diff(mel_f)
ramps = np.subtract.outer(mel_f, fft_f)
lower = -ramps[:-2] / fdiff[:-1, np.newaxis]
upper = ramps[2:] / fdiff[1:, np.newaxis]
weights = np.maximum(0.0, np.minimum(lower, upper))
if norm == "slaney":
enorm = 2.0 / (mel_f[2 : int(n_mels) + 2] - mel_f[: int(n_mels)])
weights *= enorm[:, np.newaxis]
elif norm is not None:
raise ValueError(f"Unsupported mel filterbank norm: {norm!r}")
return weights.astype(dtype, copy=False)