From 743e94d293053635c3c1694eb004cdd4a3858ca7 Mon Sep 17 00:00:00 2001 From: polyfloyd Date: Tue, 10 Oct 2017 23:55:40 +0200 Subject: [PATCH] Perform some tweaking on the PCM visualizer --- nyan/nyancat.py | 12 ++++++------ nyan/pcm.py | 31 +++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/nyan/nyancat.py b/nyan/nyancat.py index 8898be9..4a61c4d 100644 --- a/nyan/nyancat.py +++ b/nyan/nyancat.py @@ -4,14 +4,14 @@ import sys import time from PIL import Image # Requires the Pillow library -background_color = (0x0f, 0x4d, 0x8f) +background_color = (0x07, 0x26, 0x47) tail_colors = [ (0xff, 0x00, 0x00), (0xff, 0x99, 0x00), (0xff, 0xff, 0x00), (0x00, 0xff, 0x00), - (0x00, 0x99, 0xff), - (0x66, 0x33, 0xff), + (0x00, 0x88, 0xcc), + (0xaa, 0x00, 0xaa), ] anim_cat = [] @@ -40,8 +40,8 @@ class Nyancat(object): self.sparkles = [] def render(self): - self.frame_index = (self.frame_index + 1) % len(anim_cat) - anim_frame = anim_cat[self.frame_index] + self.frame_index = (self.frame_index + 1) % (len(anim_cat) * 2) + anim_frame = anim_cat[self.frame_index // 2] if len(self.sparkles) < 32: self.sparkles.append(Sparkle(self.width, self.height)) @@ -52,7 +52,7 @@ class Nyancat(object): frame[i*3:i*3+3] = background_color # Render the tail - for (x, tail_y) in enumerate(self.plot_tail(self.width - 10)): + for (x, tail_y) in enumerate(self.plot_tail(self.width - 24)): for (y, color) in enumerate(tail_colors, tail_y - len(tail_colors) // 2): if 0 <= y < self.height: i = y * self.width + x diff --git a/nyan/pcm.py b/nyan/pcm.py index d58e01f..291bfff 100644 --- a/nyan/pcm.py +++ b/nyan/pcm.py @@ -1,36 +1,47 @@ #!/usr/bin/env python3 +import math +import sys from nyancat import Nyancat INTERVAL = 1 / 20 -WAVE_FACTOR = 3 +FACTOR = 3 +AMPLIFICATION = 3 +HISTORY_SIZE = 4 class NyancatSignal(Nyancat): def __init__(self, w, h, signal): super().__init__(w, h) self.signal = signal - self.samples_history = [[0] * int(INTERVAL * signal.sample_rate * WAVE_FACTOR)] * 6 + self.samples_history = [[0] * int(INTERVAL * signal.sample_rate * FACTOR)] * HISTORY_SIZE def plot_tail(self, width): # Calculate the wave samples = self.signal.get_signal(INTERVAL) samples_offset = 0 smallest_diff = float('inf') - # Find a part in the new sample window that resembles the previous one. - for i in range(min(len(samples), len(self.samples_history[-1])) - width * WAVE_FACTOR): - z = zip(self.samples_history[-1][0:width], samples[i:i + width * WAVE_FACTOR]) + # Find a part in the new sample window that resembles the previous one, + # this makes the wave seem stand still. + for i in range(min(len(samples), len(self.samples_history[-1])) - width * FACTOR): + z = zip(self.samples_history[-1][0:width], samples[i:i + width * FACTOR]) diff = sum(map(lambda t: (t[0] - t[1]) ** 2, z)) if diff < smallest_diff: samples_offset = i smallest_diff = diff - assert samples_offset + width * WAVE_FACTOR < len(samples), 'w=%d < len=%d' % (samples_offset + width * WAVE_FACTOR, len(samples)) - self.samples_history.append(samples[samples_offset:samples_offset + width * WAVE_FACTOR]) + assert samples_offset + width * FACTOR < len(samples), 'w=%d < len=%d' % (samples_offset + width * FACTOR, len(samples)) + + selected_window = samples[samples_offset:samples_offset + width * FACTOR] + # Make sure the mean of the selected window is equal to 0, this + # lowers vertical stuttering. + win_avg = sum(selected_window) / len(selected_window) + stabilized_window = [sample + win_avg for sample in selected_window] + # Append to the history. + self.samples_history.append(stabilized_window) self.samples_history.pop(0) - # Render the tail for x in range(width): - amplitude = sum(map(lambda hist: hist[x * WAVE_FACTOR], self.samples_history)) / len(self.samples_history) * 3 - yield int((amplitude * .5 - .5) * self.height) + self.height + amplitude = sum([samples[x * FACTOR] for samples in self.samples_history]) / len(self.samples_history) * AMPLIFICATION + yield int((amplitude * .5 + .5) * self.height) def sleep(self): pass # Handled by a blocking read from the audio source