(note_sequence, samples, sample_rate, min_length,
                      max_length)
return split_points
Returns times at which there are no notes.

  The general strategy employed is to first check if there are places in the
  sustained pianoroll where no notes are active within the max_length window;
  if so the middle of the last gap is chosen as the split point.

  If not, then it checks if there are places in the pianoroll without sustain
  where no notes are active and then finds last zero crossing of the wav file
  and chooses that as the split point.

  If neither of those is true, then it chooses the last zero crossing within
  the max_length window as the split point.

  If there are no zero crossings in the entire window, then it basically gives
  up and advances time forward by max_length.

  Args:
      note_sequence: The NoteSequence to split.
      samples: The audio file as samples.
      sample_rate: The sample rate (samples/second) of the audio file.
      min_length: Minimum number of seconds in a split.
      max_length: Maximum number of seconds in a split.

  Returns:
      A list of split points in seconds from the beginning of the file.
Returns times at which there are no notes.
Returns times at which there are no notes .
def find_split_points(note_sequence, samples, sample_rate, min_length,
                      max_length):
  """Returns times at which there are no notes.

  The general strategy employed is to first check if there are places in the
  sustained pianoroll where no notes are active within the max_length window;
  if so the middle of the last gap is chosen as the split point.

  If not, then it checks if there are places in the pianoroll without sustain
  where no notes are active and then finds last zero crossing of the wav file
  and chooses that as the split point.

  If neither of those is true, then it chooses the last zero crossing within
  the max_length window as the split point.

  If there are no zero crossings in the entire window, then it basically gives
  up and advances time forward by max_length.

  Args:
      note_sequence: The NoteSequence to split.
      samples: The audio file as samples.
      sample_rate: The sample rate (samples/second) of the audio file.
      min_length: Minimum number of seconds in a split.
      max_length: Maximum number of seconds in a split.

  Returns:
      A list of split points in seconds from the beginning of the file.
  """

  if not note_sequence.notes:
    return []

  end_time = note_sequence.total_time

  note_sequence_sustain = sequences_lib.apply_sustain_control_changes(
      note_sequence)

  ranges_nosustain = find_inactive_ranges(note_sequence)
  ranges_sustain = find_inactive_ranges(note_sequence_sustain)

  nosustain_starts = [x[0] for x in ranges_nosustain]
  sustain_starts = [x[0] for x in ranges_sustain]

  nosustain_ends = [x[1] for x in ranges_nosustain]
  sustain_ends = [x[1] for x in ranges_sustain]

  split_points = [0.]

  while end_time - split_points[-1] > max_length:
    max_advance = split_points[-1] + max_length

    # check for interval in sustained sequence
    pos = bisect.bisect_right(sustain_ends, max_advance)
    if pos < len(sustain_starts) and max_advance > sustain_starts[pos]:
      split_points.append(max_advance)

    # if no interval, or we didn't fit, try the unmodified sequence
    elif pos == 0 or sustain_starts[pos - 1] <= split_points[-1] + min_length:
      # no splits available, use non sustain notes and find close zero crossing
      pos = bisect.bisect_right(nosustain_ends, max_advance)

      if pos < len(nosustain_starts) and max_advance > nosustain_starts[pos]:
        # we fit, great, try to split at a zero crossing
        zxc_start = nosustain_starts[pos]
        zxc_end = max_advance
        last_zero_xing = _last_zero_crossing(
            samples, int(math.floor(zxc_start * sample_rate)),
            int(math.ceil(zxc_end * sample_rate)))
        if last_zero_xing:
          last_zero_xing = float(last_zero_xing) / sample_rate
          split_points.append(last_zero_xing)
        else:
          # give up and just return where there are at least no notes
          split_points.append(max_advance)

      else:
        # there are no good places to cut, so just pick the last zero crossing
        # check the entire valid range for zero crossings
        start_sample = int(
            math.ceil((split_points[-1] + min_length) * sample_rate)) + 1
        end_sample = start_sample + (max_length - min_length) * sample_rate
        last_zero_xing = _last_zero_crossing(samples, start_sample, end_sample)

        if last_zero_xing:
          last_zero_xing = float(last_zero_xing) / sample_rate
          split_points.append(last_zero_xing)
        else:
          # give up and advance by max amount
          split_points.append(max_advance)
    else:
      # only advance as far as max_length
      new_time = min(np.mean(ranges_sustain[pos - 1]), max_advance)
      split_points.append(new_time)

  if split_points[-1] != end_time:
    split_points.append(end_time)

  # ensure that we've generated a valid sequence of splits
  for prev, curr in zip(split_points[:-1], split_points[1:]):
    assert curr > prev
    assert curr - prev <= max_length + 1e-8
    if curr < end_time:
      assert curr - prev >= min_length - 1e-8
  assert end_time - split_points[-1] < max_length

  return split_points
def find_split_points ( note_sequence , samples , sample_rate , min_length , max_length ) : if not note_sequence . notes : return [ ] end_time = note_sequence . total_time note_sequence_sustain = sequences_lib . apply_sustain_control_changes ( note_sequence ) ranges_nosustain = find_inactive_ranges ( note_sequence ) ranges_sustain = find_inactive_ranges ( note_sequence_sustain ) nosustain_starts = [ x [ 0 ] for x in ranges_nosustain ] sustain_starts = [ x [ 0 ] for x in ranges_sustain ] nosustain_ends = [ x [ 1 ] for x in ranges_nosustain ] sustain_ends = [ x [ 1 ] for x in ranges_sustain ] split_points = [ 0. ] while end_time - split_points [ - 1 ] > max_length : max_advance = split_points [ - 1 ] + max_length # check for interval in sustained sequence pos = bisect . bisect_right ( sustain_ends , max_advance ) if pos < len ( sustain_starts ) and max_advance > sustain_starts [ pos ] : split_points . append ( max_advance ) # if no interval, or we didn't fit, try the unmodified sequence elif pos == 0 or sustain_starts [ pos - 1 ] <= split_points [ - 1 ] + min_length : # no splits available, use non sustain notes and find close zero crossing pos = bisect . bisect_right ( nosustain_ends , max_advance ) if pos < len ( nosustain_starts ) and max_advance > nosustain_starts [ pos ] : # we fit, great, try to split at a zero crossing zxc_start = nosustain_starts [ pos ] zxc_end = max_advance last_zero_xing = _last_zero_crossing ( samples , int ( math . floor ( zxc_start * sample_rate ) ) , int ( math . ceil ( zxc_end * sample_rate ) ) ) if last_zero_xing : last_zero_xing = float ( last_zero_xing ) / sample_rate split_points . append ( last_zero_xing ) else : # give up and just return where there are at least no notes split_points . append ( max_advance ) else : # there are no good places to cut, so just pick the last zero crossing # check the entire valid range for zero crossings start_sample = int ( math . ceil ( ( split_points [ - 1 ] + min_length ) * sample_rate ) ) + 1 end_sample = start_sample + ( max_length - min_length ) * sample_rate last_zero_xing = _last_zero_crossing ( samples , start_sample , end_sample ) if last_zero_xing : last_zero_xing = float ( last_zero_xing ) / sample_rate split_points . append ( last_zero_xing ) else : # give up and advance by max amount split_points . append ( max_advance ) else : # only advance as far as max_length new_time = min ( np . mean ( ranges_sustain [ pos - 1 ] ) , max_advance ) split_points . append ( new_time ) if split_points [ - 1 ] != end_time : split_points . append ( end_time ) # ensure that we've generated a valid sequence of splits for prev , curr in zip ( split_points [ : - 1 ] , split_points [ 1 : ] ) : assert curr > prev assert curr - prev <= max_length + 1e-8 if curr < end_time : assert curr - prev >= min_length - 1e-8 assert end_time - split_points [ - 1 ] < max_length return split_points