def generate_list(self, input, result, prev_notes): self.ncalls+=1 is_first_phrase= self.is_first_phrase() if is_first_phrase: start_pitch= self.pick_support_note(input.now_chord, input.min_pitch, input.max_pitch) second_pitch= None else: second_pitch= self.ec.last_support_note start_pitch= self.ec.last_pitches[-1] end_pitch= self.pick_support_note(input.prox_chord, input.min_pitch, input.max_pitch) phrase_length= input.rythm_phrase_len assert phrase_length > 0 if phrase_length == 1 and is_first_phrase: import ipdb;ipdb.set_trace() if phrase_length == 1 and not is_first_phrase: self.ec.last_support_note= end_pitch self.ec.last_state= self._choose_state(self.ec.last_pitches[-2], self.ec.last_pitches[-1], second_pitch) self.ec.last_pitches.append(second_pitch) return self._generate_result(input, result, [second_pitch]) next_chord_pitches= set([n.pitch%12 for n in input.prox_chord.notes]) available_notes= set(xrange(input.min_pitch, input.max_pitch+1)) end_pitches= [p for p in available_notes if p%12 in next_chord_pitches] robs= NarmourRandomObservation(start_pitch, second_pitch, end_pitches, phrase_length, self.melody_alg.model, min_pitch=input.min_pitch, max_pitch=input.max_pitch, start=self.ec.last_state) if is_first_phrase: #XXX hack nexts_distr= robs._get_state_distr(robs.actual_state) for state, state_tuples in robs.must_dict[phrase_length-1].iteritems(): if state not in nexts_distr: continue if len(state_tuples) == 0: continue second_note_candidates= [i[1] for i in state_tuples if i[0] == start_pitch] if len(second_note_candidates) == 0: continue break print state if len(second_note_candidates) == 0: import ipdb;ipdb.set_trace() second_pitch= robs.n1= choice(second_note_candidates) robs.now_pitches= set([(robs.n0, robs.n1)]) path= [robs.actual_state] for i in xrange(phrase_length-1): robs.next() path.append(robs.actual_state) self.ec.last_state= path[-1] # los estados del hmm van a ser tupla (pos, narmour_interval) para # permitir que haya varias veces el mismo estado en la cadena states= [PathNarmourState(ni, i) for (i, ni) in enumerate(path)] hmm= HiddenMarkovModel() hmm.add_hidden_state(states[0], 1.0) for prev, next in zip(states, states[1:]): hmm.add_hidden_state(next, 0.0) hmm.add_transition(prev, next, 1.0) for next, prob in self.melody_alg.model.nexts(path[-1]).iteritems(): next= PathNarmourState(next, len(states)) hmm.add_hidden_state(next, 0.0) hmm.add_transition(states[-1], next, prob) #hmm.make_walkable() #import ipdb;ipdb.set_trace() robs2= NarmourRandomObservation(start_pitch, second_pitch, end_pitches, phrase_length, hmm, min_pitch=input.min_pitch, max_pitch=input.max_pitch) self._check_sub_model(robs, robs2) if (start_pitch, second_pitch) not in robs2.must_dict[phrase_length-1][states[1]]: import ipdb;ipdb.set_trace() if (start_pitch, second_pitch) not in robs.must_dict[phrase_length-1][path[1]]: import ipdb;ipdb.set_trace() context_distr= dict((n.pitch, prob) for (n,prob) in self.melody_alg.candidate_pitches(input.now_chord.notes)) if is_first_phrase: pitches= [start_pitch, second_pitch] else: pitches= [second_pitch] #import ipdb;ipdb.set_trace() for i in xrange(1, phrase_length - 1): # candidates lo inicializo en las que tengo que tocar antes del proximo estado candidates= robs2.must_dict[phrase_length-1-i][states[i+1]] if len(pitches) == 1: prev_pitch= start_pitch else: prev_pitch= pitches[-2] candidates= candidates.intersection(path[i].related_notes(prev_pitch, pitches[-1], available_notes, reverse=False)) #if not candidates.issubset(xrange(input.min_pitch, input.max_pitch+1)): import ipdb;ipdb.set_trace() #candidates= candidates.intersection(xrange(input.min_pitch, input.max_pitch+1)) if len(candidates) == 0: import ipdb;ipdb.set_trace() candidates_distr= dict((p[1], context_distr.get(p[1]%12)*1.0/(2**abs(p[1]-pitches[-1])+1)) for p in candidates if context_distr.get(p[1]%12) is not None) # XXX ver que hacer cuando el contexto no me deja tocar (paso el contexto a la definicion de Must?) if len(candidates_distr) == 0: print "CONTEXTO NO ME DEJO" candidates_distr= dict((p[1],1.0/(1+2**abs(p[1]-pitches[-1]))) for p in candidates) new_pitch= RandomPicker(values=candidates_distr).get_value(normalize=True) #if not (new_pitch >= input.min_pitch and new_pitch <= input.max_pitch): import ipdb;ipdb.set_trace() pitches.append(new_pitch) for i, (p1, p2, p3) in enumerate(zip(pitches, pitches[1:], pitches[2:])): node= path[i+1] if (p1, p2, p3) not in node: import ipdb;ipdb.set_trace() #if p2 not in node.related_notes(p1): import ipdb;ipdb.set_trace() self.ec.last_pitches= pitches[:] if len(pitches) != phrase_length: import ipdb;ipdb.set_trace() res= [] for pitch in pitches: child_result= result.copy() child_input= input.copy() child_result.pitch= pitch res.append((child_input, child_result)) self.ec.last_support_note= end_pitch return res
def generate_list(self, input, result, prev_notes): self.ncalls+=1 if self.ec.last_support_note is None: start_pitch= self.pick_support_note(input.now_chord, input.min_pitch, input.max_pitch) else: start_pitch= self.ec.last_support_note end_pitch= self.pick_support_note(input.prox_chord, input.min_pitch, input.max_pitch) phrase_length= input.rythm_phrase_len assert phrase_length > 0 if phrase_length <= 2: child_result= result.copy() child_input= input.copy() child_result.pitch= start_pitch res= [(child_input, child_result)] if phrase_length == 2: child_result= result.copy() child_input= input.copy() child_result.pitch= end_pitch res.append((child_input, child_result)) return res # construyo el camino en la cadena de narmour robs= NarmourRandomObservation(start_pitch, end_pitch, phrase_length, self.melody_alg.model, min_pitch= input.min_pitch, max_pitch= input.max_pitch, start=self.ec.last_state) path= [robs.actual_state] #if self.ncalls == 15: import ipdb;ipdb.set_trace() for i in xrange(phrase_length): robs.next() path.append(robs.actual_state) self.ec.last_state= path[-1] # los estados del hmm van a ser tupla (pos, narmour_interval) para # permitir que haya varias veces el mismo estado en la cadena states= [PathNarmourInterval(ni, i) for (i, ni) in enumerate(path)] hmm= HiddenMarkovModel() hmm.add_hidden_state(states[0], 1.0) for prev, next in zip(states, states[1:]): hmm.add_hidden_state(next, 0.0) hmm.add_transition(prev, next, 1.0) #import ipdb;ipdb.set_trace() hmm.make_walkable() robs2= NarmourRandomObservation(start_pitch, end_pitch, phrase_length, hmm, min_pitch=input.min_pitch, max_pitch=input.max_pitch) if start_pitch not in robs2.must_dict[phrase_length-1][states[1]]: import ipdb;ipdb.set_trace() pitches= [start_pitch] context_distr= dict((n.pitch, prob) for (n,prob) in self.melody_alg.candidate_pitches(input.now_chord.notes)) for i in xrange(1, phrase_length): # candidates lo inicializo en las que tengo que tocar antes del proximo estado candidates= robs2.must_dict[phrase_length-1-i][states[i+1]] candidates= candidates.intersection(path[i].related_notes(pitches[-1])) if not candidates.issubset(xrange(input.min_pitch, input.max_pitch+1)): import ipdb;ipdb.set_trace() #candidates= candidates.intersection(xrange(input.min_pitch, input.max_pitch+1)) if len(candidates) == 0: import ipdb;ipdb.set_trace() candidates_distr= dict((p, context_distr.get(p%12)*1.0/(2**abs(p-pitches[-1])+1)) for p in candidates if context_distr.get(p%12) is not None) # XXX ver que hacer cuando el contexto no me deja tocar (paso el contexto a la definicion de Must?) if len(candidates_distr) == 0: print "CONTEXTO NO ME DEJO" candidates_distr= dict((p,1.0/(1+2**abs(p-pitches[-1]))) for p in candidates) new_pitch= RandomPicker(values=candidates_distr).get_value(normalize=True) #if not (new_pitch >= input.min_pitch and new_pitch <= input.max_pitch): import ipdb;ipdb.set_trace() pitches.append(new_pitch) #import ipdb;ipdb.set_trace() for i, (p1, p2) in enumerate(zip(pitches, pitches[1:])): node= path[i+1] if p2 not in node.related_notes(p1): import ipdb;ipdb.set_trace() if len(pitches) != phrase_length: import ipdb;ipdb.set_trace() res= [] for pitch in pitches: child_result= result.copy() child_input= input.copy() child_result.pitch= pitch res.append((child_input, child_result)) return res