class PointFx(Fx): enabled = True position = 0 def __init__(self, video_buffer, color=(255,255,255), range=None, **kwargs): super().__init__(video_buffer, **kwargs) self.point = Point(0, video_buffer.N) self.range = range or (0, video_buffer.N) self.color = [c/255.0 for c in color] self.p0 = self.range[0] / self.video_buffer.N self.p1 = self.range[1] / self.video_buffer.N def project(self, position): """ take position from 0->1 and map to entire video_buffer range """ return self.p0 + position * (self.p1-self.p0) def set(self, position): self.position = self.project(position) def _update(self): N = self.video_buffer.N self.point.pos = self.position points = self.point.get_points() for i,color in enumerate(self.color): if i in (0,1,2): self.video_buffer.buffer[i:N*3:3][points>0] = color*points[points>0]
def _update(self): secs = (datetime.now() - self.timestamp).total_seconds() # if we haven't seen a metronome() call in 2 seconds, revert to autoscan delta_beat = secs / (60.0/self.bpm) if self.count in (1, 3): self.pos = delta_beat else: self.pos = 1 - delta_beat if delta_beat > 1.05 or delta_beat < -0.05: delta_beat = np.clip(delta_beat, 0, 1) self.count = ((self.count) % 4) + 1 self.timestamp = datetime.now() for scanner in self.scanners: n1,n2 = scanner['n1'], scanner['n2'] r,g,b = scanner.get('color', (1,1,1)) point = Point(self.pos, n2 - n1, width=scanner.get('width', 2)) points = point.get_points() color_points = np.full((n2-n1)*3, fill_value=0, dtype=np.uint8) color_points[0::3] = r * points color_points[1::3] = g * points color_points[2::3] = b * points self.video_buffer.merge(n1, n2, color_points)