code: def attenuation_curve(signal, resp, fs, calf, smooth_pts=99):
      
      # remove dc offset
      y = resp - np.mean(resp)
      x = signal
  
      # frequencies present in calibration spectrum
      npts = len(y)
      fq = np.arange(npts / 2 + 1) / (float(npts) / fs)
  
      # convert time signals to frequency domain
      Y = np.fft.rfft(y)
      X = np.fft.rfft(x)
  
      # take the magnitude of signals
      Ymag = np.sqrt(Y.real ** 2 + Y.imag ** 2)  # equivalent to abs(Y)
      Xmag = np.sqrt(X.real ** 2 + X.imag ** 2)
  
      # convert to decibel scale
      YmagdB = 20 * np.log10(Ymag)
      XmagdB = 20 * np.log10(Xmag)
  
      # now we can substract to get attenuation curve
      diffdB = XmagdB - YmagdB
  
      # may want to smooth results here?
      diffdB = smooth(diffdB, smooth_pts)
  
      # shift by the given calibration frequency to align attenutation
      # with reference point set by user
      fidx = (np.abs(fq - calf)).argmin()
      diffdB -= diffdB[fidx]
  
      return diffdB
docs: Calculate an attenuation roll-off curve, from a signal and its recording
  
      :param signal: ouput signal delivered to the generation hardware
      :type signal: numpy.ndarray    
      :param resp: recording of given signal, as recieved from microphone
      :type resp: numpy.ndarray
      :param fs: input and output samplerate (should be the same)
      :type fs: int
      :param smooth_pts: amount of averaging to use on the result
      :type smooth_pts: int
      :returns: numpy.ndarray -- attenuation vector