class_docstr: Converts to/from multiple-instrument metric performances.
  
  Attributes:
    num_velocity_bins: Number of velocity bins.
    max_tensors_per_notesequence: The maximum number of outputs to return
        for each NoteSequence.
    hop_size_bars: How many bars each sequence should be.
    chunk_size_bars: Chunk size used for hierarchically decomposing sequence.
    steps_per_quarter: Number of time steps per quarter note.
    quarters_per_bar: Number of quarter notes per bar.
    min_num_instruments: Minimum number of instruments per sequence.
    max_num_instruments: Maximum number of instruments per sequence.
    min_total_events: Minimum total length of all performance tracks, in events.
    max_events_per_instrument: Maximum length of a single-instrument
        performance, in events.
    first_subsequence_only: If True, only use the very first hop and discard all
        sequences longer than the hop size.
    chord_encoding: An instantiated OneHotEncoding object to use for encoding
        chords on which to condition, or None if not conditioning on chords.
    drop_tracks_and_truncate: Randomly drop extra tracks and truncate the event
        sequence.
class_docstr_tok: ["Converts","to\/from","multiple-instrument","metric","performances",".","Attributes",":","num_velocity_bins",":","Number","of","velocity","bins",".","max_tensors_per_notesequence",":","The","maximum","number","of","outputs","to","return","for","each","NoteSequence",".","hop_size_bars",":","How","many","bars","each","sequence","should","be",".","chunk_size_bars",":","Chunk","size","used","for","hierarchically","decomposing","sequence",".","steps_per_quarter",":","Number","of","time","steps","per","quarter","note",".","quarters_per_bar",":","Number","of","quarter","notes","per","bar",".","min_num_instruments",":","Minimum","number","of","instruments","per","sequence",".","max_num_instruments",":","Maximum","number","of","instruments","per","sequence",".","min_total_events",":","Minimum","total","length","of","all","performance","tracks",",","in","events",".","max_events_per_instrument",":","Maximum","length","of","a","single-instrument","performance",",","in","events",".","first_subsequence_only",":","If","True",",","only","use","the","very","first","hop","and","discard","all","sequences","longer","than","the","hop","size",".","chord_encoding",":","An","instantiated","OneHotEncoding","object","to","use","for","encoding","chords","on","which","to","condition",",","or","None","if","not","conditioning","on","chords",".","drop_tracks_and_truncate",":","Randomly","drop","extra","tracks","and","truncate","the","event","sequence","."]
code: def _quantized_subsequence_to_tensors(self, quantized_subsequence):
      # Reject sequences with out-of-range pitches.
      if any(
          note.pitch < self._min_pitch or note.pitch > self._max_pitch
          for note in quantized_subsequence.notes
      ):
          return [], []
  
      # Extract all instruments.
      tracks, _ = performance_pipeline.extract_performances(
          quantized_subsequence,
          max_steps_truncate=self._max_steps_truncate,
          num_velocity_bins=self._num_velocity_bins,
          split_instruments=True,
      )
  
      if (
          self._drop_tracks_and_truncate
          and len(tracks) > self._max_num_instruments
      ):
          tracks = random.sample(tracks, self._max_num_instruments)
  
      # Reject sequences with too few instruments.
      if not (
          self._min_num_instruments
          <= len(tracks)
          <= self._max_num_instruments
      ):
          return [], []
  
      # Sort tracks by program, with drums at the end.
      tracks = sorted(tracks, key=lambda t: (t.is_drum, t.program))
  
      chunk_size_steps = self._steps_per_bar * self._chunk_size_bars
      chunks = [[] for _ in range(self._max_num_chunks)]
  
      total_length = 0
  
      for track in tracks:
          # Make sure the track is the proper number of time steps.
          track.set_length(self._max_steps_truncate)
  
          # Split this track into chunks.
          def new_performance(
              quantized_sequence, start_step, track=track
          ):
              steps_per_quarter = (
                  self._steps_per_quarter
                  if quantized_sequence is None
                  else None
              )
              return performance_lib.MetricPerformance(
                  quantized_sequence=quantized_sequence,
                  steps_per_quarter=steps_per_quarter,
                  start_step=start_step,
                  num_velocity_bins=self._num_velocity_bins,
                  program=track.program,
                  is_drum=track.is_drum,
              )
  
          track_chunks = split_performance(
              track,
              chunk_size_steps,
              new_performance,
              clip_tied_notes=True,
          )
  
          assert len(track_chunks) == self._max_num_chunks
  
          if self._drop_tracks_and_truncate:
              for i in range(len(track_chunks)):
                  track_chunks[i].truncate(
                      self._max_events_per_instrument - 2
                  )
  
          track_chunk_lengths = [
              len(track_chunk) for track_chunk in track_chunks
          ]
          # Each track chunk needs room for program token and end token.
          if not all(
              l <= self._max_events_per_instrument - 2
              for l in track_chunk_lengths
          ):
              return [], []
          if not all(
              note_seq.MIN_MIDI_PROGRAM
              <= t.program
              <= note_seq.MAX_MIDI_PROGRAM
              for t in track_chunks
              if not t.is_drum
          ):
              return [], []
  
          total_length += sum(track_chunk_lengths)
  
          # Aggregate by chunk.
          for i, track_chunk in enumerate(track_chunks):
              chunks[i].append(track_chunk)
  
      # Reject sequences that are too short (in events).
      if total_length < self._min_total_events:
          return [], []
  
      num_programs = (
          note_seq.MAX_MIDI_PROGRAM - note_seq.MIN_MIDI_PROGRAM + 1
      )
  
      chunk_tensors = []
      chunk_chord_tensors = []
  
      for chunk_tracks in chunks:
          track_tensors = []
  
          for track in chunk_tracks:
              # Add a special token for program at the beginning of each track.
              track_tokens = [
                  self._performance_encoding.num_classes
                  + (num_programs if track.is_drum else track.program)
              ]
              # Then encode the performance events.
              for event in track:
                  track_tokens.append(
                      self._performance_encoding.encode_event(event)
                  )
              # Then add the end token.
              track_tokens.append(self.end_token)
  
              encoded_track = data.np_onehot(
                  track_tokens, self.output_depth, self.output_dtype
              )
              track_tensors.append(encoded_track)
  
          if self._chord_encoding:
              # Extract corresponding chords for each track. The chord sequences may
              # be different for different tracks even though the underlying chords
              # are the same, as the performance event times will generally be
              # different.
              try:
                  track_chords = chords_lib.event_list_chords(
                      quantized_subsequence, chunk_tracks
                  )
              except chords_lib.CoincidentChordsError:
                  return [], []
  
              track_chord_tensors = []
  
              try:
                  # Chord encoding for all tracks is inside this try block. If any
                  # track fails we need to skip the whole subsequence.
  
                  for chords in track_chords:
                      # Start with a pad token corresponding to the track program token.
                      track_chord_tokens = [self._control_pad_token]
                      # Then encode the chords.
                      for chord in chords:
                          track_chord_tokens.append(
                              self._chord_encoding.encode_event(chord)
                          )
                      # Then repeat the final chord for the track end token.
                      track_chord_tokens.append(track_chord_tokens[-1])
  
                      encoded_track_chords = data.np_onehot(
                          track_chord_tokens,
                          self.control_depth,
                          self.control_dtype,
                      )
                      track_chord_tensors.append(encoded_track_chords)
  
              except (
                  note_seq.ChordSymbolError,
                  note_seq.ChordEncodingError,
              ):
                  return [], []
  
              chunk_chord_tensors.append(track_chord_tensors)
  
          chunk_tensors.append(track_tensors)
  
      return chunk_tensors, chunk_chord_tensors
  
imports: import abc
  import random
  from magenta.models.music_vae import data
  from magenta.pipelines import performance_pipeline
  import note_seq
  from note_seq import chords_lib
  from note_seq import performance_lib
  import numpy
  import tensorflow.compat.v1
label_desc: Use image node_id 2 for calling the MultiInstrumentPerformanceConverter obj's underlying member method code with example usage: obj._quantized_subsequence_to_tensors(quantized_subsequence) and returns: chunk_tensors,  chunk_chord_tensors, list,  list, list,  list, list,  list, performance_lib, list,  list, list,  list, list,  list, list,  list