Beispiel #1
0
    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
Beispiel #2
0
    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