Almost implemented oversampling for F0
This commit is contained in:
@@ -91,6 +91,12 @@ class Analysis(object):
|
||||
vtimes = times.reshape(-1, 1)
|
||||
|
||||
selection = np.transpose((vtimes >= start) & (vtimes <= end))
|
||||
# If there are no frames for this grain, take the two closest frames
|
||||
# from the adjacent grains.
|
||||
if not selection.any():
|
||||
frame_center = start + (end-start)/2.
|
||||
closest_frames = np.abs(vtimes-frame_center).argsort()[:2]
|
||||
selection[closest_frames] = True
|
||||
|
||||
#start_ind = np.min(selection)
|
||||
#end_ind = np.argmax(selection)
|
||||
|
||||
@@ -7,6 +7,7 @@ from numpy.lib import stride_tricks
|
||||
from Analysis import Analysis
|
||||
from scipy import signal
|
||||
from numpy.fft import fft, ifft, fftshift
|
||||
from sppysound import multirate
|
||||
import warnings
|
||||
|
||||
from numpy import polyfit, arange
|
||||
@@ -70,6 +71,10 @@ class F0Analysis(Analysis):
|
||||
vtimes = times.reshape(-1, 1)
|
||||
|
||||
selection = np.transpose((vtimes >= start) & (vtimes <= end))
|
||||
if not selection.any():
|
||||
frame_center = start + (end-start)/2.
|
||||
closest_frames = np.abs(vtimes-frame_center).argsort()[:2]
|
||||
selection[closest_frames] = True
|
||||
|
||||
return ((frames, times, hr), selection)
|
||||
|
||||
@@ -92,6 +97,7 @@ class F0Analysis(Analysis):
|
||||
if not M:
|
||||
M=int(round(0.016*samplerate))
|
||||
|
||||
|
||||
hopSize = int(window_size - np.floor(overlapFac * window_size))
|
||||
|
||||
# zeros at beginning (thus center of 1st window should be for sample nr. 0)
|
||||
@@ -116,21 +122,6 @@ class F0Analysis(Analysis):
|
||||
Z = (1/(2*window.size)) * np.sum(np.abs(np.sign(window)-np.sign(window2)))
|
||||
return Z
|
||||
|
||||
def autocorr(x):
|
||||
"""
|
||||
FFT based autocorrelation function, which is faster than numpy.correlate
|
||||
Operates on muti-dimensional arrays on a per element basis.
|
||||
|
||||
Ref: http://stackoverflow.com/questions/4503325/autocorrelation-of-a-multidimensional-array-in-numpy
|
||||
|
||||
"""
|
||||
length = np.size(x, axis=1)
|
||||
# x is supposed to be an array of sequences, of shape (totalelements, length)
|
||||
fftx = fft(x, n=(length*2-1), axis=1)
|
||||
ret = ifft(fftx * np.conjugate(fftx), axis=1).real
|
||||
ret = fftshift(ret, axes=1)
|
||||
return ret
|
||||
|
||||
def parabolic(f, x):
|
||||
"""
|
||||
Quadratic interpolation for estimating the true position of an
|
||||
@@ -232,10 +223,13 @@ class F0Analysis(Analysis):
|
||||
Formats the output from the analysis method to save to the HDF5 file.
|
||||
'''
|
||||
samplerate = self.AnalysedAudioFile.samplerate
|
||||
data = self.create_f0_analysis(*args, **kwargs)
|
||||
frames = args[0]
|
||||
frames = multirate.interp(frames, 2)
|
||||
samplerate *= 2
|
||||
data = self.create_f0_analysis(frames, samplerate, **kwargs)
|
||||
f0 = data[:, 0]
|
||||
harmonic_ratio = data[:, 1]
|
||||
f0_times = self.calc_f0_frame_times(f0, args[0], samplerate)
|
||||
f0_times = self.calc_f0_frame_times(f0, frames, samplerate)
|
||||
return ({'frames': f0, 'harmonic_ratio': harmonic_ratio, 'times': f0_times}, {})
|
||||
|
||||
@staticmethod
|
||||
@@ -267,7 +261,6 @@ class F0Analysis(Analysis):
|
||||
'log2_median': self.log2_median,
|
||||
}
|
||||
|
||||
# For debugging apply along axis:
|
||||
if not selection.size:
|
||||
# TODO: Add warning here
|
||||
return np.nan
|
||||
|
||||
@@ -46,6 +46,10 @@ class F0HarmRatioAnalysis(Analysis):
|
||||
vtimes = times.reshape(-1, 1)
|
||||
|
||||
selection = np.transpose((vtimes >= start) & (vtimes <= end))
|
||||
if not selection.any():
|
||||
frame_center = start + (end-start)/2.
|
||||
closest_frames = np.abs(vtimes-frame_center).argsort()[:2]
|
||||
selection[closest_frames] = True
|
||||
|
||||
return ((hr, times), selection)
|
||||
|
||||
@@ -53,6 +57,7 @@ class F0HarmRatioAnalysis(Analysis):
|
||||
def calc_F0HarmRatio_frame_times(F0HarmRatioframes, sample_frames, samplerate):
|
||||
|
||||
"""Calculate times for frames using sample size and samplerate."""
|
||||
samplerate *= 4
|
||||
|
||||
# Get number of frames for time and frequency
|
||||
timebins = F0HarmRatioframes.shape[0]
|
||||
|
||||
@@ -5,7 +5,7 @@ rms = {
|
||||
}
|
||||
|
||||
f0 = {
|
||||
"window_size": 2048,
|
||||
"window_size": 8192,
|
||||
"overlap": 8,
|
||||
"ratio_threshold": 0.0
|
||||
}
|
||||
@@ -55,7 +55,7 @@ matcher_weightings = {
|
||||
"kurtosis": 1.,
|
||||
"skewness": 1.,
|
||||
"variance": 2.,
|
||||
"harm_ratio": 5.
|
||||
"harm_ratio": 2.
|
||||
}
|
||||
|
||||
# Specifies the method for averaging analysis frames to create a single value
|
||||
|
||||
Reference in New Issue
Block a user