def goodCells(cells):
    if not all([len(i.pits) == len(i.durs) for i in cells]):
        return False
    pits = fh.concat([j.pits for j in cells])
    #no leaping from non-tone chord
    if not hm.inChord(cells[0].pits[-1], cells[0].chord) and abs(cells[0].pits[-1] - cells[1].pits[0]) > 1:
        return False
    pit_diffs = [abs(pits[i] - pits[i - 1]) for i in range(1, len(pits))]
    #no three in a row
    for i in range(2, len(pits)):
        if abs(pits[i] - pits[i - 1]) == 6:
            return False
        if pits[i] == pits[i - 1] and pits[i - 2] == pits[i]:
            return False
        if (pits[i] % 7) == 3 and (pits[i - 1] % 7) == 6 or  (pits[i] % 7) == 6 and (pits[i - 1] % 7) == 3:
            return False
    #no jumps bigger than 4
    if max(pit_diffs) > 4:
        return False
    #no notes lower than -3
    if min(pits) < -3:
        return False
    if max(pits) > 20:
        return False
    for i in range(1, len(cells)):
        if (cells[i - 1].pits[-1] % 7) == 3 and cells[i].chord == [0,2,4] and (cells[i].pits[0] % 7) != 2:
            return False
        if (cells[i - 1].pits[-1] % 7) == 6 and cells[i].chord == [0,2,4] and (cells[i].pits[0] % 7) != 0:
            return False
    if len(cells) > 1:
        if max(pits) - min(pits) < 4:
            return False
    return True
def genBass(main_passage, low = -4, high = 7):
    prev_note = 4
    main_cells = main_passage.cells
    bass_cells = []
    for main_cell in main_cells:
        if main_cell.chord == [] or main_cell.chord == None:
            bass_cells.append(gc.genBlankCell(2.0))
            prev_note = 4
        else:
            main_pits = main_cell.beat_pits
            pits = []
            pits.append(pth.getClosestPCDegree(prev_note, main_pits[0][0], low = low, high = high))


            if len(main_pits) == 2:
                if hm.inChord(main_pits[1][0], main_cell.chord):
                    pits.append(sc.closestNoteDegreeInChord(note=pits[-1], chord=main_cell.chord, same=False, low = low, high = high))
                    durs = [1.0,1.0]
                    bass_cells.append(Chunk(pits = pits, durs=durs, chord=main_cell.chord, key = main_cell.key))
                else:
                    durs = [2.0]
                    bass_cells.append(Chunk(pits = pits, durs = durs, chord=main_cell.chord, key = main_cell.key))
            else: #if it's a 1.5, 0.5 or 1.5, 0.25,0.25
                durs = [2.0]
                bass_cells.append(Chunk(pits = pits, durs = durs, chord=main_cell.chord, key = main_cell.key))
            prev_note = pits[-1]
    return bass_cells
def genAlbertiEighths(main_cells, leading_eighths = True):
    prev_note = 0
    cells = []
    for k in range(0, len(main_cells)): #loop through all cells
        main_cell = main_cells[k]
        if main_cell.chord == None or main_cell.chord == []:
            if leading_eighths == False: #if we are coming to a close
                new_pits = []
                for pit in main_cell.pits:
                    new_pits.append(pth.getClosestPCDegree(prev_note, pit, low = -5, high = 14))
                    prev_note = new_pits[-1]
                cells.append(Chunk(pits = new_pits, durs = main_cell.durs, key=main_cell.key))
            else: #if we want eighths
                main_pitches = main_cell.pits
                main_durs = main_cell.durs
                pits = []
                tot_durs = [sum(main_durs[:i]) for i in range(0, len(main_durs))]
                eighths = []
                for i in range(0, 4):
                    found = False
                    for j in range(0, len(tot_durs)):
                        if tot_durs[j] == i/2.0:
                            eighths.append(main_pitches[j])
                            found = True
                    if found == False:
                        eighths.append(None)
                if eighths[1] == None and eighths[2] == None and eighths[3] == None:
                    if main_pitches[0] % 7 == 1 or main_pitches[0] % 7 == 6: #if we're dealing with a dominant chord
                        first_note = (pth.getClosestPC(prev_note, 4))
                    else:
                        first_note = (pth.getClosestPC(prev_note, 0))
                    pat = random.choice([[0,-1,-2,-3], [0,-1,-2,-1]])
                    pits = [first_note + i for i in pat]
                else:
                    if hm.matches(eighths[0], 0):
                        pits.append(pth.getClosestPCDegree(prev_note, 0))
                    elif hm.matches(eighths[0], 4):
                        pits.append(pth.getClosestPCDegree(prev_note, 7))
                    else:
                        print('error')
                    prev_note = pits[-1]
                    for note in eighths[1:]: #run through all of the possibilities of the notes
                        if hm.inChord(note, [0,2,4]):
                            pits.append(sc.closestNoteDegreeInChord(prev_note, [0,2,4], same=False))
                        elif hm.inChord(note, [4,6,8]):
                            pits.append(sc.closestNoteDegreeInChord(prev_note, [4,8], same=False))
                        elif note == None:
                            pits.append(prev_note + random.choice([-1,1]))
                        else:
                            pits.append(pth.getClosestPCDegree(prev_note, note))
                            prev_note = pits[-1]
                cells.append(Chunk(pits=pits, durs=[0.5,0.5,0.5,0.5], key = main_cell.key))
        else: #if there is a chord
            inversion = False
            chord = main_cell.chord
            if chord == [1,3,5] or chord == [-2,0,2] or chord == [5,7,9]:
                inversion = True
            if k > 0:
                if main_cells[k - 1].chord == [0,2,4] and chord == [0,2,4]:
                    inversion = True
            '''if diff(main_cell.beat_pits[0], chord[1] == octave and diff(cells[-1].pits[-1], main_cells[k].beat_pits[0] == octave:
                inversion = False
            '''
            eighths = getAlbertiEighths(chord, main_cell.pits, main_cell.durs, inversion=inversion)
            #if isDiminished(eighths[0],cells[-1].pits[-1]:
            #   choose different end for cells[-1]
            closest_eighths = []
            for i in range(0, len(eighths)):
                closest_eighths.append(pth.getClosestPC(prev_note, eighths[i]))
                prev_note = closest_eighths[-1]
            cells.append(Chunk(pits = closest_eighths, durs = [0.5,0.5,0.5,0.5], chord=chord, key=main_cell.key))
    return cells
示例#4
0
def goodCells(cells, melody = True):
    for cell in cells:
        if len(cell.pits) != len(cell.durs):
            return False

    if not all([len(i.pits) == len(i.durs) for i in cells]):
        return False
    pits = fh.concat([j.pits for j in cells])
    durs = fh.concat([j.durs for j in cells])
    beat_pits = fh.concat([j.beat_pits for j in cells])
    beat_durs = fh.concat([j.beat_durs for j in cells])
    #no more than 4 half notes
    if durs.count(2.0) > 4:
        return False

    #no leaping from non-tone chord
    if not hm.inChord(cells[0].pits[-1], cells[0].chord) and abs(cells[0].pits[-1] - cells[1].pits[0]) > 1:
        return False
    pit_diffs = [abs(pits[i] - pits[i - 1]) for i in range(1, len(pits))]
    for i in range(1, len(pits)):
        #no jumps of a seventh
        if abs(pits[i] - pits[i - 1]) == 6:
            return False
        #no tritones
        if (pits[i] % 7) == 3 and (pits[i - 1] % 7) == 6 or  (pits[i] % 7) == 6 and (pits[i - 1] % 7) == 3:
            return False
    #no three in a row
    for i in range(2, len(pits)):
        if pits[i] == pits[i - 1] and pits[i - 2] == pits[i]:
            return False
    #no jumps more than an octave
    if max(pit_diffs) > 7:
        return False
    #no two arpeggiated cells
    for i in range(0, len(beat_pits) - 3):
        if max(beat_pits[i]) - min(beat_pits[i]) > 4:
            if max(beat_pits[i + 3]) - min(beat_pits[i + 3]) > 4 or max(beat_pits[i + 1]) - min(beat_pits[i + 1]) > 4 or max(beat_pits[i + 2]) - min(beat_pits[i + 2]) > 4:
                return False
    #no more than 3 half notes
    for i in range(0, len(durs) - 1):
        if durs[i] == 2.0 and durs[i + 1] == 2.0:
            return False
    #no more than 8 quarter notes
    for i in range(0, len(durs) - 9):
        if durs[i] == 1.0 and durs[i + 1] == 1.0 and durs[i + 2] == 1.0 and durs[i + 3] == 1.0 and durs[i + 4] == 1.0 and durs[i + 5] == 1.0 and durs[i+6] == 1.0 and durs[i + 7] == 1.0 and durs[i +8] == 1.0:
            return False
    #no notes lower than -3
    if min(pits) < -3:
        return False
    if max(pits) > 20:
        return False
    for i in range(1, len(cells)):
        if (cells[i - 1].pits[-1] % 7) == 3 and cells[i].chord == [0,2,4] and (cells[i].pits[0] % 7) != 2:
            return False
        if (cells[i - 1].pits[-1] % 7) == 6 and cells[i].chord == [0,2,4] and (cells[i].pits[0] % 7) != 0:
            return False
    if len(cells) > 1:
        if max(pits) - min(pits) < 4:
            return False
    #no doubles of sixteenth notes
    for i in range(1, len(pits)):
        if pits[i] == pits[i - 1] and (durs[i] == 0.25 or durs[i - 1] == 0.25):
            return False
    if melody:
        #no annoying 16ths
        for i in range(0, len(pits) - 3):
            if durs[i] == 0.25 and durs[i + 1] == 0.25 and durs[i + 2] == 0.25 and durs[i + 3] == 0.25:
                if pits[i] == pits[i + 2] and pits[i + 1] == pits[i + 3]:
                    return False
        #no more than 8 eighth notes
        for i in range(0, len(beat_durs) - 3):
            if beat_durs[i] == [0.5,0.5] and beat_durs[i + 1] == [0.5,0.5] and beat_durs[i+2] == [0.5,0.5] and beat_durs[i + 3] == [0.5,0.5]:
                return False
    #no ending on leading tone
    for beat_pit in beat_pits:
        if beat_pit[-1] % 7 == 6:
            return False
    return True