Refactored visualize.py

Refactored the led shooting_beats effect (now renamed to
radiate_effect). Formatted for pep8 compliance
This commit is contained in:
Scott Lawson 2016-10-12 16:00:05 -07:00
parent 028500f04e
commit 0809f9b6d1

View File

@ -1,31 +1,25 @@
from __future__ import print_function from __future__ import print_function
import time
import numpy as np import numpy as np
from scipy.ndimage.filters import gaussian_filter1d from scipy.ndimage.filters import gaussian_filter1d
import dsp import dsp
import led import led
import microphone as mic import microphone as mic
# Settings for beat detection
dsp.ys_beat_threshold = 1.8
dsp.ys_variance_threshold = 0.1
# List of beats currently visible on the LED strip
visible_beats = np.array([])
class Beat: class Beat:
def __init__(self, pixels, speed): def __init__(self, pixels, speed, direction):
self.pixels = pixels self.pixels = pixels
self.speed = float(speed) self.speed = float(speed)
self.zeros = np.zeros(len(pixels)) self.zeros = np.zeros(len(pixels))
self.iteration = 0 self.iteration = 0
self.direction = direction
def update_pixels(self): def update_pixels(self):
self.iteration += 1 self.iteration += 1
self.speed = max(0.95 * self.speed, 1.0) self.speed = max(0.95 * self.speed, 1.0)
self.pixels = np.roll(self.pixels, int(self.speed)) self.pixels = np.roll(self.pixels, int(self.speed))
self.pixels[:int(self.speed)] = 0.0 self.pixels[:int(self.speed)] = 0.0
s = self.iteration / led.N_pixels s = 1.5 * self.iteration / (led.N_pixels / 2.0)
self.pixels = gaussian_filter1d(self.pixels, s, mode='constant') self.pixels = gaussian_filter1d(self.pixels, s, mode='constant')
self.pixels = np.round(self.pixels, decimals=1) self.pixels = np.round(self.pixels, decimals=1)
@ -33,71 +27,58 @@ class Beat:
return (self.pixels == self.zeros).all() return (self.pixels == self.zeros).all()
prev_dir = True def radiate_effect(beats, max_speed=3, max_length=24):
def shooting_beats(beats):
global visible_beats
N_beats = len(beats[beats == True]) N_beats = len(beats[beats == True])
# Add new beat if beats were detected
# Settings
max_speed = 3
max_length = 24
if N_beats > 0: if N_beats > 0:
# Fraction of beats that have been detected # Beat properties
beat_power = float(N_beats) / dsp.N_subbands beat_power = float(N_beats) / dsp.N_subbands
# Speed
beat_speed = min(N_beats, max_speed) beat_speed = min(N_beats, max_speed)
# Brightness
beat_brightness = min(beat_power * 255.0, 255.0) beat_brightness = min(beat_power * 255.0, 255.0)
# Length
beat_length = int(np.sqrt(beat_power) * max_length) beat_length = int(np.sqrt(beat_power) * max_length)
beat_direction = not radiate_effect.previous_direction
# Pixels # Beat pixels
beat_pixels = np.zeros(led.N_pixels / 2) beat_pixels = np.zeros(led.N_pixels / 2)
beat_pixels[:beat_length] = beat_brightness beat_pixels[:beat_length] = beat_brightness
beat_pixels = gaussian_filter1d(beat_pixels, 0.5, mode='reflect') # Create and add the new beat
beat = Beat(beat_pixels, beat_speed, beat_direction)
# Create the beat radiate_effect.previous_direction = beat_direction
beat = Beat(pixels=beat_pixels, speed=beat_speed) radiate_effect.beats = np.append(radiate_effect.beats, beat)
# Assign direction # Pixels that will be displayed on the LED strip
# beat.is_left = np.random.random() > 0.5
global prev_dir
beat.is_left = not prev_dir
prev_dir = not prev_dir
visible_beats = np.append(visible_beats, beat)
# Clear pixels and add beats
remaining_beats = []
pixels_L = np.zeros(led.N_pixels / 2) pixels_L = np.zeros(led.N_pixels / 2)
pixels_R = np.zeros(led.N_pixels / 2) pixels_R = np.zeros(led.N_pixels / 2)
for i in range(len(visible_beats)): for beat in radiate_effect.beats:
if visible_beats[i].is_left: if beat.direction:
pixels_L += visible_beats[i].pixels pixels_L += beat.pixels
else: else:
pixels_R += visible_beats[i].pixels pixels_R += beat.pixels
visible_beats[i].update_pixels() beat.update_pixels()
if not visible_beats[i].finished(): # Only keep the beats that are still visible on the strip
remaining_beats.append(visible_beats[i]) radiate_effect.beats = [b for b in radiate_effect.beats if not b.finished()]
# Enforce value limits # Enforce value limits
pixels_L = np.clip(pixels_L, 0.0, 255.0) pixels_L = np.clip(pixels_L, 0.0, 255.0)
pixels_R = np.clip(pixels_R, 0.0, 255.0) pixels_R = np.clip(pixels_R, 0.0, 255.0)
# Only keep the beats that are still visible on the LED strip
visible_beats = np.array(remaining_beats)
# Update the LED values # Update the LED values
led.set_from_array(np.append(pixels_L[::-1], pixels_R)) led.set_from_array(np.append(pixels_L[::-1], pixels_R))
def microphone_update(stream): def microphone_update(stream):
data = np.fromstring(stream.read(mic.CHUNK), dtype=np.int16) / (2.0**15) data = np.fromstring(stream.read(mic.CHUNK), dtype=np.int16) / (2.0**15)
data = np.diff(data) #data = np.diff(data)
data = np.append(data, data[-1]) #data = np.append(data, data[-1])
xs, ys = dsp.fft_log_partition(data=data, subbands=dsp.N_subbands) xs, ys = dsp.fft_log_partition(data=data, subbands=dsp.N_subbands)
beats = dsp.beat_detect(ys) beats = dsp.beat_detect(ys)
# print('Beats:', len(beats[beats == True])) radiate_effect(beats)
shooting_beats(beats)
# Settings for beat detection
dsp.ys_beat_threshold = 1.8
dsp.ys_variance_threshold = 100.0
# Initial valeus for the radiate effect
radiate_effect.previous_direction = True
radiate_effect.beats = np.array([])
if __name__ == "__main__": if __name__ == "__main__":
mic.start_stream(microphone_update) mic.start_stream(microphone_update)