def randomWalkBeginningEndDegrees(start, end, n, any_octave = False): if n == 1: return [start] elif n == 2: return [start, end] elif n == 3: return [start, random.choice([start - 1] + range(start + 1, end) + [end + 1]), end] else: while (True): degs = [start] for i in range(1, n - 2): if degs[-1] < 0: degs.append(degs[-1] + ph.probDictToChoice(sc.horizontalmarkov)) elif degs[-1] > 14: degs.append(degs[-1] + ph.probDictToChoice(sc.horizontalmarkov)*-1) else: degs.append(degs[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,-1,-1,1])) if any_octave: end = getClosestPCDegree(degs[-1], end) if end == degs[-1]: second_to_last = random.choice([end - 2, end - 1, end + 1, end + 2]) else: second_to_last = random.randint(degs[-1] + 1, end) if end > degs[-1] else random.randint(end + 1, degs[-1]) degs.append(second_to_last) degs.append(end) if abs(degs[-1] - degs[-2]) < 3: break return degs
def randomDuration(length = 2.0, avoid = [], triplets = False): if length == 2.0: new_prob_dict = {} for val, prob in two_prob_dict.items(): if val not in avoid and not (triplets == False and 0.33333333 in strToRhy(val)): new_prob_dict[val] = prob return strToRhy(ph.probDictToChoice(new_prob_dict))
def genCell(length, prev_note = 0, first_note = None, chord = [], durs = [], cell_type = None, key=0): if cell_type == None: cell_type = ph.probDictToChoice(p_cell_dict) if cell_type == 'scalewise': return genScalewiseCell(length, prev_note, first_note, chord, durs, key) elif cell_type == 'chordal': return genChordalCell(length, prev_note, first_note, chord, durs, key) else: return genUsualCell(length, prev_note, first_note, chord, durs, key)
def randomDuration(length = 2.0, same = '', avoid = []): if length == 2.0: new_prob_dict = {} for val, prob in two_prob_dict.items(): if val not in avoid: new_prob_dict[val] = prob return strToRhy(ph.probDictToChoice(new_prob_dict)) elif length == 4.0: if same == '': same = random.choice([True, False]) if same: a = notHalfNote() return fh.concat([a,a]) else: if random.uniform(0,1) < 0.1 and '3.0 1.0' not in avoid and '3.0 0.5 0.5' not in avoid and '1.0 2.0 1.0' not in avoid: a = strToRhy(ph.probDictToChoice({'3.0 1.0':0.2, '3.0 0.5 0.5':0.4, '1.0 2.0 1.0': 0.6})) return a else: return randomDuration(2.0, avoid=avoid) + randomDuration(2.0, avoid=avoid)
def doubleSmooth(pitches, durs, leading = True): new = [pitches[0]] new_durs = [durs[0]] for i in range(1, len(pitches)): dur = durs[i] if i < len(durs) else 1.0 new_durs.append(dur) if pitches[i] == new[-1]: #remove doubles new.append(new[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])) elif pitches[i] < -3: #choose a new note if going lower than -3 if new[-1] > 0: new.append(new[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1]) ) else: new.append(new[-1] + 2) elif pitches[i] > 14: #choose a new note if going higher than 14 if new[-1] < 12: new.append(new[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1]) ) else: new.append(new[-1] - 2) elif (new[-1] - pitches[i]) >= 4 or (new[-1] - pitches[i]) <= -4: #choose a new note if the gap between notes is too large closest = sc.closestNoteDegreeInTriad(new[-1], 0) if closest < -2: new.append(closest + random.choice([1,2,2,3])) elif new[-1] == closest: new.append(closest + random.choice([-2,-1,-1,1,1,2])) else: new.append(closest) else: new.append(pitches[i]) if dur > 1 and new[-1] % 7 not in [0,2,4]: #choose a new note if it is not in the chord triad closest = sc.closestNoteDegreeInTriad(new[-1], 0) new[-1] = (closest) if new[-1] < -3: new[-1] = random.choice(range(-3, 0)) elif new[-1] > 14: new[-1] = random.choice(range(12,14)) #make leading notes resolve to tonic if leading: for i in range(0, len(new) - 1): if new[i] % 12 == 11: if random.uniform(0,1) < 0.7: new[i + 1] = new[i] + 1 return (new, new_durs)
def genHPhrase( prev_note=0, harmony=[[0, 2, 4], [0, 2, 4], [4, 6, 8], [0, 2, 4]], prob_transform_dict={"transformed": 0.6, "new": 0.4}, ): first_motif = genMotif(prev_note, harmony[:2]) next_motif_type = ph.probDictToChoice(prob_transform_dict) if next_motif_type == "new": second_motif = genMotif(first_motif.pits[-1], harmony[2:]) else: second_motif = transformChunk(first_motif, first_motif.pits[-1], harmony[2:]) return Chunk([first_motif, second_motif])
def genMotif(beats): durations = rhy.randomDuration(beats) tot_durs = [sum(durations[:i]) for i in range(0, len(durations))] pitches = [random.choice([0,0,2,2,4,4,1,-1,-2])] for i in range(1, len(durations)): if tot_durs[i] == 2.0: probOnBeat = {-4: 1, -2:4, 0: 2, 2:4, 4:1} #try to make the on beat a member of the major triad probOnBeat = dict([(k,v) for k,v in probOnBeat.items() if abs(pitches[-1] - k) <= 4]) if len(probOnBeat) == 0: probOnBeat = {pitches[-1] - 1:1, pitches[-1] + 1:1} pitches.append(pitches[0] + ph.probDictToChoice(probOnBeat)) else: #if pitches are too high/low, move towards the center if pitches[-1] > 12: pitches.append(pitches[-1] - ph.probDictToChoice(sc.horizontalmarkov)) elif pitches[-1] < 0: pitches.append(pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov)) #otherwise, move either up or down else: pitches.append(pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov) * random.choice([1,-1])) return Motif(pitches, durations)
def genMotif(prev_note=0, harmony=[[0, 2, 4], [4, 6, 8]]): first_chord = harmony[0] second_chord = harmony[1] # gen first cell cell1 = gc.getCell(2, prev_note, None, first_chord, []) # either gen or transform second cell next_cell_type = ph.probDictToChoice({"transformed": 0.7, "new": 0.3}) if len(set(cell1.durs)) < 2 and len(cell1.durs) > 1: next_cell_type = "new" if next_cell_type == "new": cell2 = gc.getCell(2, cell1.pits[-1], None, second_chord, []) else: cell2 = transformChunk(cell1, cell1.pits[-1], [second_chord]) return Chunk([cell1, cell2])
def randomDuration(length): if length == 1: return strToRhy(ph.probDictToChoice(prob_dict)) elif length == 2: return strToRhy(ph.probDictToChoice(two_prob_dict)) elif length == 3: return strToRhy(ph.probDictToChoice(two_prob_dict)) + strToRhy(ph.probDictToChoice(prob_dict)) elif length == 4: return strToRhy(ph.probDictToChoice(two_prob_dict)) + strToRhy(ph.probDictToChoice(two_prob_dict)) print('issue!')
def randomDuration(length, triplets = False): if length == 1: return strToRhy(ph.probDictToChoice(prob_dict)) elif length == 2: pdict = two_prob_dict_triplets if triplets else two_prob_dict return strToRhy(ph.probDictToChoice(pdict)) elif length == 3: return strToRhy(ph.probDictToChoice(two_prob_dict) + strToRhy(ph.probDictToChoice(prob_dict))) elif length == 4: return strToRhy(ph.probDictToChoice(two_prob_dict) + strToRhy(ph.probDictToChoice(two_prob_dict))) else: print('error - duration not supported yet')
def genChordalCell(length, prev_note = 0, first_note = None, cord = [], durs = [], key = 0): pitches = [] def strToNum(string): return [int(i) for i in string.split()] if cord == []: cord = strToNum(ph.probDictToChoice({'0 2 4':0.5, '4 6 8':0.3, '3 5 7':0.2})) if durs == []: durs = rhy.randomDuration(length) if first_note != None: pitches = [first_note] elif prev_note % 7 == 6 and cord == [0,2,4]: pitches = [prev_note + 1] elif prev_note % 7 == 3 and cord == [0,2,4]: pitches = [prev_note - 1] else: pitches = [sc.closestNoteDegreeInChord(prev_note, cord, 1, False)] for i in range(1, len(durs)): pitches.append(randomChordNote(pitches[-1], cord, durs[i] == 0.25)) return Chunk(pits=pitches, durs=durs, chord=cord, key = key)
def closenessDistribution(chord, prev_note, dist): if chord == []: return prev_note + random.choice([-1,-1,1,1,-2,2]) if dist == 'close': far_dict = {0:0.6, 1:0.4} elif dist == 'med': far_dict = {0:0.4, 1:0.35, 2:0.2, 3:0.05} n = ph.probDictToChoice((far_dict)) #get note in chord that is nth away from prev_note all_notes_in_chord = fh.concat([[root_note + octave for root_note in chord] for octave in range(-21,21,7)]) #get distances between notes and prev_note notes_distances = map(lambda i: (i, abs(i - prev_note)), all_notes_in_chord) #sort notes_distances by the distance notes_distances = sorted(notes_distances, key = itemgetter(1)) return notes_distances[n][0]
def genUsualCell(length, prev_note = 0, first_note = None, cord = [], durs = [], key=0): pitches = [] def strToNum(string): return [int(i) for i in string.split()] if cord == []: cord = strToNum(ph.probDictToChoice({'0 2 4':0.5, '4 6 8':0.3, '3 5 7':0.2})) if durs == []: durs = rhy.randomDuration(length) if first_note != None: pitches = [first_note] elif prev_note % 7 == 6 and cord == [0,2,4]: pitches = [prev_note + 1] elif prev_note % 7 == 3 and cord == [0,2,4]: pitches = [prev_note - 1] else: pitches = [sc.closestNoteDegreeInChord(prev_note, cord, 1, False)] if durs[0] < 0: pitches.append(sc.closestNoteDegreeInChord(prev_note, cord, 1, False)) i_continue = 2 else: i_continue = 1 tot_durs = [sum(durs[:i]) for i in range(0, len(durs))] for i in range(i_continue, len(durs)): if tot_durs[i] % 1.0 == 0: if prev_note not in cord: pitches.append(sc.closestNoteDegreeInChord(prev_note, cord, True)) else: pitches.append(randomChordNote(prev_note, cord)) elif random.uniform(0,1) < 0.5: if prev_note not in cord: pitches.append(sc.closestNoteDegreeInChord(prev_note, cord, True)) else: pitches.append(randomChordNote(prev_note, cord)) else: pitches.append(randomNextDegree(prev_note, 1)) prev_note = pitches[-1] return_val = Chunk(pitches, durs, chord=cord, key=key) if pref.goodCell(return_val) or random.uniform(0,1) < 0.05: return return_val else: return genUsualCell(length, prev_note, first_note, cord, durs)
def randomMeasure(): one_prob_dict = {'1.0': 0.4, '0.5 0.5': 0.53, '0.75 0.25':0.02, '0.5 0.25 0.25':0.02, '0.25 0.25 0.25 0.25':0.02} two_prob_dict = {} prob_dict_keys = list(prob_dict.keys()) for i in range(0, len(prob_dict_keys)): two_prob_dict[prob_dict_keys[i] + ' ' + prob_dict_keys[i]] = 0.5*prob_dict[prob_dict_keys[i]] for j in range(i + 1, len(prob_dict_keys)): two_prob_dict[prob_dict_keys[i] + ' ' + prob_dict_keys[j]] = ph.geometricMean([prob_dict[prob_dict_keys[i]], prob_dict[prob_dict_keys[j]]]) two_prob_dict[prob_dict_keys[j] + ' ' + prob_dict_keys[i]] = ph.geometricMean([prob_dict[prob_dict_keys[i]], prob_dict[prob_dict_keys[j]]]) two_prob_dict['1.5 0.5'] = 0.5 two_prob_dict['1.5 0.25 0.25'] = 0.1 two_prob_dict['2.0'] = 0.5 four_prob_dict = {} two_prob_dict_keys = list(two_prob_dict.keys()) for i in range(0, len(prob_dict_keys)): four_prob_dict[two_prob_dict_keys[i] + ' ' + two_prob_dict_keys[i]] = 3*two_prob_dict[two_prob_dict_keys[i]] for j in range(i + 1, len(prob_dict_keys)): four_prob_dict[two_prob_dict_keys[i] + ' ' + two_prob_dict_keys[j]] = ph.geometricMean([two_prob_dict[two_prob_dict_keys[i]], two_prob_dict[two_prob_dict_keys[j]]]) four_prob_dict[two_prob_dict_keys[j] + ' ' + two_prob_dict_keys[i]] = ph.geometricMean([two_prob_dict[two_prob_dict_keys[i]], two_prob_dict[two_prob_dict_keys[j]]]) for key in prob_dict.keys(): four_prob_dict['3.0 ' + key] = 0.2 + prob_dict[key] return strToRhy(ph.probDictToChoice(four_prob_dict))
def randomNextDegree(prev_note = 0): interval = ph.probDictToChoice(sc.horizontalmarkov) * random.choice([-1,1]) return prev_note + interval
def alterMotif(motif, p_alter_pitch = 0.2, p_alter_rhythm = 0.2): new_durs = [] new_pitches = [] for i in range(0, len(motif.l1d)): beat = motif.l1d[i] beat_pitches = motif.l1p[i] ran1 = random.uniform(0,1) #used to determine rhythm changes ran2 = random.uniform(0,1) #used to determine pitch changes tmp_dur = [] if beat == [1.0]: #either keep as quarter note, or transform to eighths or sixteenths if ran1 < p_alter_rhythm/2: tmp_dur = [0.25,0.25,0.25,0.25] tmp_pitches = [beat_pitches[0]] for i in range(0,3): tmp_pitches.append(tmp_pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])) elif ran1 < p_alter_rhythm: tmp_dur = [0.5,0.5] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] tmp_pitches.append(tmp_pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])) else: tmp_pitches = [beat_pitches[0], beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] else: tmp_dur = [1.0] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] else: tmp_pitches = beat_pitches elif beat == [0.5,0.5]: #either keep as eighths, or transform to sixteenths or quarter if ran1 < p_alter_rhythm/2: tmp_dur = [0.25,0.25,0.25,0.25] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] for i in range(0,3): tmp_pitches.append(tmp_pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])) else: tmp_pitches = [beat_pitches[0], beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1]), beat_pitches[1], beat_pitches[1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] elif ran1 < p_alter_rhythm: tmp_dur = [1.0] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] else: tmp_pitches = [beat_pitches[0]] else: tmp_dur = [0.5,0.5] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1]), beat_pitches[1]] else: tmp_pitches = beat_pitches elif beat == [0.25,0.25,0.25,0.25]: #either keep as sixteenths, or transform to eighths or quarter if ran1 < p_alter_rhythm/2: tmp_dur = [0.5,0.5] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] tmp_pitches.append(tmp_pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])) else: tmp_pitches = [beat_pitches[0], beat_pitches[2]] elif ran1 < p_alter_rhythm: tmp_dur = [1.0] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] else: tmp_pitches = [beat_pitches[0]] else: tmp_dur = [0.25,0.25,0.25,0.25] if ran2 < p_alter_pitch: tmp_pitches = [beat_pitches[0] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])] for i in range(0,3): tmp_pitches.append(tmp_pitches[-1] + ph.probDictToChoice(sc.horizontalmarkov)*random.choice([-1,1])) else: tmp_pitches = beat_pitches else: #if the beat is neither all eighth notes nor sixteenth notes nor a quarter, keep the rhythm constant tmp_dur = beat tmp_pitches = [] for pitch in beat_pitches: ran2 = random.uniform(0,1) if ran2 < p_alter_pitch: tmp_pitches.append(pitch + ph.probDictToChoice(sc.horizontalmarkov)) else: tmp_pitches.append(pitch) new_durs.extend(tmp_dur) new_pitches.extend(tmp_pitches) return Motif(new_pitches, new_durs)
def genProcessCell(prev_note = 0, first_note = None, chord = [0,2,4], key = 0): if first_note == None: pitches = [sc.closestNoteDegreeInChord(prev_note, chord=chord)] durs = rhy.strToRhy(ph.probDictToChoice({'0.5 0.25 0.25':0.1, '0.25 0.25 0.5':0.1, '0.5 0.5':0.5, '0.25 0.25 0.25 0.25':0.1}))
def randomHalfQuarterEighths(): half_prob_dict = {'1.0 0.5 0.5':0.3, '00.5 0.5 1': 0.1, '0.5 0.5 0.5 0.5':0.25, '1.0 1.0': 0.15} return strToRhy(ph.probDictToChoice(half_prob_dict))
def randomHalfRhythm(short = False): if short: return random.choice([[1.5, 0.5], [1.5, 0.25, 0.25], [1.0, 1.0], [1.0,0.5,0.5], [0.5,0.5,1.0]]) else: return strToRhy(ph.probDictToChoice(two_prob_dict))
motif_patterns.append(reused_pattern) phrs_motifs = ([motifs[i] for i in random.choice(prev_types)]) else: phrs_motifs = [motifs[which_to_start]] which_second = random.choice(range(0, len(motifs))) phrs_motifs.append(mlh.alterMotif(motifs[which_second], random.uniform(0,0.3), random.uniform(0,0.3))) #now, append third motif phrs_motifs.append(mlh.genMotif(4)) #append to list of motifs and motif patterns motifs.append(phrs_motifs[-1]) motif_patterns.append([which_to_start, which_second, len(motifs) - 1]) else: phrs_motifs = [mlh.genMotif(4), mlh.genMotif(4), mlh.genMotif(4)] motifs.extend(phrs_motifs) motif_patterns.append([len(motifs) - 3, len(motifs) - 2, len(motifs) - 1]) #then, divide into phrases phrase_functions_list = dict([(o[0], o[1]) for o in getmembers(ngp) if isfunction(o[1])]) #the probability dict containing names of functions phrase_functions_probs = dict( [ (o[0], probPhraseType(o[0])) for o in getmembers(ngp) if isfunction(o[1]) ]) phrase_type = phrase_functions_list[ph.probDictToChoice(phrase_functions_probs)] phrases.append(phrase_type(phrs_motifs)) phrases = [shiftMotifs(phrase) for phrase in phrases] p = fh.concat(phrases) degrees = fh.concat([i.l0p for i in p]) rhythms = fh.concat([i.l0d for i in p]) degrees, rhythms = smooth.smoothOut(degrees, rhythms) score = mh.listsDegreesToStream(degrees, rhythms, scale = scales["dorian"]) score.show()
def getChoice(item, rules): return rules[item.split("-")[0]][ph.probDictToChoice(rule_probs[item.split("-")[0]])]
def randomMeasure(): return strToRhy(ph.probDictToChoice(fourprobs))
def randomThreeProb(): two = strToRhy(ph.probDictToChoice(twoprobs)) two.extend(strToRhy(ph.probDictToChoice(oneprobs))) return two
def randomTwoProb(): return strToRhy(ph.probDictToChoice(twoprobs))
def randomOneProb(): return strToRhy(ph.probDictToChoice(oneprobs))
def probToRhys(string_dict): return strToRhy(ph.probDictToChoice(string_dict))