Download python/flowhigh_sdk/audio.py from HY-2012/FlowHigh.AXERA: direct link, hf CLI and curl.
- Browser
- Download file 4.17 kB
-
https://huggingface.co/HY-2012/FlowHigh.AXERA/resolve/main/python/flowhigh_sdk/audio.py
- Command line
-
hf download hf://HY-2012/FlowHigh.AXERA/python/flowhigh_sdk/audio.py
-
curl -L -o audio.py https://huggingface.co/HY-2012/FlowHigh.AXERA/resolve/main/python/flowhigh_sdk/audio.py
4.17 kB
| import numpy as np | |
| from math import gcd | |
| SR = 48000 | |
| N_FFT = 2048 | |
| HOP = 480 | |
| N_MELS = 256 | |
| FMIN = 20.0 | |
| FMAX = 24000.0 | |
| LOG_FLOOR = 1e-5 | |
| MAG_EPS = 1e-9 | |
| _MEL = None | |
| _WIN = None | |
| def _hz_to_mel(f): | |
| f = np.asarray(f, dtype=np.float64) | |
| f_sp, min_log_hz = 200.0 / 3.0, 1000.0 | |
| min_log_mel = min_log_hz / f_sp | |
| logstep = np.log(6.4) / 27.0 | |
| mel = np.empty_like(f) | |
| lin = f < min_log_hz | |
| mel[lin] = f[lin] / f_sp | |
| mel[~lin] = min_log_mel + np.log(f[~lin] / min_log_hz) / logstep | |
| return mel | |
| def _mel_to_hz(m): | |
| m = np.asarray(m, dtype=np.float64) | |
| f_sp, min_log_hz = 200.0 / 3.0, 1000.0 | |
| min_log_mel = min_log_hz / f_sp | |
| logstep = np.log(6.4) / 27.0 | |
| hz = np.empty_like(m) | |
| lin = m < min_log_mel | |
| hz[lin] = m[lin] * f_sp | |
| hz[~lin] = min_log_hz * np.exp(logstep * (m[~lin] - min_log_mel)) | |
| return hz | |
| def mel_filterbank(): | |
| global _MEL | |
| if _MEL is None: | |
| freqs = np.linspace(0.0, SR / 2.0, N_FFT // 2 + 1) | |
| edges = np.linspace(_hz_to_mel([FMIN])[0], _hz_to_mel([FMAX])[0], N_MELS + 2) | |
| hz = _mel_to_hz(edges) | |
| fb = np.zeros((N_MELS, freqs.shape[0]), dtype=np.float32) | |
| for m in range(N_MELS): | |
| left, center, right = hz[m], hz[m + 1], hz[m + 2] | |
| up = (freqs - left) / (center - left) | |
| down = (right - freqs) / (right - center) | |
| fb[m] = np.maximum(0.0, np.minimum(up, down)) * (2.0 / max(1e-8, right - left)) | |
| _MEL = fb | |
| return _MEL | |
| def hann(): | |
| global _WIN | |
| if _WIN is None: | |
| _WIN = np.hanning(N_FFT + 1)[:-1].astype(np.float64) | |
| return _WIN | |
| def log_mel(audio): | |
| x = np.asarray(audio, dtype=np.float64).reshape(-1) | |
| pad = (N_FFT - HOP) // 2 | |
| x = np.pad(x, (pad, pad), mode="reflect") | |
| frames = 1 + (x.size - N_FFT) // HOP | |
| idx = np.arange(N_FFT)[None, :] + HOP * np.arange(frames)[:, None] | |
| spec = np.fft.rfft(x[idx] * hann(), n=N_FFT, axis=1).T | |
| mag = np.sqrt(spec.real ** 2 + spec.imag ** 2 + MAG_EPS) | |
| mel = np.log(np.clip(mel_filterbank() @ mag, LOG_FLOOR, None)) | |
| return mel.T[None].astype(np.float32) | |
| def stft(x, center=True, pad_mode="constant"): | |
| x = np.asarray(x, dtype=np.float64).reshape(-1) | |
| if center: | |
| p = N_FFT // 2 | |
| x = np.pad(x, (p, p), mode=pad_mode) | |
| frames = 1 + (x.size - N_FFT) // HOP | |
| idx = np.arange(N_FFT)[None, :] + HOP * np.arange(frames)[:, None] | |
| return np.fft.rfft(x[idx] * hann(), n=N_FFT, axis=1).T | |
| def istft(spec, length=None, center=True): | |
| spec = np.asarray(spec) | |
| frames = np.fft.irfft(spec.T, n=N_FFT, axis=1) * hann() | |
| out_len = N_FFT + HOP * (frames.shape[0] - 1) | |
| ola = np.zeros(out_len, dtype=np.float64) | |
| wsum = np.zeros(out_len, dtype=np.float64) | |
| w2 = hann() ** 2 | |
| for i in range(frames.shape[0]): | |
| s = i * HOP | |
| ola[s:s + N_FFT] += frames[i] | |
| wsum[s:s + N_FFT] += w2 | |
| ola /= np.where(wsum > 1e-11, wsum, 1.0) | |
| if center: | |
| ola = ola[N_FFT // 2:len(ola) - N_FFT // 2] | |
| if length is not None: | |
| if ola.size > length: | |
| ola = ola[:length] | |
| elif ola.size < length: | |
| ola = np.pad(ola, (0, length - ola.size)) | |
| return ola.astype(np.float32) | |
| def cutoff_bin(spec): | |
| energy = np.cumsum(np.abs(spec).sum(axis=-1)) | |
| if energy[-1] <= 0: | |
| return 0 | |
| limit = energy[-1] * 0.99 | |
| below = np.nonzero(energy < limit)[0] | |
| return int(below[-1]) + 1 if below.size else 0 | |
| def postprocess(pred, src, length): | |
| ps = stft(pred, center=True, pad_mode="constant") | |
| ss = stft(src, center=True, pad_mode="constant") | |
| n = min(ps.shape[-1], ss.shape[-1]) | |
| ps, ss = ps[:, :n], ss[:, :n] | |
| cr = cutoff_bin(ss) | |
| merged = ps.copy() | |
| merged[:cr] = ss[:cr] | |
| out = istft(merged, length=length, center=True) | |
| peak = np.max(np.abs(out)) | |
| if peak > 0: | |
| out = out / peak * 0.99 | |
| return out.astype(np.float32) | |
| def resample(x, sr_in, sr_out=SR): | |
| x = np.asarray(x, dtype=np.float32).reshape(-1) | |
| if sr_in == sr_out: | |
| return x | |
| g = gcd(int(sr_out), int(sr_in)) | |
| from scipy.signal import resample_poly | |
| return resample_poly(x, sr_out // g, sr_in // g).astype(np.float32) | |