Skip to content

Commit c2ae212

Browse files
committed
Adding code for the RGB Matrix QT audio visualizer
Adding code for the RGB Matrix QT audio visualizer. Uses a Feather Sense to sample audio that is visualized with the RGB LEDs with ulab
1 parent 568abca commit c2ae212

File tree

1 file changed

+100
-0
lines changed
  • Feather_Sense_Audio_Visualizer_13x9_RGB_LED_Matrix

1 file changed

+100
-0
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
'''Adapted from the FFT Example: Waterfall Spectrum Analyzer
2+
by Jeff Epler
3+
https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython/overview '''
4+
5+
import array
6+
import board
7+
import audiobusio
8+
import busio
9+
from ulab import numpy as np
10+
from ulab.scipy.signal import spectrogram
11+
import adafruit_is31fl3741
12+
from adafruit_is31fl3741.adafruit_rgbmatrixqt import Adafruit_RGBMatrixQT
13+
14+
# Manually declare I2c (not board.I2C()) to access 1 MHz speed for
15+
i2c = busio.I2C(board.SCL, board.SDA, frequency=1000000)
16+
# Declare is31 w/buffering preferred (low RAM will fall back on unbuffered)
17+
is31 = Adafruit_RGBMatrixQT(i2c, allocate=adafruit_is31fl3741.PREFER_BUFFER)
18+
# In buffered mode, MUST use show() to refresh matrix (see line 94)
19+
20+
# brightness for the RGBMatrixQT
21+
# set to about 20%
22+
is31.set_led_scaling(0x19)
23+
is31.global_current = 0x03
24+
is31.enable = True
25+
26+
# array of colors for the LEDs
27+
# goes from purple to red
28+
# gradient generated using https://colordesigner.io/gradient-generator
29+
heatmap = [0xb000ff,0xa600ff,0x9b00ff,0x8f00ff,0x8200ff,
30+
0x7400ff,0x6500ff,0x5200ff,0x3900ff,0x0003ff,
31+
0x0003ff,0x0047ff,0x0066ff,0x007eff,0x0093ff,
32+
0x00a6ff,0x00b7ff,0x00c8ff,0x00d7ff,0x00e5ff,
33+
0x00e0ff,0x00e6fd,0x00ecf6,0x00f2ea,0x00f6d7,
34+
0x00fac0,0x00fca3,0x00fe81,0x00ff59,0x00ff16,
35+
0x00ff16,0x45ff08,0x62ff00,0x78ff00,0x8bff00,
36+
0x9bff00,0xaaff00,0xb8ff00,0xc5ff00,0xd1ff00,
37+
0xedff00,0xf5eb00,0xfcd600,0xffc100,0xffab00,
38+
0xff9500,0xff7c00,0xff6100,0xff4100,0xff0000,
39+
0xff0000,0xff0000]
40+
41+
# size of the FFT data sample
42+
fft_size = 64
43+
44+
# setup for onboard mic
45+
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
46+
sample_rate=16000, bit_depth=16)
47+
48+
# use some extra sample to account for the mic startup
49+
samples_bit = array.array('H', [0] * (fft_size+3))
50+
51+
# sends visualized data to the RGB matrix with colors
52+
def waves(data, y):
53+
offset = max(0, (13-len(data))//2)
54+
55+
for x in range(min(13, len(data))):
56+
is31.pixel(x+offset, y, heatmap[int(data[x])])
57+
58+
# main loop
59+
def main():
60+
# value for audio samples
61+
max_all = 10
62+
# variable to move data along the matrix
63+
scroll_offset = 0
64+
# setting the y axis value to equal the scroll_offset
65+
y = scroll_offset
66+
67+
while True:
68+
# record the audio sample
69+
mic.record(samples_bit, len(samples_bit))
70+
# send the sample to the ulab array
71+
samples = np.array(samples_bit[3:])
72+
# creates a spectogram of the data
73+
spectrogram1 = spectrogram(samples)
74+
# spectrum() is always nonnegative, but add a tiny value
75+
# to change any zeros to nonzero numbers
76+
spectrogram1 = np.log(spectrogram1 + 1e-7)
77+
spectrogram1 = spectrogram1[1:(fft_size//2)-1]
78+
# sets range of the spectrogram
79+
min_curr = np.min(spectrogram1)
80+
max_curr = np.max(spectrogram1)
81+
# resets values
82+
if max_curr > max_all:
83+
max_all = max_curr
84+
else:
85+
max_curr = max_curr-1
86+
min_curr = max(min_curr, 3)
87+
# stores spectrogram in data
88+
data = (spectrogram1 - min_curr) * (51. / (max_all - min_curr))
89+
# sets negative numbers to zero
90+
data = data * np.array((data > 0))
91+
# resets y
92+
y = scroll_offset
93+
# runs waves to write data to the LED's
94+
waves(data, y)
95+
# updates scroll_offset to move data along matrix
96+
scroll_offset = (y + 1) % 9
97+
# writes data to the RGB matrix
98+
is31.show()
99+
100+
main()

0 commit comments

Comments
 (0)