class_docstr: A helper class to compute metrics for MIDI output.
class_docstr_tok: ["A","helper","class","to","compute","metrics","for","MIDI","output","."]
docstr: Update metrics with given controls and notes.
docstr_tok: ["Update","metrics","with","given","controls","and","notes","."]
code: def update_state(
      self,
      controls_batch,
      pred_seq_batch,
      gt_key="note_active_velocities",
      ch=None,
  ):
      """Update metrics with given controls and notes."""
  
      gt_pianoroll_batch = controls_batch[gt_key]
      for i in range(len(pred_seq_batch)):
          if ch is None:
              pred_sequence = pred_seq_batch[i]
              gt_pianoroll = gt_pianoroll_batch[i]
          else:
              pred_sequence = pred_seq_batch[i, ..., ch]
              gt_pianoroll = gt_pianoroll_batch[i, ..., ch]
  
          # ------ Note metrics
          gt_sequence = self._safe_convert_to_note_sequence(
              gt_pianoroll
          )
          pred_sequence = self._safe_convert_to_note_sequence(
              pred_sequence
          )
  
          if self._align_midi_with_f0:
              f0 = controls_batch["f0_hz"][i]
              gt_sequence = self.align_midi_with_f0(gt_sequence, f0)
  
          note_counts_i, note_offset_counts_i = compute_note_metrics(
              gt_sequence, pred_sequence
          )
          self.note_counts.add(note_counts_i)
          self.note_offset_counts.add(note_offset_counts_i)
  
          # ------ Framewise metrics
  
          # converting to/from note_seq adds empty frames at the end. Remove them.
          gt_len = gt_pianoroll.shape[0]
          pred_pianoroll = self._safe_convert_to_pianoroll(
              pred_sequence
          )
          pred_pianoroll = pred_pianoroll[:gt_len, :]
  
          frame_counts_i = compute_frame_metrics(
              gt_pianoroll, pred_pianoroll
          )
          self.frame_counts.add(frame_counts_i)
  
imports: import dataclasses
  from absl import logging
  import ddsp
  import librosa
  import mir_eval
  import note_seq
  from note_seq import sequences_lib
  import numpy
  import tensorflow.compat.v2
label_desc: Use image node_id 5 for calling the MidiMetrics obj's underlying member method code with example usage: obj.update_state(controls_batch, pred_seq_batch, gt_key, ch) without return types