예제 #1
0
    def __init__(self, pits = [], durs = [], chord = [], sub_chunks = None, key = 0, name='', scale = [0,2,4,5,7,9,11], dynamics = 'mf'):
        self.sub_chunks = sub_chunks
        self.name = name
        self.chord = chord
        #find depth
        if sub_chunks == None or sub_chunks == []:
            self.depth = 0
        else:
            self.depth = sub_chunks[0].depth

        self.key = key
        self.setKey(key)
        self.scale = scale
        #find pits/durs
        if pits == [] and self.depth > 0:
            pits = fh.concat([i.pits for i in self.cells])
            durs = fh.concat([i.durs for i in self.cells])
        self.pits = pits
        self.durs = durs

        #get ctype - basically only useful for cells
        self.ctype = self.getCtype(self.pits)

        #get beat rhythms and pitches
        self.beat_durs = []
        self.beat_pits = []
        self.resetBeatPitsAndDurs()
        self.length = []
        self.setLength()
예제 #2
0
    def __init__(self, pits = [], durs = [], ctype = -1, chord = [], sub_chunks = None, key = 0):
        self.sub_chunks = sub_chunks

        self.chord = chord
        #find depth
        self.depth = getMaxDepth(self)

        #get cells
        self.cells = getCells(self)

        self.key = key
        self.setKey(key)

        #find pits/durs
        if pits == [] and self.depth > 0:
            pits = fh.concat([i.pits for i in self.cells])
            durs = fh.concat([i.durs for i in self.cells])
        self.pits = pits
        self.durs = durs

        #get ctype - basically only useful for cells
        self.ctype = ctype

        #get beat rhythms and pitches
        self.beat_durs = []
        self.beat_pits = []
        self.resetBeatPitsAndDurs()
예제 #3
0
def fitsBasicIdeaPref(motifs):
    if sum([sum(i.durs) for i in motifs]) != 8.0:
        return False
    if motifs[0].pits == motifs[1].pits and motifs[0].durs == motifs[1].durs:
        return False
    if abs(motifs[0].pits[-1] - motifs[1].pits[0]) > 2:
        return False
    all_pits = fh.concat([i.pits for i in motifs])
    all_durs = fh.concat([i.durs for i in motifs])
    if len(set(all_pits)) < 3:
        return False
    if all_durs.count(2.0) > 2:
        return False
    return True
예제 #4
0
    def __init__(self, sub_chunks = None, cells = None, pits = [], durs = [], ctype = -1, name = '', names = {}, harm = None, structure = '', start_time = 0, depth = -1):
        self.sub_chunks = sub_chunks

        #find depth
        self.depth = getMaxDepth(self)
        self.max_depth = getMaxDepth(self)
        self.min_depth = getMinDepth(self)

        #set names of substructures and name of larger structure
        self.name = name
        self.names = names
        self.name = ''
        self.setName(name)

        #set harmony
        self.harm = harm

        #set structure
        if structure == '':
            self.structure = getStructure(self)
        else:
            self.structure = structure

        #create a dict of all of the different sub_chunks of all sizes
        self.all_chunks = getAllChunks(self)

        #get cells
        if cells == None:
            self.cells = getCells(self)
            #self.resetStructure()
        else:
            self.cells = cells


        #find pits/durs
        if pits == [] and self.depth > 0:
            pits = fh.concat([i.pits for i in self.cells.values()])
            durs = fh.concat([i.durs for i in self.cells.values()])
        self.pits = pits
        self.durs = durs

        #set ctype - basically only useful for cells
        self.ctype = ctype
        
        #set start time
        self.start_time = start_time
        #get beat rhythms and pitches
        self.beat_durs = []
        self.beat_pits = []
        self.resetBeatPitsAndDurs()
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
예제 #6
0
def closestNoteDegreeInChord(note, chord, same = True, up_down = 0):
    #print(note)
    #print(chord)
    allnotes = fh.concat([map(lambda j: i + j, chord) for i in range(-14,14,7)])
    tmp_allnotes = allnotes
    if up_down == 1:
        allnotes = filter(lambda i: i >= note, allnotes)
    elif up_down == -1:
         allnotes = filter(lambda i: i <= note, allnotes)
    if allnotes == [] and up_down == 1:
        allnotes = [tmp_allnotes[-1]]
    elif allnotes == [] and up_down == -1:
        allnotes = [tmp_allnotes[0]]
    dChords = map(lambda i: abs(note - i), allnotes)
    if same:
        minindex = min(enumerate(dChords), key=itemgetter(1))[0] 
        return allnotes[minindex]
    else:
        minnotsameindex = -1
        minnotsame = 1000
        for i in range(0, len(dChords)):
            if dChords[i] != 0 and dChords[i] < minnotsame:
                minnotsame = dChords[i]
                minnotsameindex = i
        return allnotes[minnotsameindex]
def showCells(cells,  degrees = True):
    pitches = []
    mpitches = ([i.pits for i in cells])
    for i in range(0, len(mpitches)):
        pitches.extend(mpitches[i][:len(cells[i].pits)])
    if degrees:
        pitches = sc.degreesToNotes(pitches)
    durs = fh.concat([i.durs for i in cells])
    score = listsToStream(pitches, durs)
    score.show()
def writeCells(cells,  fname, degrees = True):
    pitches = []
    mpitches = ([i.pits for i in cells])
    for i in range(0, len(mpitches)):
        pitches.extend(mpitches[i][:len(cells[i].pits)])
    if degrees:
        pitches = sc.degreesToNotes(pitches)
    durs = fh.concat([i.durs for i in cells])
    score = listsToStream(pitches, durs)
    score.write(fmt = 'musicxml', fp = fname)
def writePhrase(motifs,  fname, degrees = True):
    pitches = []
    mpitches = ([i.l0p for i in motifs])
    for i in range(0, len(mpitches)):
        pitches.extend(mpitches[i][:len(motifs[i].l0d)])
    if degrees:
        pitches = sc.degreesToNotes(pitches)
    durs = fh.concat([i.l0d for i in motifs])
    score = listsToStream(pitches, durs)
    score.write(fmt = 'musicxml', fp = fname)
def genBasicIdea(prev_note = random.choice([0,2,4,7]), chords = [[0,2,4], [4,6,8], [0,2,4], [0,2,4]], motif1 = None, cell1 = None):
    if motif1 == None:
        motif1 = gm.genMotif(prev_note = prev_note, chords = chords[:2], cell1 = cell1)
    motif1_durs = fh.concat([i.durs for i in motif1])
    if 2.0 in motif1_durs or motif1_durs == [1.0,1.0,1.0,1.0]:
        motif2 = gm.genMotif(prev_note=motif1[1].pits[-1], chords = chords[2:])
        return Chunk(sub_chunks = motif1 + motif2, ctype='bi')
    else:
        motif2 = tf.transformMotif(transform_motif=motif1, prev_cell=motif1[0], chords=chords[2:])
        return Chunk(sub_chunks = motif1 + motif2, ctype='bi')
def cellsToPart(cells, leading = True, octave = 5):
    durs = fh.concat([i.durs for i in cells])
    pitches = [i.pits for i in cells]
    #if there is a stretch where too low or high, fix
    midi_pitches = []
    for i in range(0, len(pitches)):
        midi_pitches.extend(sc.degreesToNotes(pitches[i], scale = scales["C major"], octave = octave))

    #pitches, durs = smooth.smoothOut(pitches, durs, leading)
    score = listsToPart(midi_pitches, durs)
    return score
예제 #12
0
def fitsMotifPref(cells):
    if sum([sum(i.durs) for i in cells]) != 4.0:
        return False
    if cells[0].pits == cells[1].pits and cells[0].durs == cells[1].durs:
        #print('in same')
        return False
    if abs(cells[0].pits[-1] - cells[1].pits[0]) > 2:
        #print('in too far apart')
        return False
    all_pits = fh.concat([i.pits for i in cells])
    all_durs = fh.concat([i.durs for i in cells])
    if len(all_pits) > 4 and len(set(all_pits)) < 3:
        #print('in not enough pits')
        return False
    if all_durs.count(1.0) > 3:
        #print('in too many 1.0')
        return False
    if all_durs.count(2.0) > 1:
        #print('in too many 2.0')
        return False
    return True
def getDefiningRhythm(cells):
    durs = fh.concat([i.durs for i in cells])
    if 0.75 in durs:
        if random.uniform(0,1) < 0.7:
            return [0.75,0.25,0.75,0.25]
        else:
            return [0.75,0.25,0.5,0.5]
    elif 1.5 in durs:
        return [1.5, 0.25, 0.25]
    elif 0.33333333 in durs:
        return [1.0,0.33333333,0.33333333,0.33333333]
    else:
        return randomDuration(2.0, triplets = False)
def pitchesDursToPart(pitches, durs, key_area, octave = 5):
    durs = fh.concat(durs)
    midi_pitches = []    
    for i in range(0, len(pitches)):
        skale = scales["G major"] if key_area[i] == 7 else scales["C major"]
        for j in range(0, len(pitches[i])):
            if type(pitches[i][j]) == tuple:
                cord = tuple(sc.degreeToNote(pitch, octave, scale = skale) for pitch in pitches[i][j])
                midi_pitches.append(cord)
            else:
                midi_pitches.append(sc.degreeToNote(pitches[i][j], octave = octave, scale = skale))
                    
    #pitches, durs = smooth.smoothOut(pitches, durs, leading)
    score = listsToPart(midi_pitches, durs)
    return score
예제 #15
0
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 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 motifsToPart(motifs, key_area, leading = True, octave = 5):
    durs = fh.concat([i.l0d for i in motifs])
    pitches = [i.l0p for i in motifs]
    """
    prev = pitches[0][0]
    tot_durs = [sum(durs[:i]) for i in range(0, len(durs)) ]
    n = 0

    for i in range(0, len(pitches)):
        if i > 0:
            prev = pitches[i - 1][-1]
        for j in range(1, len(pitches[i])):
            if tot_durs[n] % 1.0 != 0:
                if pitches[i] == prev:
                    pitches[i] += random.choice([1,-1]) 
            if pitches[i][j] > 14:
                if abs(prev - pitches[i][j] - 7) < 4:
                    pitches[i][j] = pitches[i][j] - 7
            elif pitches[i][j] < 0:
                if abs(prev - pitches[i][j] + 7) < 4:
                    pitches[i][j] = pitches[i][j] + 7
            #elif abs(pitches[i][j] - prev) > 4:
            #    pitches[i][j] = pth.getClosestPCDegree(pitches[i][j - 1], pitches[i][j])
            prev = pitches[i][j]
        n += 1 
    """
    #if there is a stretch where too low or high, fix
    midi_pitches = []    
    for i in range(0, len(pitches)):
        if key_area[i] == 0:
            midi_pitches.extend(sc.degreesToNotes(pitches[i], scale = scales["C major"], octave = octave))
        elif key_area[i] == 7:
            new_pitches = sc.degreesToNotes(pitches[i], scale = scales["G major"], octave = octave)
            midi_pitches.extend(new_pitches)

    #pitches, durs = smooth.smoothOut(pitches, durs, leading)
    score = listsToPart(midi_pitches, durs)
    return score
                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()
예제 #19
0
__author__ = 'halley'
import fitness
import functionalhelpers as fh
from music21 import *
from Note import *


candidates = []

for i in range(0,400):
    fitnesses_and_candidates = zip(map(fitness.fitness, candidates), candidates)
    fitnesses_and_candidates.sort(reverse=True, key=lambda i:i[0])
    bests = [i[1] for i in fitnesses_and_candidates[:50]]
    candidates = fh.concat(map(genVariations, bests))


best_score = stream.Score()
for note_ in bests[0]:
    n = note.Note(pitToPitch(note_.pit))
    n.quarterLength = note_.dur
    best_score.append(n)

best_score.show()

예제 #20
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
예제 #21
0
def closeChordNotes(chord, start_note, max_distance):
    allnotes = fh.concat([map(lambda j: i + j, chord) for i in range(-14,14,7)])
    allnotes = filter(lambda i: abs(i - start_note) <= max_distance, allnotes)
    allnotes.sort(key=lambda i: abs(start_note - i))
    return allnotes
예제 #22
0
def closestNoteDegreeInTriad(note, chord):
    allnotes = fh.concat([[i,i+2,i+4]  for i in range(-14,14,7)])
    dChords = map(lambda i: abs(note - i), allnotes)
    minindex = min(enumerate(dChords), key=itemgetter(1))[0] 
    return allnotes[minindex]
예제 #23
0
# -*- coding: utf-8 -*-
"""
Created on Mon Dec 29 10:18:04 2014

@author: halley
"""
import functionalhelpers as fh
import music21helpers as mh
from music21 import *
import scale as sc
from constants import *
import rhythms as rhy
import pitchhelpers as pth

#Etude 1: up and down the scale
durs = fh.concat([[0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1.0] for i in range(0,8)])
degs = fh.concat([map(lambda j: j + i, [0,1,2,3,4,3,2,1,0]) for i in range(0,8)])

score = mh.listsDegreesToPart(degs, durs)
score.insert(0, meter.TimeSignature('5/4'))
#score.show('musicxml')


#Etude 2: up and down different scales
durs = fh.concat([[0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1.0] for i in range(0,8)])
degs = fh.concat([sc.degreesToNotes([0,1,2,3,4,3,2,1,0], scale = map(lambda j: j + i, scales["major"])) for i in scales["major"] + [12]])
score = mh.listsToPart(degs, durs)
score.insert(0, meter.TimeSignature('5/4'))
#score.show('musicxml')

#Etude 3: up and down scale with intervals of 2
예제 #24
0
 def getCells(self, chunk):
     if chunk.depth == 0:
         return [chunk]
     else:
         return fh.concat([self.getCells(i) for i in chunk.sub_chunks])
예제 #25
0
def closestNotesInChord(note, chord):
    all_notes = fh.concat([map(lambda j: i + j, chord) for i in range(-14,14,7)])
    dChords = [(i, abs(note - i)) for i in all_notes]
    dChords.sort(key=lambda tup:tup[1])
    return [i[0] for i in dChords]