Perform some tweaking on the PCM visualizer

This commit is contained in:
polyfloyd 2017-10-10 23:55:40 +02:00
parent 587598e8c5
commit 743e94d293
2 changed files with 27 additions and 16 deletions

View file

@ -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

View file

@ -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