def __init__(self, *nchromos, tempo=0, max_len=None, tempo_range=None):
        """
        >>> gene = NoteGene(1,1,1,1,1)
        >>> chromosome = NoteChromosome(gene)
        >>> song = GeneticSong(chromosome, max_len=3, tempo=8)
        >>> song2 = GeneticSong(chromosome)
        >>> song.mutation_chance
        0
        >>> song.crossover_chance
        0
        >>> song.score
        0
        >>> song.max_length
        3
        >>> song.tempo
        8
        """
        
        self._chromosome_dict = {nc.track_id:nc for nc in nchromos[:max_len]}
        
        self._max_length = max_len
        self.tempo_range = tempo_range
        self.tempo = tempo
        if tempo_range is not None:
            self.tempo = to_range(self.tempo, tempo_range)

        self.mutation_chance = 0
        self.crossover_chance = 0
        self.score = 0
        self.diversity = 0

        self._song_id = type(self)._song_count
        type(self)._song_count += 1
    def mutate(self, *delta_mask):
        """
        >>> gene1 = NoteGene(1,1,1,1,1)
        >>> gene2 = NoteGene(2,2,2,2,2)
        >>> gene3 = NoteGene(3,3,3,3,3)
        >>> gene4 = NoteGene(4,4,4,4,4)
        >>> gene5 = NoteGene(5,5,5,5,5)
        >>> gene6 = NoteGene(6,6,6,6,6)
        >>> gene7 = NoteGene(7,7,7,7,7)
        >>> gene8 = NoteGene(8,8,8,8,8)
        >>> nc1 = NoteChromosome(gene1, gene2, track_id = 1)
        >>> nc2 = NoteChromosome(gene3, gene4, track_id = 3)
        >>> nc3 = NoteChromosome(gene5, track_id=0)
        >>> nc4 = NoteChromosome(gene6, track_id=2)
        >>> nc5 = NoteChromosome(gene7, track_id=4)
        >>> nc6 = NoteChromosome(gene8, track_id=6)
        >>> song1 = GeneticSong(nc1, nc2)
        >>> song1.song_id = 1
        >>> song2 = GeneticSong(nc3, nc4, nc5, nc6)
        >>> song2.song_id = 19
        >>> song1.mutate(0,2,2,2,2,2,1,1,1,1,1,0,0,0,0,0,-1,-1,-1,-1,-1)
        >>> song1
        1
        0
        1
        None
        [3, 3, 3, 3, 3]
        [3, 3, 3, 3, 3]
        <BLANKLINE>
        3
        None
        [3, 3, 3, 3, 3]
        [3, 3, 3, 3, 3]
        >>> song2.song_id == 19
        True
        >>> song2.mutate(40,-2,-2,-2,-2,-2,-3,-3,-3,-3,-3,-4,-4,-4,-4,-4,-5,-5,-5,-5,-5)
        >>> song2
        19
        40
        0
        None
        [3, 3, 3, 3, 3]
        <BLANKLINE>
        2
        None
        [3, 3, 3, 3, 3]
        <BLANKLINE>
        4
        None
        [3, 3, 3, 3, 3]
        <BLANKLINE>
        6
        None
        [3, 3, 3, 3, 3]
        >>> song2.mutate(1,1,1)
        Traceback (most recent call last):
            ...
        ValueError: Expecting delta mask of size 21, got 3
        """
        if len(delta_mask) != (self.num_genes * 5 + 1):
            raise ValueError("Expecting delta mask of size {}, got {}"
                             .format(self.num_genes * 5 + 1, len(delta_mask)))
        self.tempo += delta_mask[0]
        if self.tempo_range is not None:
            self.tempo = to_range(self.tempo, self.tempo_range)

        start_index = 1
        for nc in self._chromosome_dict.values():
            end_index = to_gene_index(len(nc)) + start_index
            nc.mutate(*delta_mask[start_index:end_index])
            start_index = end_index