code: def filterbank(signal, fs, pre_emphasis=0.97, nfft=512, nfilt=40):
      """Computes the MEL-spaced filterbank.
  
      It provides the information about the power in each frequency band.
  
      Implementation details and description on:
      https://www.kaggle.com/ilyamich/mfcc-implementation-and-tutorial
      https://haythamfayek.com/2016/04/21/speech-processing-for-machine-learning.html#fnref:1
  
      Parameters
      ----------
      signal : nd-array
          Input from which filterbank is computed
      fs : float
          Sampling frequency
      pre_emphasis : float
          Pre-emphasis coefficient for pre-emphasis filter application
      nfft : int
          Number of points of fft
      nfilt : int
          Number of filters
  
      Returns
      -------
      nd-array
          MEL-spaced filterbank
  
      """
  
      # Signal is already a window from the original signal, so no frame is needed.
      # According to the references it is needed the application of a window function such as
      # hann window. However if the signal windows don't have overlap, we will lose information,
      # as the application of a hann window will overshadow the windows signal edges.
  
      # pre-emphasis filter to amplify the high frequencies
  
      emphasized_signal = np.append(
          np.array(signal)[0],
          np.array(signal[1:]) - pre_emphasis * np.array(signal[:-1]),
      )
  
      # Fourier transform and Power spectrum
      mag_frames = np.absolute(
          np.fft.rfft(emphasized_signal, nfft)
      )  # Magnitude of the FFT
  
      pow_frames = (1.0 / nfft) * (mag_frames**2)  # Power Spectrum
  
      low_freq_mel = 0
      high_freq_mel = 2595 * np.log10(
          1 + (fs / 2) / 700
      )  # Convert Hz to Mel
      mel_points = np.linspace(
          low_freq_mel, high_freq_mel, nfilt + 2
      )  # Equally spaced in Mel scale
      hz_points = 700 * (
          10 ** (mel_points / 2595) - 1
      )  # Convert Mel to Hz
      filter_bin = np.floor((nfft + 1) * hz_points / fs)
  
      fbank = np.zeros((nfilt, int(np.floor(nfft / 2 + 1))))
      for m in range(1, nfilt + 1):
          f_m_minus = int(filter_bin[m - 1])  # left
          f_m = int(filter_bin[m])  # center
          f_m_plus = int(filter_bin[m + 1])  # right
  
          for k in range(f_m_minus, f_m):
              fbank[m - 1, k] = (k - filter_bin[m - 1]) / (
                  filter_bin[m] - filter_bin[m - 1]
              )
          for k in range(f_m, f_m_plus):
              fbank[m - 1, k] = (filter_bin[m + 1] - k) / (
                  filter_bin[m + 1] - filter_bin[m]
              )
  
      # Area Normalization
      # If we don't normalize the noise will increase with frequency because of the filter width.
      enorm = 2.0 / (hz_points[2 : nfilt + 2] - hz_points[:nfilt])
      fbank *= enorm[:, np.newaxis]
  
      filter_banks = np.dot(pow_frames, fbank.T)
      filter_banks = np.where(
          filter_banks == 0, np.finfo(float).eps, filter_banks
      )  # Numerical Stability
      filter_banks = 20 * np.log10(filter_banks)  # dB
  
      return filter_banks
  
file_path: tsfel/tsfel/feature_extraction/features_utils.py
imports: import scipy
  import numpy
label_desc: Use image node_id 4 for calling a global function with example usage: filterbank(signal, fs, pre_emphasis, nfft, nfilt) and returns: filter_banks