Spaces:
Running on Zero
Running on Zero
| """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) | |