waveform_analysis
waveform_analysis copied to clipboard
ValueError: Invalid number of FFT data points (0) specified.
I get a ValueError when I try to call freq_from_hps
on a filtered segments of this audio file. I segment and filter my signal like this before calling freq_from_hps
on every segment:
def get_pitches(filename, sr=44100):
# Get onset times.
onset_frames = get_onset_frames(filename, sr)
# Filter the signal.
filtered_y = bandpass_filter(y, sr, 80., 4000.)
# Get pitches.
hps_pitches = detect_pitch(filtered_y, sr, onset_frames, 'hps')
def detect_pitch(y, sr, onset_frames, method='stft', stft_offset=10, fmin=80, fmax=4000):
pitches, magnitudes = librosa.piptrack(y=y,
sr=sr, fmin=fmin, fmax=fmax)
...
elif method == 'hps':
slices = segment_signal(y, sr, onset_frames)
for segment in slices:
pitch = freq_from_hps(segment, sr)
result_pitches.append(pitch)
...
return result_pitches
def bandpass_filter(y, sr, lowcut, highcut):
# Setup parameters.
nyquist_rate = sr / 2.
filter_order = 3
normalized_low = lowcut / nyquist_rate
normalized_high = highcut / nyquist_rate
sos = butter(filter_order, [normalized_low, normalized_high],
btype='bandpass', output='sos')
y = sosfilt(sos, y)
return y
def segment_signal(y, sr, onset_frames):
offset_end = int(librosa.time_to_samples(0.2, sr))
slices = np.array([y[i : i + offset_end] for i
in librosa.frames_to_samples(onset_frames)])
return slices
I specifically get this error:
/home/pavlos55/guitartab/app/frequency_estimator.py:107: RuntimeWarning: divide by zero encountered in log
X = log(abs(rfft(windowed)))
/home/pavlos55/guitartab/.env/local/lib/python2.7/site-packages/numpy/core/fromnumeric.py:2889: RuntimeWarning: Mean of empty slice.
out=out, **kwargs)
/home/pavlos55/guitartab/.env/local/lib/python2.7/site-packages/numpy/core/_methods.py:80: RuntimeWarning: invalid value encountered in double_scalars
ret = ret.dtype.type(ret / rcount)
127.0.0.1 - - [30/May/2017 18:51:09] "POST / HTTP/1.1" 500 -
Traceback (most recent call last):
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1997, in __call__
return self.wsgi_app(environ, start_response)
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
response = self.handle_exception(e)
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
reraise(exc_type, exc_value, tb)
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
response = self.full_dispatch_request()
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
rv = self.dispatch_request()
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/pavlos55/guitartab/app/app.py", line 39, in index
pitches = handle_file(file)
File "/home/pavlos55/guitartab/app/app.py", line 53, in handle_file
pitches = mir.transcribe(filepath)
File "/home/pavlos55/guitartab/app/mir.py", line 49, in transcribe
hps_pitches = detect_pitch(filtered_y, sr, onset_frames, 'hps')
File "/home/pavlos55/guitartab/app/mir.py", line 106, in detect_pitch
pitch = freq_from_hps(segment, sr)
File "/home/pavlos55/guitartab/app/frequency_estimator.py", line 107, in freq_from_hps
X = log(abs(rfft(windowed)))
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/numpy/fft/fftpack.py", line 372, in rfft
_real_fft_cache)
File "/home/pavlos55/guitartab/.env/lib/python2.7/site-packages/numpy/fft/fftpack.py", line 56, in _raw_fft
% n)
Any ideas?
Are you feeding a zero-length array to freq_from_hps()
?
freq_from_hps(array([]), 48000)
does the same thing?
@pavlos163 did you fix that? if not, @endolith there is some workaround?
def get_frequency_from_fft(sig, fs = 44100) -> str:
"""
Estimate frequency from peak of FFT
"""
# Compute Fourier transform of windowed signal
windowed = sig * blackmanharris(len(sig))
f = np.fft.rfft(windowed)
# Find the peak and interpolate to get a more accurate peak
#i = np.argmax(abs(f)) # Just use this for less-accurate, naive version
i = np.argmax(abs(f))
j = np.log(abs(f))
if j[i] < 0:
r = '0'
else:
i = _parabolic(j, i)[0]
...
I made this.