code: def split_performance(
      performance,
      steps_per_segment,
      new_performance_fn,
      clip_tied_notes=False,
  ):
      """Splits a performance into multiple fixed-length segments.
  
      Args:
        performance: A Performance (or MetricPerformance) object to split.
        steps_per_segment: The number of quantized steps per segment.
        new_performance_fn: A function to create new Performance (or
            MetricPerformance objects). Takes `quantized_sequence` and `start_step`
            arguments.
        clip_tied_notes: If True, clip tied notes across segments by converting each
            segment to NoteSequence and back.
  
      Returns:
        A list of performance segments.
      """
      segments = []
      cur_segment = new_performance_fn(
          quantized_sequence=None, start_step=0
      )
      cur_step = 0
      for e in performance:
          if (
              e.event_type
              != performance_lib.PerformanceEvent.TIME_SHIFT
          ):
              if cur_step == steps_per_segment:
                  # At a segment boundary, note-offs happen before the cutoff.
                  # Everything else happens after.
                  if (
                      e.event_type
                      != performance_lib.PerformanceEvent.NOTE_OFF
                  ):
                      segments.append(cur_segment)
                      cur_segment = new_performance_fn(
                          quantized_sequence=None,
                          start_step=len(segments) * steps_per_segment,
                      )
                      cur_step = 0
                  cur_segment.append(e)
              else:
                  # We're not at a segment boundary.
                  cur_segment.append(e)
          else:
              if cur_step + e.event_value <= steps_per_segment:
                  # If it's a time shift, but we're still within the current segment,
                  # just append to current segment.
                  cur_segment.append(e)
                  cur_step += e.event_value
              else:
                  # If it's a time shift that goes beyond the current segment, possibly
                  # split the time shift into two events and create a new segment.
                  cur_segment_steps = steps_per_segment - cur_step
                  if cur_segment_steps > 0:
                      cur_segment.append(
                          performance_lib.PerformanceEvent(
                              event_type=performance_lib.PerformanceEvent.TIME_SHIFT,
                              event_value=cur_segment_steps,
                          )
                      )
  
                  segments.append(cur_segment)
                  cur_segment = new_performance_fn(
                      quantized_sequence=None,
                      start_step=len(segments) * steps_per_segment,
                  )
                  cur_step = 0
  
                  new_segment_steps = e.event_value - cur_segment_steps
                  if new_segment_steps > 0:
                      cur_segment.append(
                          performance_lib.PerformanceEvent(
                              event_type=performance_lib.PerformanceEvent.TIME_SHIFT,
                              event_value=new_segment_steps,
                          )
                      )
                      cur_step += new_segment_steps
  
      segments.append(cur_segment)
  
      # There may be a final segment with zero duration. If so, remove it.
      if segments and segments[-1].num_steps == 0:
          segments = segments[:-1]
  
      if clip_tied_notes:
          # Convert each segment to NoteSequence and back to remove notes that are
          # held across segment boundaries.
          for i in range(len(segments)):
              sequence = segments[i].to_sequence()
              if isinstance(
                  segments[i], performance_lib.MetricPerformance
              ):
                  # Performance is quantized relative to meter.
                  quantized_sequence = note_seq.quantize_note_sequence(
                      sequence,
                      steps_per_quarter=segments[i].steps_per_quarter,
                  )
              else:
                  # Performance is quantized with absolute timing.
                  quantized_sequence = (
                      note_seq.quantize_note_sequence_absolute(
                          sequence,
                          steps_per_second=segments[i].steps_per_second,
                      )
                  )
              segments[i] = new_performance_fn(
                  quantized_sequence=quantized_sequence,
                  start_step=segments[i].start_step,
              )
              segments[i].set_length(steps_per_segment)
  
      return segments
  
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 1 for calling a global function with example usage: split_performance(performance, steps_per_segment, new_performance_fn, clip_tied_notes) and returns: segments