Example #1
0
 def advance(self):
     # return True if advanced
     if self.index + 1 == len(self.segments):  # last segment
         if self.loop:
             self.segments[self.index].reset()
             self.index = 0
             self.current_segment_time_delta = 0
             if self.loop_counter and self.loop > 0:
                 # this is a finite loop
                 self.loop_counter -= 1
             return True
         else:
             # non-looping, or done with final loop
             pass
     else:
         # proceed through sequence of segments
         if self.segments[self.index]:
             # TODO - this is a reason to always have a segment of some sort
             # even if it is a null segment, rather than use none
             self.segments[self.index].reset()
         self.index += 1
         self.current_segment_time_delta = 0
         logger.debug("advanced to %s" % self.segments[self.index].label)
         return True
     self.advancing = False
     return False
Example #2
0
 def advance(self):
     # return True if advanced
     if self.index + 1 == len(self.segments):  # last segment
         if self.loop:
             self.segments[self.index].reset()
             self.index = 0
             self.current_segment_time_delta = 0
             if self.loop_counter and self.loop > 0:
                 # this is a finite loop
                 self.loop_counter -= 1
             return True
         else:
             # non-looping, or done with final loop
             pass
     else:
         # proceed through sequence of segments
         if self.segments[self.index]:
             # TODO - this is a reason to always have a segment of some sort
             # even if it is a null segment, rather than use none
             self.segments[self.index].reset()
         self.index += 1
         self.current_segment_time_delta = 0
         logger.debug("advanced to %s" % self.segments[self.index].label)
         return True
     self.advancing = False
     return False
Example #3
0
    def _off_trigger(self):
        self.trigger_state = 0
        # TODO - setting trigger intensity to 0 here - works for sweeps
        # but non-sweep has to use trigger 1 as it doesn't have access to the
        # original trigger_intensity
        self.trigger_intensity = 0

        # if self.bell_mode:
            # TODO does bell apply to chase classes?
            # ignore release in bell mode
            # return

        logger.debug("%s: pulse trigger off" % self.name)
        self.reset_positions()

        if self.off_mode == "all":
            # TODO some cleanup needed - moving set to false in
            # reset_positions, need to more clearly define between
            # these functions what does what
            self.moving = False
            for e in self.elements:
                    # blackout
                    e.trigger(0)
        elif self.off_mode in ["follow", "reverse"]:
            # reset the chase to follow itself as trigger off
            # TODO - placeholder, not sure anything needs to be done
            self.moving = True
Example #4
0
    def trigger(self, intensity, **kwargs):
        # @@ need toggle mode implementation here
        if self.simple:
#            print "BaseLightElement triggered"
            self.set_intensity(intensity)
            return
        if intensity > 0 and self.trigger_state == 0:
            if self.bell_mode:
                self.bell_reset()
            self.trigger_state = 1
            [x.trigger(intensity) for x in self.effects]
            self.trigger_intensity = intensity
            logger.debug("%s: trigger on @ %s" % (self.name, intensity))
            self.set_intensity(0.0)  # reset light on trigger
            self.adsr_envelope.trigger(state=1)
            self._on_trigger(intensity, **kwargs)
        elif intensity == 0 and (self.trigger_state and not self.trigger_toggle
                and not self.bell_mode):
            self._off_trigger()
        elif intensity and self.trigger_state and self.trigger_toggle:
            self._off_trigger()
        elif intensity > self.intensity and self.trigger_state == 1:
            # a greater trigger intensity has occured - override
            self.trigger_intensity = intensity
            logger.debug("%s: override trigger on @ %s" %
                    (self.name, intensity))
            self.intensity = 0.0  # reset light on trigger
            # reset the envelope with a forced on trigger
            self.adsr_envelope.trigger(state=1, force=True)
Example #5
0
    def trigger(self, state=1, value=1.0, force=False):
        """
        state is on or off
        value is 0-1 for max value of tween - currently not
        handled from here - must be set at segment level
        can be used to scale max value on callers end - ie midi velocity
        value of 0 is also implicit state=0
        """
        assert len(self.segments) == 2, "too many segments for a \
        trigger envelope"

        # TODO I think the whole value arg and associated code needs to go
        # this is only about state
        if value == 0:
            state = 0
        if force:
            self.state = not state
        if self.state != state:
            self.state = state
            if state:
                # on trigger
                logger.debug("envelope trigger on - resetting")
                self.reset()
                logger.debug("%s-%s: self post reset current elapsed %s" % (
                    id(self),
                    self.label,
                    self.current_segment_time_delta,
                ))
            else:
                # off trigger
                self.advance()
                logger.debug("current value: %s" % self.value)
                logger.debug("current change for release: %s" %
                             self.segments[1].get_profile().change)
                if self.value < self.segments[1].get_profile().start:
                    # TODO this shortcut works on release, but for attack?
                    # also need to sort out when in decay (say .9), and release
                    # start is .8 - now will be greater - want a way to change
                    # release start value for this time only
                    # perhaps start value should always just be current value
                    # - for when greater if dimmer, want shorter release if
                    # brigher (.9) then want standard release time but greater
                    # change

                    jump_value = self.segments[1].get_profile().get_jump_time(
                        self.value)
                    self.update(jump_value)
                # TODO - this won't work for multisegment release
                # if not hasattr(self.segments[1], 'segments'):
                # self.segments[1].segments[0].profile.change = -1 * self.value
                # self.segments[1].segments[0].profile.start = self.value
                # else:
                # print "has segments"
                # print self.segments[1].segments

                logger.debug("new current change for release: %s" %
                             self.segments[1].get_profile().change)
        self.state = state
Example #6
0
    def trigger(self, state=1, value=1.0, force=False):
        """
        state is on or off
        value is 0-1 for max value of tween - currently not
        handled from here - must be set at segment level
        can be used to scale max value on callers end - ie midi velocity
        value of 0 is also implicit state=0
        """
        assert len(self.segments) == 2, "too many segments for a \
        trigger envelope"
        # TODO I think the whole value arg and associated code needs to go
        # this is only about state
        if value == 0:
            state = 0
        if force:
            self.state = not state
        if self.state != state:
            self.state = state
            if state:
                # on trigger
                logger.debug("envelope trigger on - resetting")
                self.reset()
                logger.debug("%s-%s: self post reset current elapsed %s" % (
                        id(self),
                        self.label,
                        self.current_segment_time_delta,
                        ))
            else:
                # off trigger
                self.advance()
                logger.debug("current value: %s" % self.value)
                logger.debug("current change for release: %s" %
                        self.segments[1].get_profile().change)
                if self.value < self.segments[1].get_profile().start:
                    # TODO this shortcut works on release, but for attack?
                    # also need to sort out when in decay (say .9), and release
                    # start is .8 - now will be greater - want a way to change
                    # release start value for this time only
                    # perhaps start value should always just be current value
                    # - for when greater if dimmer, want shorter release if
                    # brigher (.9) then want standard release time but greater
                    # change

                    jump_value = self.segments[1].get_profile().get_jump_time(
                            self.value)
                    self.update(jump_value)
                # TODO - this won't work for multisegment release
                # if not hasattr(self.segments[1], 'segments'):
                # self.segments[1].segments[0].profile.change = -1 * self.value
                # self.segments[1].segments[0].profile.start = self.value
                # else:
                    # print "has segments"
                    # print self.segments[1].segments

                logger.debug("new current change for release: %s" %
                        self.segments[1].get_profile().change)
        self.state = state
Example #7
0
 def _move_completed(self):
     # called at the end of a move, for looping, pong, etc
     # TODO while pulse paused at one end - this is firing multiple
     # times
     if self.continuation_mode == 'pong':
         if round(self.center_position) == self.end_pos:
             logger.debug("%s pong-end @ %s" % (self.name, self.end_pos))
             self.moveto = self.start_pos
         if round(self.center_position) == self.start_pos:
             self.moveto = self.end_pos
     elif self.continuation_mode == 'loop':
         # TODO the last_center reset is an easy one to miss, and should
         # be built into something else
         self.last_center = self.center_position = self.start_pos
         self.setup_move()
     else:
         self.moving = False
     self.move_complete = True
     if self.bell_mode and self.trigger_state:
         self._off_trigger()
Example #8
0
    def set_current_nodes(self):
        """
        the node array becomes a list of values - generally for intensity
        that describes the left and right shape of the pulse around
        the center_position.

        The node_range specifies the location start and end of the pulse
        overall
        """
        node_offset = self.center_position % 1
        left_of_center = math.floor(self.center_position)
        far_left = int(left_of_center - self.left_width)
        self.nodes = []
        for n in range(self.left_width + 1):
            self.nodes.append(self.left_shape(
                        n + node_offset, 1, -1, self.left_width + 1.0))
        if far_left >= 1:
            self.nodes.append(0)
            far_left -= 1
        self.nodes.reverse()
        for n in range(1, self.right_width + 1):
            self.nodes.append(self.right_shape(
                    max(0, n - node_offset), 1, -1, self.right_width + 1.0))
        self.nodes.append(0)
        self.node_range = range(far_left, far_left + len(self.nodes))
        logger.debug("NodeData:")
        logger.debug(self.node_range)
        logger.debug(self.nodes)
Example #9
0
    def update(self, delta):
        # delta is time passed since last update
        if self.index + 1 > len(self.segments):
            # non looping or end of finite loop
            # just reurn last value until something resets index
            return self.value
        segment = self.current_segment
        if not segment.duration:
            # for example, no attack value
            # self.advance()
            pass
        self.current_segment_time_delta += delta
        logger.debug("%s-%s: self current elapsed %s, after delta %s" % (
            id(self),
            self.label,
            self.current_segment_time_delta,
            delta,
        ))
        logger.debug("current segment %s" % segment.label)
        # TODO this is advancing past end of on segemnt,
        # when that on segment only contains a 0 duration attack, and no decay
        # not going into any sustain
        if (self.current_segment_time_delta > segment.duration
                and not isinstance(segment, StaticEnvelopeSegment)):
            overage = self.current_segment_time_delta - segment.duration
            logger.debug("overage: %s" % overage)
            # TODO currently don't handle case where overage > new segment
            # duration - could need recursion

            if self.advance():
                logger.debug('advanced, new delta: %s' % overage)
                delta = self.current_segment_time_delta = overage
                segment = self.segments[self.index]
            else:
                logger.debug("did not advance after overage")

        self.value = segment.update(delta)
        return self.value
Example #10
0
    def update(self, delta):
        # delta is time passed since last update
        if self.index + 1 > len(self.segments):
            # non looping or end of finite loop
            # just reurn last value until something resets index
            return self.value
        segment = self.current_segment
        if not segment.duration:
            # for example, no attack value
            # self.advance()
            pass
        self.current_segment_time_delta += delta
        logger.debug("%s-%s: self current elapsed %s, after delta %s" % (
                id(self),
                self.label,
                self.current_segment_time_delta,
                delta,
        ))
        logger.debug("current segment %s" % segment.label)
        # TODO this is advancing past end of on segemnt,
        # when that on segment only contains a 0 duration attack, and no decay
        # not going into any sustain
        if (self.current_segment_time_delta > segment.duration and
                not isinstance(segment, StaticEnvelopeSegment)):
            overage = self.current_segment_time_delta - segment.duration
            logger.debug("overage: %s" % overage)
            # TODO currently don't handle case where overage > new segment
            # duration - could need recursion

            if self.advance():
                logger.debug('advanced, new delta: %s' % overage)
                delta = self.current_segment_time_delta = overage
                segment = self.segments[self.index]
            else:
                logger.debug("did not advance after overage")

        self.value = segment.update(delta)
        return self.value
Example #11
0
 def trigger(self, intensity, **kwargs):
     if intensity > 0 and self.trigger_state == 0:  # or note off message
         if self.moving:
             # we are already in either in an active on or off chase
             # TODO - do we reset everything - draw on top...?
             # print "Already moving"
             return
         # self.reset_positions()
         # TODO so reset positions only for off trigger?
         self.trigger_state = 1
         self.trigger_intensity = intensity
         self.center_position = self.last_center = self.start_pos
         self.moveto = self.end_pos
         logger.debug("%s: chase trigger on @ %s" % (self.name, intensity))
         self.moving = True
         self.setup_move()
         self._on_trigger(intensity, **kwargs)
     elif intensity == 0 and (self.trigger_state and not self.trigger_toggle
             and not self.bell_mode):
         self._off_trigger()
     elif intensity and self.trigger_state and self.trigger_toggle:
         logger.info("%s: chase trigger toggle off @ %s" % (self.name,
             intensity))
         self._off_trigger()
Example #12
0
    def update(self, show):
        """
        The update method is called once per iteration of the main show loop.
        """
        if (self.simple or not (self.update_active)):
            # light is inactive or in sustain mode
            # print 'inactive intensity: ', self.name, self.intensity
            return self.intensity
        if self.bell_mode and self.adsr_envelope.segments[0].index == 1:
            # bell mode ignores trigger off - simulate trigger off once
            # sustain levels are reached
            self.bell_reset()
            return

        if self.adsr_envelope.advancing:
            intensity_scale = self.adsr_envelope.update(show.time_delta)
            self.set_intensity(self.trigger_intensity * intensity_scale)
        elif self.trigger_intensity:
            logger.debug(self.name)
            logger.debug('not advancing, intensity: {}'.format(self.intensity))
            self.trigger_intensity = 0.0
            self.intensity = max(0, self.intensity)
            logger.debug('not advancing, intensity: {}'.format(self.intensity))
            logger.debug('not advancing, trigger intensity: {}'.format(
                self.trigger_intensity))
            # only turn off effects here so they can continue to effect
            # releases
            [x.trigger(0) for x in self.effects]

        # moved dmx update to show update, to accomodate effects
        # self.dmx_update(show.universes[self.universe].dmx)
        # if self.last_used_intensity != self.intensity:
        #     print int(self.intensity)
        for effect in self.effects:
            effect.update(show, [self])
        self.device.set_intensity(self.intensity)
        #print 'intensity: ', self.name, self.intensity
        return self.intensity
Example #13
0
 def get_profile(self):
     logger.debug("Envelop %s profile property, index: %s" %
                  (self.label, self.index))
     end_segment = self.get_current_segment()
     return end_segment.profile
Example #14
0
 def get_profile(self):
     logger.debug("Envelop %s profile property, index: %s" % (self.label,
         self.index))
     end_segment = self.get_current_segment()
     return end_segment.profile
Example #15
0
 def update(self, show):
     super(PulseChase, self).update(show)
     logger.debug("%s Centered @ %s -> %s" %
             (self.name, self.center_position, self.end_pos))
Example #16
0
 def _off_trigger(self):
     self.trigger_state = 0
     logger.debug("%s: trigger off" % self.name)
     self.adsr_envelope.trigger(state=0)