code: def spectrogram_to_mel_matrix(
      num_mel_bins=20,
      num_spectrogram_bins=129,
      audio_sample_rate=8000,
      lower_edge_hertz=125.0,
      upper_edge_hertz=3800.0,
      unused_dtype=None,
  ):
      """Return a matrix that can post-multiply spectrogram rows to make mel.
  
      Copied from
      https://github.com/tensorflow/models/blob/master/research/audioset/mel_features.py.
  
      Returns a np.array matrix A that can be used to post-multiply a matrix S of
      spectrogram values (STFT magnitudes) arranged as frames x bins to generate a
      "mel spectrogram" M of frames x num_mel_bins.  M = S A.
  
      The classic HTK algorithm exploits the complementarity of adjacent mel bands
      to multiply each FFT bin by only one mel weight, then add it, with positive
      and negative signs, to the two adjacent mel bands to which that bin
      contributes.  Here, by expressing this operation as a matrix multiply, we go
      from num_fft multiplies per frame (plus around 2*num_fft adds) to around
      num_fft^2 multiplies and adds.  However, because these are all presumably
      accomplished in a single call to np.dot(), it's not clear which approach is
      faster in Python.  The matrix multiplication has the attraction of being more
      general and flexible, and much easier to read.
  
      Args:
        num_mel_bins: How many bands in the resulting mel spectrum.  This is
          the number of columns in the output matrix.
        num_spectrogram_bins: How many bins there are in the source spectrogram
          data, which is understood to be fft_size/2 + 1, i.e. the spectrogram
          only contains the nonredundant FFT bins.
        audio_sample_rate: Samples per second of the audio at the input to the
          spectrogram. We need this to figure out the actual frequencies for
          each spectrogram bin, which dictates how they are mapped into mel.
        lower_edge_hertz: Lower bound on the frequencies to be included in the mel
          spectrum.  This corresponds to the lower edge of the lowest triangular
          band.
        upper_edge_hertz: The desired top edge of the highest frequency band.
  
      Returns:
        An np.array with shape (num_spectrogram_bins, num_mel_bins).
  
      Raises:
        ValueError: if frequency edges are incorrectly ordered.
      """
      audio_sample_rate = tensor_util.constant_value(audio_sample_rate)
      nyquist_hertz = audio_sample_rate / 2.0
      if lower_edge_hertz >= upper_edge_hertz:
          raise ValueError(
              "lower_edge_hertz %.1f >= upper_edge_hertz %.1f"
              % (lower_edge_hertz, upper_edge_hertz)
          )
      spectrogram_bins_hertz = np.linspace(
          0.0, nyquist_hertz, num_spectrogram_bins
      )
      spectrogram_bins_mel = hertz_to_mel(spectrogram_bins_hertz)
      # The i'th mel band (starting from i=1) has center frequency
      # band_edges_mel[i], lower edge band_edges_mel[i-1], and higher edge
      # band_edges_mel[i+1].  Thus, we need num_mel_bins + 2 values in
      # the band_edges_mel arrays.
      band_edges_mel = np.linspace(
          hertz_to_mel(lower_edge_hertz),
          hertz_to_mel(upper_edge_hertz),
          num_mel_bins + 2,
      )
      # Matrix to post-multiply feature arrays whose rows are num_spectrogram_bins
      # of spectrogram values.
      mel_weights_matrix = np.empty(
          (num_spectrogram_bins, num_mel_bins)
      )
      for i in range(num_mel_bins):
          lower_edge_mel, center_mel, upper_edge_mel = band_edges_mel[
              i : i + 3
          ]
          # Calculate lower and upper slopes for every spectrogram bin.
          # Line segments are linear in the *mel* domain, not hertz.
          lower_slope = (spectrogram_bins_mel - lower_edge_mel) / (
              center_mel - lower_edge_mel
          )
          upper_slope = (upper_edge_mel - spectrogram_bins_mel) / (
              upper_edge_mel - center_mel
          )
          # .. then intersect them with each other and zero.
          mel_weights_matrix[:, i] = np.maximum(
              0.0, np.minimum(lower_slope, upper_slope)
          )
      # HTK excludes the spectrogram DC bin; make sure it always gets a zero
      # coefficient.
      mel_weights_matrix[0, :] = 0.0
      return mel_weights_matrix
  
imports: from absl.testing import parameterized
  import numpy
  from tensorflow.python.eager import context
  from tensorflow.python.framework import constant_op
  from tensorflow.python.framework import dtypes
  from tensorflow.python.framework import ops
  from tensorflow.python.framework import tensor_util
  from tensorflow.python.framework import test_util
  from tensorflow.python.kernel_tests.signal import test_util
  from tensorflow.python.ops import array_ops
  from tensorflow.python.ops.signal import mel_ops
  from tensorflow.python.platform import test
label_desc: Use image node_id 2 for calling a global function with example usage: spectrogram_to_mel_matrix(num_mel_bins, num_spectrogram_bins, audio_sample_rate, lower_edge_hertz, upper_edge_hertz, unused_dtype) and returns: mel_weights_matrix