Spaces:
Build error
Build error
import numba as nb | |
import numpy as np | |
def find_nearest_stft_bin(f0_, freqs): | |
freqs = np.expand_dims(freqs, 0) | |
f0_ = np.expand_dims(f0_, 1) | |
return np.abs(freqs - f0_).argmin() | |
def get_med_curve(f0, step_size=20): | |
v_begin = -1 | |
v_end = -1 | |
x_med_curve = [] | |
y_med_curve = [] | |
T = len(f0) | |
for i in range(T): | |
if f0[i] >= 50 and i < T - 1: | |
if v_begin == -1: | |
v_begin = i | |
v_end = i | |
else: | |
if v_end != -1: | |
if v_end - v_begin > 3: | |
for j in range(v_begin, v_end + 1 - step_size, step_size): | |
frag_med = np.median(f0[j:j + step_size]) | |
x_med_curve.append(j) | |
y_med_curve.append(frag_med) | |
x_med_curve.append(v_end) | |
y_med_curve.append(np.median(f0[v_end - step_size:v_end + 1])) | |
v_end = v_begin = -1 | |
x_med_curve = [0] + x_med_curve + [T] | |
x_med_curve = np.array(x_med_curve) | |
y_med_curve = [y_med_curve[0]] + y_med_curve + [y_med_curve[-1]] | |
y_med_curve = np.array(y_med_curve) | |
return x_med_curve, y_med_curve | |
def clean_short_v_frag(f0): | |
v_begin = -1 | |
T = len(f0) | |
uv = np.zeros_like(f0).astype(np.bool_) | |
for i in range(T): | |
if f0[i] >= 1e-4 and i < T - 1: | |
if v_begin == -1: | |
v_begin = i | |
else: | |
if v_begin != -1: | |
v_end = i if f0[i] >= 1e-4 else i - 1 | |
if v_end - v_begin + 1 < 3: | |
uv[v_begin:v_end + 1] = 1 | |
v_begin = -1 | |
return uv | |
def find_best_f0_using_har_energy(spec, pitches, freqs, hars, hars_mhalf, f0_min, f0_max): | |
re = np.zeros_like(spec) | |
T = len(spec) | |
for i in range(T): | |
spec_i = spec[i] | |
for j, f0_j in enumerate(pitches[i]): | |
if f0_j == 0 or f0_j < f0_min[i] or f0_j > f0_max[i]: | |
continue | |
mask = np.zeros((10000,)) | |
mask_mhalf = np.zeros((10000,)) | |
for mul in hars: | |
b = find_nearest_stft_bin(np.array((f0_j * mul,)), freqs) | |
for delta in range(-1, 2): | |
mask[b + delta] = 1 | |
for mul in hars_mhalf: | |
b_mhalf = find_nearest_stft_bin(np.array((f0_j * (mul - 0.5),)), freqs) | |
for delta in range(-1, 2): | |
mask_mhalf[b_mhalf + delta] = 1 | |
mask = mask[:len(spec_i)] | |
mask_mhalf = mask_mhalf[:len(spec_i)] | |
energy = (np.exp(spec_i) * mask).sum() / mask.sum() | |
energy_mhalf = (np.exp(spec_i) * mask_mhalf).sum() / mask_mhalf.sum() | |
re[i, j] = energy / energy_mhalf | |
f0_2d_mask = 10000 * (re > 2) + 20000 * (re > 3) + np.expand_dims(np.arange(re.shape[1])[::-1], 0) | |
f0_idx = np.zeros((T,), dtype=np.int_) | |
for i in range(T): | |
f0_idx[i] = f0_2d_mask[i].argmax() | |
uv = re.sum(-1) == 0 | |
f0 = np.zeros((T,)) | |
for i in range(T): | |
f0[i] = pitches[i, f0_idx[i]] | |
f0 = f0 * (1 - uv) | |
uv = clean_short_v_frag(f0) | |
f0[uv] = 0 | |
x_med_curve, y_med_curve = get_med_curve(f0) | |
re = re * (re > 1.5) | |
return re, f0, x_med_curve, y_med_curve | |