def process(self, spectrogram):
mult = np.multiply(self.weights, np.ones((1, spectrogram.shape[1])))
square_mag = np.power(spectrogram.magnitude(),2)
square_mag = np.vstack((square_mag[1:,:],np.flipud(square_mag[1:,:])))
square_mag_sum = np.sum(square_mag, 0)
energy_threshold = np.percentile(square_mag_sum, 25)
res = np.fft.rfft(square_mag.T, 2 * (self.n_bins - 1)).T
resN = np.abs(res)
resP = np.angle(res)
yin = np.zeros((spectrogram.shape))
yin[0,:] = 1
tmp = np.zeros((spectrogram.shape[1],))
for tau in range(1, self.n_bins):
yin[tau,:] = square_mag_sum - resN[tau,:] * np.cos(resP[tau,:])
tmp += yin[tau,:]
yin[tau,:] *= tau/tmp
tau = self.tau_min + np.argmin(yin[self.tau_min:self.tau_max,:],0)
y_min = np.min(yin[self.tau_min:self.tau_max,:],0)
tau = tau[:,np.newaxis]
if self.interp:
ranges = np.hstack((tau - 5, tau - 4, tau - 3, tau-2,tau-1,tau,
tau+1,tau + 2, tau + 3, tau + 4, tau + 5))
new_tau = np.empty_like(tau)
for frame in range(spectrogram.shape[1]):
r = ranges[frame]
r[0] = max(r[0], 0)
r[1] = min(r[1], self.n_bins-1)
val = yin[r.astype(int), frame]
tck = interpolate.splrep(r, val, s=0, k = 2)
xnew = np.arange(r[0],r[-1], (r[-1] - r[0]) /10)
ynew = interpolate.splev(xnew, tck, der=0)
new_tau[frame] = xnew[np.argmin(ynew)]
y_min[frame] = np.min(ynew)
tau = new_tau
tau = tau[:,0]
pitch_confidence = 1- y_min
pitch = np.zeros((spectrogram.shape[1],))
pitch[tau!=0] = np.nan_to_num(self.sample_rate * 1.0 / (tau[tau!=0]))
pitch[tau==0] = 0
pitch_confidence[tau==0] = 0
pitch[square_mag_sum < energy_threshold] = 0
pitch_confidence[square_mag_sum < energy_threshold] = 0
return (pitch, pitch_confidence)
评论列表
文章目录