Almost implemented oversampling for F0

This commit is contained in:
2016-04-12 23:39:48 +01:00
parent 9c4de3e9c2
commit a6bf541693
4 changed files with 24 additions and 20 deletions
+6
View File
@@ -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)
+11 -18
View File
@@ -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]
+2 -2
View File
@@ -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