code: def compute_dataset_statistics(
      data_provider,
      batch_size=1,
      power_frame_size=1024,
      power_frame_rate=50,
  ):
      """Calculate dataset stats.
  
      Args:
        data_provider: A DataProvider from ddsp.training.data.
        batch_size: Iterate over dataset with this batch size.
        power_frame_size: Calculate power features on the fly with this frame size.
        power_frame_rate: Calculate power features on the fly with this frame rate.
  
      Returns:
        Dictionary of dataset statistics. This is an overcomplete set of statistics,
        as there are now several different tone transfer implementations (js, colab,
        vst) that need different statistics for normalization.
      """
      print("Calculating dataset statistics for", data_provider)
      ds = data_provider.get_batch(batch_size, repeats=1)
  
      # Unpack dataset.
      i = 0
      loudness = []
      power = []
      f0 = []
      f0_conf = []
      audio = []
  
      batch = next(iter(ds))
      audio_key = (
          "audio_16k" if "audio_16k" in batch.keys() else "audio"
      )
  
      for batch in iter(ds):
          loudness.append(batch["loudness_db"])
          power.append(
              spectral_ops.compute_power(
                  batch[audio_key],
                  frame_size=power_frame_size,
                  frame_rate=power_frame_rate,
              )
          )
          f0.append(batch["f0_hz"])
          f0_conf.append(batch["f0_confidence"])
          audio.append(batch[audio_key])
          i += 1
  
      print(f"Computing statistics for {i * batch_size} examples.")
  
      loudness = np.vstack(loudness)
      power = np.vstack(power)
      f0 = np.vstack(f0)
      f0_conf = np.vstack(f0_conf)
      audio = np.vstack(audio)
  
      # Fit the transform.
      trim_end = 20
      f0_trimmed = f0[:, :-trim_end]
      pitch_trimmed = hz_to_midi(f0_trimmed)
      power_trimmed = power[:, :-trim_end]
      loudness_trimmed = loudness[:, :-trim_end]
      f0_conf_trimmed = f0_conf[:, :-trim_end]
  
      # Detect notes.
      mask_on, _ = detect_notes(loudness_trimmed, f0_conf_trimmed)
  
      # If no notes detected, just default to using full signal.
      mask_on = np.logical_or(
          mask_on,
          np.logical_not(np.any(mask_on, axis=1, keepdims=True)),
      )
  
      quantile_transform = fit_quantile_transform(
          loudness_trimmed, mask_on
      )
  
      # Pitch statistics.
      def get_stats(x, prefix="x", note_mask=None):
          if note_mask is None:
              mean_max = np.mean(np.max(x, axis=-1))
              mean_min = np.mean(np.min(x, axis=-1))
          else:
              max_list = []
              for x_i, m in zip(x, note_mask):
                  if np.sum(m) > 0:
                      max_list.append(np.max(x_i[m]))
              mean_max = np.mean(max_list)
  
              min_list = []
              for x_i, m in zip(x, note_mask):
                  if np.sum(m) > 0:
                      min_list.append(np.min(x_i[m]))
              mean_min = np.mean(min_list)
  
              x = x[note_mask]
  
          return {
              f"mean_{prefix}": np.mean(x),
              f"max_{prefix}": np.max(x),
              f"min_{prefix}": np.min(x),
              f"mean_max_{prefix}": mean_max,
              f"mean_min_{prefix}": mean_min,
              f"std_{prefix}": np.std(x),
          }
  
      ds_stats = {}
      ds_stats.update(get_stats(pitch_trimmed, "pitch"))
      ds_stats.update(get_stats(power_trimmed, "power"))
      ds_stats.update(get_stats(loudness_trimmed, "loudness"))
      ds_stats.update(get_stats(pitch_trimmed, "pitch_note", mask_on))
      ds_stats.update(get_stats(power_trimmed, "power_note", mask_on))
      ds_stats.update(
          get_stats(loudness_trimmed, "loudness_note", mask_on)
      )
  
      ds_stats["quantile_transform"] = quantile_transform
      return ds_stats
  
file_path: ddsp/ddsp/training/postprocessing.py
imports: from ddsp import spectral_ops
  from ddsp.core import hz_to_midi
  import numpy
  from scipy import stats
  import tensorflow.compat.v2
label_desc: Use image node_id 3 for calling a global function with example usage: compute_dataset_statistics(data_provider, batch_size, power_frame_size, power_frame_rate) and returns: ds_stats, dict