-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathspectrumLED.py
executable file
·78 lines (61 loc) · 1.95 KB
/
spectrumLED.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import pyaudio as pa
import numpy as np
import scipy.fftpack as sf
from luma.core.interface.serial import spi, noop
from luma.core.render import canvas
from luma.led_matrix.device import max7219
# Connect to a matrix via SPI
serial = spi(port=0, device=0, gpio=noop())
device = max7219(serial, cascaded=4, block_orientation=-90)
device.contrast(1)
# Init PyAudio
p = pa.PyAudio()
N = 1024
device_index = 4
device_info = p.get_device_info_by_index(device_index)
# Frequency processing and grouping into bars
T = 1. / 48000
x = np.fft.rfftfreq(N, T)[-N//2:]
a = np.concatenate([np.linspace(47, 1000, 8),
np.linspace(1500, 6000, 13),
np.linspace(7000, 12000, 7),
np.linspace(13000, 17000, 5)
])
bins = np.column_stack((a[:-1], a[1:]))
freq_ind = {}
bins_len = len(bins)
for i in range(32):
freq_ind[i] = []
for i, f in enumerate(x):
for j, a in enumerate(bins):
if f > a[0] and f <= a[1]:
freq_ind[j].append(i)
win = np.hamming(N*2)
win_sum = np.sum(win)
weights = np.linspace(3, 17, 32) ** 2
# Open a stream
s = p.open(format=pa.paInt16, channels=2,
rate=int(device_info['defaultSampleRate']), input=True,
frames_per_buffer=N, input_device_index=device_index)
bins_sum = np.zeros(32, dtype=np.int16)
maximums = np.zeros(64)
maximums[:] = 10000
z = 0
while True:
try:
s.start_stream()
data = np.frombuffer(s.read(N), dtype=np.int16)
except:
continue
y = sf.rfft(data * win)
y = 2 / win_sum * np.abs(y[:N//2])
for i, v in freq_ind.items():
bins_sum[i] = np.mean(y[v])
bins_sum = bins_sum * weights
maximums[z] = np.max([np.max(bins_sum), 1000])
bins_sum = ((bins_sum * 7) / np.mean(maximums)).astype(np.int16)
with canvas(device) as draw:
for x, y in enumerate(bins_sum):
draw.line([x, 8, x, 8 - y], fill=128)
s.stop_stream()
z = z + 1 if z < 63 else 0