mirror of
https://github.com/polyfloyd/ledcat-nyancat.git
synced 2025-07-04 16:20:09 +02:00
Perform some tweaking on the PCM visualizer
This commit is contained in:
parent
587598e8c5
commit
743e94d293
2 changed files with 27 additions and 16 deletions
|
@ -4,14 +4,14 @@ import sys
|
||||||
import time
|
import time
|
||||||
from PIL import Image # Requires the Pillow library
|
from PIL import Image # Requires the Pillow library
|
||||||
|
|
||||||
background_color = (0x0f, 0x4d, 0x8f)
|
background_color = (0x07, 0x26, 0x47)
|
||||||
tail_colors = [
|
tail_colors = [
|
||||||
(0xff, 0x00, 0x00),
|
(0xff, 0x00, 0x00),
|
||||||
(0xff, 0x99, 0x00),
|
(0xff, 0x99, 0x00),
|
||||||
(0xff, 0xff, 0x00),
|
(0xff, 0xff, 0x00),
|
||||||
(0x00, 0xff, 0x00),
|
(0x00, 0xff, 0x00),
|
||||||
(0x00, 0x99, 0xff),
|
(0x00, 0x88, 0xcc),
|
||||||
(0x66, 0x33, 0xff),
|
(0xaa, 0x00, 0xaa),
|
||||||
]
|
]
|
||||||
|
|
||||||
anim_cat = []
|
anim_cat = []
|
||||||
|
@ -40,8 +40,8 @@ class Nyancat(object):
|
||||||
self.sparkles = []
|
self.sparkles = []
|
||||||
|
|
||||||
def render(self):
|
def render(self):
|
||||||
self.frame_index = (self.frame_index + 1) % len(anim_cat)
|
self.frame_index = (self.frame_index + 1) % (len(anim_cat) * 2)
|
||||||
anim_frame = anim_cat[self.frame_index]
|
anim_frame = anim_cat[self.frame_index // 2]
|
||||||
|
|
||||||
if len(self.sparkles) < 32:
|
if len(self.sparkles) < 32:
|
||||||
self.sparkles.append(Sparkle(self.width, self.height))
|
self.sparkles.append(Sparkle(self.width, self.height))
|
||||||
|
@ -52,7 +52,7 @@ class Nyancat(object):
|
||||||
frame[i*3:i*3+3] = background_color
|
frame[i*3:i*3+3] = background_color
|
||||||
|
|
||||||
# Render the tail
|
# 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):
|
for (y, color) in enumerate(tail_colors, tail_y - len(tail_colors) // 2):
|
||||||
if 0 <= y < self.height:
|
if 0 <= y < self.height:
|
||||||
i = y * self.width + x
|
i = y * self.width + x
|
||||||
|
|
31
nyan/pcm.py
31
nyan/pcm.py
|
@ -1,36 +1,47 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import math
|
||||||
|
import sys
|
||||||
from nyancat import Nyancat
|
from nyancat import Nyancat
|
||||||
|
|
||||||
INTERVAL = 1 / 20
|
INTERVAL = 1 / 20
|
||||||
WAVE_FACTOR = 3
|
FACTOR = 3
|
||||||
|
AMPLIFICATION = 3
|
||||||
|
HISTORY_SIZE = 4
|
||||||
|
|
||||||
class NyancatSignal(Nyancat):
|
class NyancatSignal(Nyancat):
|
||||||
def __init__(self, w, h, signal):
|
def __init__(self, w, h, signal):
|
||||||
super().__init__(w, h)
|
super().__init__(w, h)
|
||||||
self.signal = signal
|
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):
|
def plot_tail(self, width):
|
||||||
# Calculate the wave
|
# Calculate the wave
|
||||||
samples = self.signal.get_signal(INTERVAL)
|
samples = self.signal.get_signal(INTERVAL)
|
||||||
samples_offset = 0
|
samples_offset = 0
|
||||||
smallest_diff = float('inf')
|
smallest_diff = float('inf')
|
||||||
# Find a part in the new sample window that resembles the previous one.
|
# 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):
|
# this makes the wave seem stand still.
|
||||||
z = zip(self.samples_history[-1][0:width], samples[i:i + width * WAVE_FACTOR])
|
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))
|
diff = sum(map(lambda t: (t[0] - t[1]) ** 2, z))
|
||||||
if diff < smallest_diff:
|
if diff < smallest_diff:
|
||||||
samples_offset = i
|
samples_offset = i
|
||||||
smallest_diff = diff
|
smallest_diff = diff
|
||||||
assert samples_offset + width * WAVE_FACTOR < len(samples), 'w=%d < len=%d' % (samples_offset + width * WAVE_FACTOR, len(samples))
|
assert samples_offset + width * FACTOR < len(samples), 'w=%d < len=%d' % (samples_offset + width * FACTOR, len(samples))
|
||||||
self.samples_history.append(samples[samples_offset:samples_offset + width * WAVE_FACTOR])
|
|
||||||
|
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)
|
self.samples_history.pop(0)
|
||||||
|
|
||||||
# Render the tail
|
|
||||||
for x in range(width):
|
for x in range(width):
|
||||||
amplitude = sum(map(lambda hist: hist[x * WAVE_FACTOR], self.samples_history)) / len(self.samples_history) * 3
|
amplitude = sum([samples[x * FACTOR] for samples in self.samples_history]) / len(self.samples_history) * AMPLIFICATION
|
||||||
yield int((amplitude * .5 - .5) * self.height) + self.height
|
yield int((amplitude * .5 + .5) * self.height)
|
||||||
|
|
||||||
def sleep(self):
|
def sleep(self):
|
||||||
pass # Handled by a blocking read from the audio source
|
pass # Handled by a blocking read from the audio source
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue