def _separate_into_non_overlapping_voices(notes, max_overlap=1e-10):
    """
    Takes a list of PerformanceNotes and breaks it up into separate voices that don't overlap more than max_overlap

    :param notes: a list of PerformanceNotes
    :return: a list of voices, each of which is a non-overlapping list of PerformanceNotes
    """
    voices = []
    for note in notes:
        voice_to_add_to = None
        for voice in voices:
            if voice[-1].end_beat <= note.start_beat + max_overlap:
                voice_to_add_to = voice
                break
        if voice_to_add_to is None:
            voice_to_add_to = []
            voices.append(voice_to_add_to)
        voice_to_add_to.append(note)
    return voices
