def _on_node_change(self, voice_player, name, old, new): if old is None or new is None: # only trigger other voices when moving to a different node return node = voice_player._current_node voice_players = self.voice_players for voice, weight_sum, transition_weights in ( self.track.get_transition_weights(node, 'Trigger') ): if voice is voice_player.voice: # Do not let voices trigger themselves. continue transition = choose_transition(weight_sum, transition_weights) target_voice_player = voice_players[voice] if node is transition.target_node: target_voice_player._current_node = None target_voice_player._current_node = transition.target_node target_voice_player.time = voice_player.time target_voice_player.phrase_player.play()
def iter(self): phrase_player = self.phrase_player # Start with the voice's start node. This will also set the phrase # player's phrase to the node's phrase. self._current_node = self.voice.start_node phrase_player.play() while True: # Wait until there is a phrase to be played back if phrase_player.phrase is None: yield None # Exit the loop if the voice player has been stopped if not self.playing: break continue try: yield phrase_player.play_iter.next() except StopIteration: # The phrase player has finished its phrase or was stopped. # Exit the loop if the voice player has been stopped. if not self.playing: break # Choose the next phrase transition. transition = choose_transition( *self.track.get_voice_transition_weights( self._current_node, 'Phrase', self.voice ) ) if transition is None: # If there is no transition for the current voice, # try to get a transition for all voices. transition = choose_transition( *self.track.get_voice_transition_weights( self._current_node, 'Phrase', None ) ) if transition is None: next_node = None else: # Set the node to be played back next. This will also set # the phrase player's phrase to the new node's phrase. next_node = transition.target_node self._current_node = next_node phrase_player.play() if next_node is None or next_node.phrase is None: # If there is no phrase to be played, update the # externally visible node attribute immediately for we # don't have a chance to do so later on (the else-branch # below will not be reached in this case). self.current_node = next_node else: # Check if the node has been changed, so we can now tell # observers to do their stuff while the first note of the # new node is already being played. if self.current_node is not self._current_node: self.current_node = self._current_node phrase_player.current_point = None self._current_node = None self.current_node = None self.time = -1