diff --git a/python/visualize.py b/python/visualize.py index 459edea..9d3e2fd 100644 --- a/python/visualize.py +++ b/python/visualize.py @@ -1,31 +1,25 @@ from __future__ import print_function -import time import numpy as np from scipy.ndimage.filters import gaussian_filter1d import dsp import led 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: - def __init__(self, pixels, speed): + def __init__(self, pixels, speed, direction): self.pixels = pixels self.speed = float(speed) self.zeros = np.zeros(len(pixels)) self.iteration = 0 + self.direction = direction def update_pixels(self): self.iteration += 1 self.speed = max(0.95 * self.speed, 1.0) self.pixels = np.roll(self.pixels, int(self.speed)) 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 = np.round(self.pixels, decimals=1) @@ -33,71 +27,58 @@ class Beat: return (self.pixels == self.zeros).all() -prev_dir = True -def shooting_beats(beats): - global visible_beats +def radiate_effect(beats, max_speed=3, max_length=24): N_beats = len(beats[beats == True]) - - # Settings - max_speed = 3 - max_length = 24 - + # Add new beat if beats were detected if N_beats > 0: - # Fraction of beats that have been detected + # Beat properties beat_power = float(N_beats) / dsp.N_subbands - # Speed beat_speed = min(N_beats, max_speed) - # Brightness beat_brightness = min(beat_power * 255.0, 255.0) - # Length beat_length = int(np.sqrt(beat_power) * max_length) - - # Pixels + beat_direction = not radiate_effect.previous_direction + # Beat pixels beat_pixels = np.zeros(led.N_pixels / 2) beat_pixels[:beat_length] = beat_brightness - beat_pixels = gaussian_filter1d(beat_pixels, 0.5, mode='reflect') - - # Create the beat - beat = Beat(pixels=beat_pixels, speed=beat_speed) - # Assign direction - # 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 = [] + # Create and add the new beat + beat = Beat(beat_pixels, beat_speed, beat_direction) + radiate_effect.previous_direction = beat_direction + radiate_effect.beats = np.append(radiate_effect.beats, beat) + # Pixels that will be displayed on the LED strip pixels_L = np.zeros(led.N_pixels / 2) pixels_R = np.zeros(led.N_pixels / 2) - for i in range(len(visible_beats)): - if visible_beats[i].is_left: - pixels_L += visible_beats[i].pixels + for beat in radiate_effect.beats: + if beat.direction: + pixels_L += beat.pixels else: - pixels_R += visible_beats[i].pixels - visible_beats[i].update_pixels() - if not visible_beats[i].finished(): - remaining_beats.append(visible_beats[i]) - + pixels_R += beat.pixels + beat.update_pixels() + # Only keep the beats that are still visible on the strip + radiate_effect.beats = [b for b in radiate_effect.beats if not b.finished()] # Enforce value limits pixels_L = np.clip(pixels_L, 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 led.set_from_array(np.append(pixels_L[::-1], pixels_R)) def microphone_update(stream): data = np.fromstring(stream.read(mic.CHUNK), dtype=np.int16) / (2.0**15) - data = np.diff(data) - data = np.append(data, data[-1]) - + #data = np.diff(data) + #data = np.append(data, data[-1]) + xs, ys = dsp.fft_log_partition(data=data, subbands=dsp.N_subbands) beats = dsp.beat_detect(ys) - # print('Beats:', len(beats[beats == True])) - shooting_beats(beats) + radiate_effect(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__": mic.start_stream(microphone_update)