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
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