class_docstr: A helper class to compute metrics for MIDI output.
class_docstr_tok: ["A","helper","class","to","compute","metrics","for","MIDI","output","."]
docstr: Align the notes in the NoteSequence with the extracted f0_hz.
docstr_tok: ["Align","the","notes","in","the","NoteSequence","with","the","extracted","f0_hz","."]
code: def align_midi_with_f0(self, gt_sequence, f0):
      """Align the notes in the NoteSequence with the extracted f0_hz."""
      sr = self._frames_per_second
      f0_midi = np.round(ddsp.core.hz_to_midi(f0))
      for i, note in enumerate(gt_sequence.notes):
          # look for the first match in [end of last note, end of curr note]
          lower_bound = (
              int(gt_sequence.notes[i - 1].end_time * sr)
              if i > 0
              else 0
          )
          upper_bound = int(note.end_time * sr)
          for j in range(lower_bound, upper_bound):
              if int(f0_midi[j]) == note.pitch:
                  note.start_time = float(j) / sr
                  break
  
          # look for the last match in [start of curr note, start of next note]
          lower_bound = int(note.start_time * sr)
          upper_bound = (
              int(gt_sequence.notes[i + 1].start_time * sr)
              if i < (len(gt_sequence.notes) - 1)
              else len(f0_midi) - 1
          )
          for j in range(upper_bound, lower_bound, -1):
              if int(f0_midi[j]) == note.pitch:
                  note.end_time = float(j) / sr
                  break
      return gt_sequence
  
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 4 for calling the MidiMetrics obj's underlying member method code with example usage: obj.align_midi_with_f0(gt_sequence, f0) and returns: gt_sequence