waveform_analysis icon indicating copy to clipboard operation
waveform_analysis copied to clipboard

ValueError: Invalid number of FFT data points (0) specified.

Open pavlos163 opened this issue 7 years ago • 3 comments

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?

pavlos163 avatar May 30 '17 17:05 pavlos163

Are you feeding a zero-length array to freq_from_hps()?

freq_from_hps(array([]), 48000) does the same thing?

endolith avatar Jun 11 '17 01:06 endolith

@pavlos163 did you fix that? if not, @endolith there is some workaround?

Master64k avatar Jun 24 '18 19:06 Master64k

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.

Master64k avatar Jun 24 '18 20:06 Master64k