code: def chroma(chromagram, times, fs, **kwargs):
      
      # We'll just use time_frequency with a Shepard tone-gram
      # To create the Shepard tone-gram, we copy the chromagram across 7 octaves
      n_octaves = 7
      # starting from C2
      base_note = 24
      # and weight each octave by a normal distribution
      # The normal distribution has mean 72 (one octave above middle C)
      # and std 6 (one half octave)
      mean = 72
      std = 6
      notes = np.arange(12*n_octaves) + base_note
      shepard_weight = np.exp(-(notes - mean)**2./(2.*std**2.))
      # Copy the chromagram matrix vertically n_octaves times
      gram = np.tile(chromagram.T, n_octaves).T
      # This fixes issues if the supplied chromagram is int type
      gram = gram.astype(float)
      # Apply Sheppard weighting
      gram *= shepard_weight.reshape(-1, 1)
      # Compute frequencies
      frequencies = 440.0*(2.0**((notes - 69)/12.0))
      return time_frequency(gram, frequencies, times, fs, **kwargs)
docs: Reverse synthesis of a chromagram (semitone matrix)
  
      Parameters
      ----------
      chromagram : np.ndarray, shape=(12, times.shape[0])
          Chromagram matrix, where each row represents a semitone [C->Bb]
          i.e., ``chromagram[3, j]`` is the magnitude of D# from ``times[j]`` to
          ``times[j + 1]``
      times: np.ndarray, shape=(len(chord_labels),) or (len(chord_labels), 2)
          Either the start time of each column in the chromagram,
          or the time interval corresponding to each column.
      fs : int
          Sampling rate to synthesize audio data at
      kwargs
          Additional keyword arguments to pass to
          :func:`mir_eval.sonify.time_frequency`
  
      Returns
      -------
      output : np.ndarray
          Synthesized chromagram