fixed ulab spectrogram imports
This commit is contained in:
parent
527a999bf9
commit
f5db43ed6f
5 changed files with 699 additions and 124 deletions
|
|
@ -18,8 +18,11 @@ import adafruit_is31fl3741
|
|||
from adafruit_is31fl3741.adafruit_ledglasses import LED_Glasses
|
||||
from rainbowio import colorwheel
|
||||
from ulab import numpy as np
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
try:
|
||||
from ulab.utils import spectrogram
|
||||
except ImportError:
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
# FFT/SPECTRUM CONFIG ----
|
||||
|
||||
|
|
|
|||
|
|
@ -18,11 +18,11 @@ import adafruit_is31fl3741
|
|||
from adafruit_is31fl3741.adafruit_rgbmatrixqt import Adafruit_RGBMatrixQT
|
||||
from rainbowio import colorwheel
|
||||
from ulab import numpy as np
|
||||
# if using CP7 and below:
|
||||
from ulab.scipy.signal import spectrogram
|
||||
# if using CP8 and above:
|
||||
# from ulab.utils import spectrogram
|
||||
|
||||
try:
|
||||
from ulab.utils import spectrogram
|
||||
except ImportError:
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
# FFT/SPECTRUM CONFIG ----
|
||||
|
||||
|
|
@ -40,7 +40,7 @@ high_bin = 75 # Highest bin "
|
|||
i2c = I2C(board.SCL, board.SDA, frequency=1000000)
|
||||
|
||||
# Initialize the IS31 LED driver, buffered for smoother animation
|
||||
#glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER)
|
||||
# glasses = LED_Glasses(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER)
|
||||
glasses = Adafruit_RGBMatrixQT(i2c, allocate=adafruit_is31fl3741.MUST_BUFFER)
|
||||
|
||||
glasses.show() # Clear any residue on startup
|
||||
|
|
@ -152,7 +152,7 @@ while True:
|
|||
|
||||
# Apply vertical scale to spectrum data. Results may exceed
|
||||
# matrix height...that's OK, adds impact!
|
||||
#data = (spectrum - lower) * (7 / (dynamic_level - lower))
|
||||
# data = (spectrum - lower) * (7 / (dynamic_level - lower))
|
||||
data = (spectrum - lower) * ((glasses.height + 2) / (dynamic_level - lower))
|
||||
|
||||
for column, element in enumerate(column_table):
|
||||
|
|
|
|||
|
|
@ -2,16 +2,20 @@
|
|||
#
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
'''Adapted from the FFT Example: Waterfall Spectrum Analyzer
|
||||
"""Adapted from the FFT Example: Waterfall Spectrum Analyzer
|
||||
by Jeff Epler
|
||||
https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython/overview '''
|
||||
https://learn.adafruit.com/ulab-crunch-numbers-fast-with-circuitpython/overview """
|
||||
|
||||
import array
|
||||
import board
|
||||
import audiobusio
|
||||
import busio
|
||||
from ulab import numpy as np
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
try:
|
||||
from ulab.utils import spectrogram
|
||||
except ImportError:
|
||||
from ulab.scipy.signal import spectrogram
|
||||
import adafruit_is31fl3741
|
||||
from adafruit_is31fl3741.adafruit_rgbmatrixqt import Adafruit_RGBMatrixQT
|
||||
|
||||
|
|
@ -30,34 +34,79 @@ is31.enable = True
|
|||
# array of colors for the LEDs
|
||||
# goes from purple to red
|
||||
# gradient generated using https://colordesigner.io/gradient-generator
|
||||
heatmap = [0xb000ff,0xa600ff,0x9b00ff,0x8f00ff,0x8200ff,
|
||||
0x7400ff,0x6500ff,0x5200ff,0x3900ff,0x0003ff,
|
||||
0x0003ff,0x0047ff,0x0066ff,0x007eff,0x0093ff,
|
||||
0x00a6ff,0x00b7ff,0x00c8ff,0x00d7ff,0x00e5ff,
|
||||
0x00e0ff,0x00e6fd,0x00ecf6,0x00f2ea,0x00f6d7,
|
||||
0x00fac0,0x00fca3,0x00fe81,0x00ff59,0x00ff16,
|
||||
0x00ff16,0x45ff08,0x62ff00,0x78ff00,0x8bff00,
|
||||
0x9bff00,0xaaff00,0xb8ff00,0xc5ff00,0xd1ff00,
|
||||
0xedff00,0xf5eb00,0xfcd600,0xffc100,0xffab00,
|
||||
0xff9500,0xff7c00,0xff6100,0xff4100,0xff0000,
|
||||
0xff0000,0xff0000]
|
||||
heatmap = [
|
||||
0xB000FF,
|
||||
0xA600FF,
|
||||
0x9B00FF,
|
||||
0x8F00FF,
|
||||
0x8200FF,
|
||||
0x7400FF,
|
||||
0x6500FF,
|
||||
0x5200FF,
|
||||
0x3900FF,
|
||||
0x0003FF,
|
||||
0x0003FF,
|
||||
0x0047FF,
|
||||
0x0066FF,
|
||||
0x007EFF,
|
||||
0x0093FF,
|
||||
0x00A6FF,
|
||||
0x00B7FF,
|
||||
0x00C8FF,
|
||||
0x00D7FF,
|
||||
0x00E5FF,
|
||||
0x00E0FF,
|
||||
0x00E6FD,
|
||||
0x00ECF6,
|
||||
0x00F2EA,
|
||||
0x00F6D7,
|
||||
0x00FAC0,
|
||||
0x00FCA3,
|
||||
0x00FE81,
|
||||
0x00FF59,
|
||||
0x00FF16,
|
||||
0x00FF16,
|
||||
0x45FF08,
|
||||
0x62FF00,
|
||||
0x78FF00,
|
||||
0x8BFF00,
|
||||
0x9BFF00,
|
||||
0xAAFF00,
|
||||
0xB8FF00,
|
||||
0xC5FF00,
|
||||
0xD1FF00,
|
||||
0xEDFF00,
|
||||
0xF5EB00,
|
||||
0xFCD600,
|
||||
0xFFC100,
|
||||
0xFFAB00,
|
||||
0xFF9500,
|
||||
0xFF7C00,
|
||||
0xFF6100,
|
||||
0xFF4100,
|
||||
0xFF0000,
|
||||
0xFF0000,
|
||||
0xFF0000,
|
||||
]
|
||||
|
||||
# size of the FFT data sample
|
||||
fft_size = 64
|
||||
|
||||
# setup for onboard mic
|
||||
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
|
||||
sample_rate=16000, bit_depth=16)
|
||||
mic = audiobusio.PDMIn(
|
||||
board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16
|
||||
)
|
||||
|
||||
# use some extra sample to account for the mic startup
|
||||
samples_bit = array.array('H', [0] * (fft_size+3))
|
||||
samples_bit = array.array("H", [0] * (fft_size + 3))
|
||||
|
||||
# sends visualized data to the RGB matrix with colors
|
||||
def waves(data, y):
|
||||
offset = max(0, (13-len(data))//2)
|
||||
offset = max(0, (13 - len(data)) // 2)
|
||||
|
||||
for x in range(min(13, len(data))):
|
||||
is31.pixel(x+offset, y, heatmap[int(data[x])])
|
||||
is31.pixel(x + offset, y, heatmap[int(data[x])])
|
||||
|
||||
|
||||
# main loop
|
||||
def main():
|
||||
|
|
@ -78,7 +127,7 @@ def main():
|
|||
# spectrum() is always nonnegative, but add a tiny value
|
||||
# to change any zeros to nonzero numbers
|
||||
spectrogram1 = np.log(spectrogram1 + 1e-7)
|
||||
spectrogram1 = spectrogram1[1:(fft_size//2)-1]
|
||||
spectrogram1 = spectrogram1[1 : (fft_size // 2) - 1]
|
||||
# sets range of the spectrogram
|
||||
min_curr = np.min(spectrogram1)
|
||||
max_curr = np.max(spectrogram1)
|
||||
|
|
@ -86,10 +135,10 @@ def main():
|
|||
if max_curr > max_all:
|
||||
max_all = max_curr
|
||||
else:
|
||||
max_curr = max_curr-1
|
||||
max_curr = max_curr - 1
|
||||
min_curr = max(min_curr, 3)
|
||||
# stores spectrogram in data
|
||||
data = (spectrogram1 - min_curr) * (51. / (max_all - min_curr))
|
||||
data = (spectrogram1 - min_curr) * (51.0 / (max_all - min_curr))
|
||||
# sets negative numbers to zero
|
||||
data = data * np.array((data > 0))
|
||||
# resets y
|
||||
|
|
@ -101,4 +150,5 @@ def main():
|
|||
# writes data to the RGB matrix
|
||||
is31.show()
|
||||
|
||||
|
||||
main()
|
||||
|
|
|
|||
608
Ukulele/code.py
608
Ukulele/code.py
|
|
@ -24,7 +24,11 @@ import digitalio
|
|||
import audiobusio
|
||||
import board
|
||||
import neopixel
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
try:
|
||||
from ulab.utils import spectrogram
|
||||
except ImportError:
|
||||
from ulab.scipy.signal import spectrogram
|
||||
from ulab import numpy as np
|
||||
from rainbowio import colorwheel
|
||||
from adafruit_lsm6ds import lsm6ds33
|
||||
|
|
@ -46,11 +50,11 @@ from adafruit_led_animation.color import (
|
|||
WHITE,
|
||||
)
|
||||
|
||||
MAX_BRIGHTNESS = 0.3 #set max brightness for sound reactive mode
|
||||
NORMAL_BRIGHTNESS = 0.1 #set brightness for non-reactive mode
|
||||
VOLUME_CALIBRATOR = 50 #multiplier for brightness mapping
|
||||
ROCKSTAR_TILT_THRESHOLD = 200 #shake threshold
|
||||
SOUND_THRESHOLD = 430000 #main strum or pluck threshold
|
||||
MAX_BRIGHTNESS = 0.3 # set max brightness for sound reactive mode
|
||||
NORMAL_BRIGHTNESS = 0.1 # set brightness for non-reactive mode
|
||||
VOLUME_CALIBRATOR = 50 # multiplier for brightness mapping
|
||||
ROCKSTAR_TILT_THRESHOLD = 200 # shake threshold
|
||||
SOUND_THRESHOLD = 430000 # main strum or pluck threshold
|
||||
|
||||
# Set to the length in seconds for the animations
|
||||
POWER_ON_DURATION = 1.3
|
||||
|
|
@ -71,56 +75,520 @@ pixels.fill(0) # NeoPixels off ASAP on startup
|
|||
pixels.show()
|
||||
|
||||
|
||||
#PIXEL MAPS: Used for reordering pixels so the animations can run in different configurations.
|
||||
#My LED strips inside the neck are accidentally swapped left-right,
|
||||
#so these maps also correct for that
|
||||
# PIXEL MAPS: Used for reordering pixels so the animations can run in different configurations.
|
||||
# My LED strips inside the neck are accidentally swapped left-right,
|
||||
# so these maps also correct for that
|
||||
|
||||
|
||||
#Bottom up along both sides at once
|
||||
pixel_map_reverse = PixelMap(pixels, [
|
||||
0, 103, 1, 102, 2, 101, 3, 100, 4, 99, 5, 98, 6, 97, 7, 96, 8, 95, 9, 94, 10,
|
||||
93, 11, 92, 12, 91, 13, 90, 14, 89, 15, 88, 16, 87, 17, 86, 18, 85, 19, 84, 20,
|
||||
83, 21, 82, 22, 81, 23, 80, 24, 79, 25, 78, 26, 77, 27, 76, 28, 75, 29, 74, 30,
|
||||
73, 31, 72, 32, 71, 33, 70, 34, 69, 35, 68, 36, 67, 37, 66, 38, 65, 39, 64, 40,
|
||||
63, 41, 62, 42, 61, 43, 60, 44, 59, 45, 58, 46, 57, 47, 56, 48, 55, 49, 54, 50,
|
||||
53, 51, 52,
|
||||
], individual_pixels=True)
|
||||
# Bottom up along both sides at once
|
||||
pixel_map_reverse = PixelMap(
|
||||
pixels,
|
||||
[
|
||||
0,
|
||||
103,
|
||||
1,
|
||||
102,
|
||||
2,
|
||||
101,
|
||||
3,
|
||||
100,
|
||||
4,
|
||||
99,
|
||||
5,
|
||||
98,
|
||||
6,
|
||||
97,
|
||||
7,
|
||||
96,
|
||||
8,
|
||||
95,
|
||||
9,
|
||||
94,
|
||||
10,
|
||||
93,
|
||||
11,
|
||||
92,
|
||||
12,
|
||||
91,
|
||||
13,
|
||||
90,
|
||||
14,
|
||||
89,
|
||||
15,
|
||||
88,
|
||||
16,
|
||||
87,
|
||||
17,
|
||||
86,
|
||||
18,
|
||||
85,
|
||||
19,
|
||||
84,
|
||||
20,
|
||||
83,
|
||||
21,
|
||||
82,
|
||||
22,
|
||||
81,
|
||||
23,
|
||||
80,
|
||||
24,
|
||||
79,
|
||||
25,
|
||||
78,
|
||||
26,
|
||||
77,
|
||||
27,
|
||||
76,
|
||||
28,
|
||||
75,
|
||||
29,
|
||||
74,
|
||||
30,
|
||||
73,
|
||||
31,
|
||||
72,
|
||||
32,
|
||||
71,
|
||||
33,
|
||||
70,
|
||||
34,
|
||||
69,
|
||||
35,
|
||||
68,
|
||||
36,
|
||||
67,
|
||||
37,
|
||||
66,
|
||||
38,
|
||||
65,
|
||||
39,
|
||||
64,
|
||||
40,
|
||||
63,
|
||||
41,
|
||||
62,
|
||||
42,
|
||||
61,
|
||||
43,
|
||||
60,
|
||||
44,
|
||||
59,
|
||||
45,
|
||||
58,
|
||||
46,
|
||||
57,
|
||||
47,
|
||||
56,
|
||||
48,
|
||||
55,
|
||||
49,
|
||||
54,
|
||||
50,
|
||||
53,
|
||||
51,
|
||||
52,
|
||||
],
|
||||
individual_pixels=True,
|
||||
)
|
||||
|
||||
#Starts at the bottom and goes around clockwise
|
||||
pixel_map_around = PixelMap(pixels, [
|
||||
0, 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, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64,
|
||||
63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45,
|
||||
44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
|
||||
76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
|
||||
95, 96, 97, 98, 99, 100, 101, 102, 103,
|
||||
], individual_pixels=True)
|
||||
# Starts at the bottom and goes around clockwise
|
||||
pixel_map_around = PixelMap(
|
||||
pixels,
|
||||
[
|
||||
0,
|
||||
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,
|
||||
75,
|
||||
74,
|
||||
73,
|
||||
72,
|
||||
71,
|
||||
70,
|
||||
69,
|
||||
68,
|
||||
67,
|
||||
66,
|
||||
65,
|
||||
64,
|
||||
63,
|
||||
62,
|
||||
61,
|
||||
60,
|
||||
59,
|
||||
58,
|
||||
57,
|
||||
56,
|
||||
55,
|
||||
54,
|
||||
53,
|
||||
52,
|
||||
51,
|
||||
50,
|
||||
49,
|
||||
48,
|
||||
47,
|
||||
46,
|
||||
45,
|
||||
44,
|
||||
43,
|
||||
42,
|
||||
41,
|
||||
40,
|
||||
39,
|
||||
38,
|
||||
37,
|
||||
36,
|
||||
35,
|
||||
34,
|
||||
33,
|
||||
32,
|
||||
31,
|
||||
30,
|
||||
29,
|
||||
28,
|
||||
76,
|
||||
77,
|
||||
78,
|
||||
79,
|
||||
80,
|
||||
81,
|
||||
82,
|
||||
83,
|
||||
84,
|
||||
85,
|
||||
86,
|
||||
87,
|
||||
88,
|
||||
89,
|
||||
90,
|
||||
91,
|
||||
92,
|
||||
93,
|
||||
94,
|
||||
95,
|
||||
96,
|
||||
97,
|
||||
98,
|
||||
99,
|
||||
100,
|
||||
101,
|
||||
102,
|
||||
103,
|
||||
],
|
||||
individual_pixels=True,
|
||||
)
|
||||
|
||||
#Radiates from the center outwards like a starburst
|
||||
pixel_map_radiate = PixelMap(pixels, [
|
||||
75, 73, 76, 27, 28, 74, 77, 26, 29, 73, 78, 25, 30, 72, 79, 24, 31, 71, 80,
|
||||
23, 32, 70, 81, 22, 33, 69, 82, 21, 34, 68, 83, 20, 35, 67, 84, 19, 36, 66,
|
||||
85, 18, 37, 65, 38, 86, 17, 64, 39, 87, 16, 63, 40, 88, 15, 62, 41, 89, 14,
|
||||
61, 42, 90, 13, 60, 43, 91, 12, 59, 44, 92, 11, 58, 45, 93, 10, 57, 46, 94,
|
||||
9, 56, 47, 95, 8, 55, 48, 96, 7, 54, 49, 97, 6, 53, 50, 98, 5, 52, 51, 99,
|
||||
4, 100, 3, 101, 2, 102, 1, 103, 0,
|
||||
], individual_pixels=True)
|
||||
# Radiates from the center outwards like a starburst
|
||||
pixel_map_radiate = PixelMap(
|
||||
pixels,
|
||||
[
|
||||
75,
|
||||
73,
|
||||
76,
|
||||
27,
|
||||
28,
|
||||
74,
|
||||
77,
|
||||
26,
|
||||
29,
|
||||
73,
|
||||
78,
|
||||
25,
|
||||
30,
|
||||
72,
|
||||
79,
|
||||
24,
|
||||
31,
|
||||
71,
|
||||
80,
|
||||
23,
|
||||
32,
|
||||
70,
|
||||
81,
|
||||
22,
|
||||
33,
|
||||
69,
|
||||
82,
|
||||
21,
|
||||
34,
|
||||
68,
|
||||
83,
|
||||
20,
|
||||
35,
|
||||
67,
|
||||
84,
|
||||
19,
|
||||
36,
|
||||
66,
|
||||
85,
|
||||
18,
|
||||
37,
|
||||
65,
|
||||
38,
|
||||
86,
|
||||
17,
|
||||
64,
|
||||
39,
|
||||
87,
|
||||
16,
|
||||
63,
|
||||
40,
|
||||
88,
|
||||
15,
|
||||
62,
|
||||
41,
|
||||
89,
|
||||
14,
|
||||
61,
|
||||
42,
|
||||
90,
|
||||
13,
|
||||
60,
|
||||
43,
|
||||
91,
|
||||
12,
|
||||
59,
|
||||
44,
|
||||
92,
|
||||
11,
|
||||
58,
|
||||
45,
|
||||
93,
|
||||
10,
|
||||
57,
|
||||
46,
|
||||
94,
|
||||
9,
|
||||
56,
|
||||
47,
|
||||
95,
|
||||
8,
|
||||
55,
|
||||
48,
|
||||
96,
|
||||
7,
|
||||
54,
|
||||
49,
|
||||
97,
|
||||
6,
|
||||
53,
|
||||
50,
|
||||
98,
|
||||
5,
|
||||
52,
|
||||
51,
|
||||
99,
|
||||
4,
|
||||
100,
|
||||
3,
|
||||
101,
|
||||
2,
|
||||
102,
|
||||
1,
|
||||
103,
|
||||
0,
|
||||
],
|
||||
individual_pixels=True,
|
||||
)
|
||||
|
||||
#Top down along both sides at once
|
||||
pixel_map_sweep = PixelMap(pixels, [
|
||||
51, 52, 50, 53, 49, 54, 48, 55, 47, 56, 46, 57, 45, 58, 44, 59, 43, 60, 42, 61,
|
||||
41, 62, 40, 63, 39, 64, 38, 65, 37, 66, 36, 67, 35, 68, 34, 69, 33, 70, 32, 71,
|
||||
31, 72, 30, 73, 29, 74, 28, 75, 27, 76, 27, 77, 26, 78, 25, 79, 24, 80, 23, 81,
|
||||
22, 82, 21, 83, 20, 84, 19, 85, 18, 86, 17, 87, 16, 88, 15, 89, 14, 90, 13, 91,
|
||||
12, 92, 11, 93, 10, 94, 9, 95, 8, 96, 7, 97, 6, 98, 5, 99, 4, 100, 3, 101, 2, 102, 1, 103, 0
|
||||
], individual_pixels=True)
|
||||
# Top down along both sides at once
|
||||
pixel_map_sweep = PixelMap(
|
||||
pixels,
|
||||
[
|
||||
51,
|
||||
52,
|
||||
50,
|
||||
53,
|
||||
49,
|
||||
54,
|
||||
48,
|
||||
55,
|
||||
47,
|
||||
56,
|
||||
46,
|
||||
57,
|
||||
45,
|
||||
58,
|
||||
44,
|
||||
59,
|
||||
43,
|
||||
60,
|
||||
42,
|
||||
61,
|
||||
41,
|
||||
62,
|
||||
40,
|
||||
63,
|
||||
39,
|
||||
64,
|
||||
38,
|
||||
65,
|
||||
37,
|
||||
66,
|
||||
36,
|
||||
67,
|
||||
35,
|
||||
68,
|
||||
34,
|
||||
69,
|
||||
33,
|
||||
70,
|
||||
32,
|
||||
71,
|
||||
31,
|
||||
72,
|
||||
30,
|
||||
73,
|
||||
29,
|
||||
74,
|
||||
28,
|
||||
75,
|
||||
27,
|
||||
76,
|
||||
27,
|
||||
77,
|
||||
26,
|
||||
78,
|
||||
25,
|
||||
79,
|
||||
24,
|
||||
80,
|
||||
23,
|
||||
81,
|
||||
22,
|
||||
82,
|
||||
21,
|
||||
83,
|
||||
20,
|
||||
84,
|
||||
19,
|
||||
85,
|
||||
18,
|
||||
86,
|
||||
17,
|
||||
87,
|
||||
16,
|
||||
88,
|
||||
15,
|
||||
89,
|
||||
14,
|
||||
90,
|
||||
13,
|
||||
91,
|
||||
12,
|
||||
92,
|
||||
11,
|
||||
93,
|
||||
10,
|
||||
94,
|
||||
9,
|
||||
95,
|
||||
8,
|
||||
96,
|
||||
7,
|
||||
97,
|
||||
6,
|
||||
98,
|
||||
5,
|
||||
99,
|
||||
4,
|
||||
100,
|
||||
3,
|
||||
101,
|
||||
2,
|
||||
102,
|
||||
1,
|
||||
103,
|
||||
0,
|
||||
],
|
||||
individual_pixels=True,
|
||||
)
|
||||
|
||||
#Every other pixel, starting at the bottom and going upwards along both sides
|
||||
pixel_map_skip = PixelMap(pixels, [
|
||||
0, 103, 2, 101, 4, 99, 6, 97, 8, 95, 10, 93, 12, 91, 14, 89, 16, 87, 18, 85, 20,
|
||||
83, 22, 81, 24, 79, 26, 77, 29, 74, 31, 72, 33, 70, 35, 68, 37, 66, 39, 64, 41,
|
||||
62, 43, 60, 45, 58, 47, 56, 49, 54, 51, 52,
|
||||
], individual_pixels=True)
|
||||
# Every other pixel, starting at the bottom and going upwards along both sides
|
||||
pixel_map_skip = PixelMap(
|
||||
pixels,
|
||||
[
|
||||
0,
|
||||
103,
|
||||
2,
|
||||
101,
|
||||
4,
|
||||
99,
|
||||
6,
|
||||
97,
|
||||
8,
|
||||
95,
|
||||
10,
|
||||
93,
|
||||
12,
|
||||
91,
|
||||
14,
|
||||
89,
|
||||
16,
|
||||
87,
|
||||
18,
|
||||
85,
|
||||
20,
|
||||
83,
|
||||
22,
|
||||
81,
|
||||
24,
|
||||
79,
|
||||
26,
|
||||
77,
|
||||
29,
|
||||
74,
|
||||
31,
|
||||
72,
|
||||
33,
|
||||
70,
|
||||
35,
|
||||
68,
|
||||
37,
|
||||
66,
|
||||
39,
|
||||
64,
|
||||
41,
|
||||
62,
|
||||
43,
|
||||
60,
|
||||
45,
|
||||
58,
|
||||
47,
|
||||
56,
|
||||
49,
|
||||
54,
|
||||
51,
|
||||
52,
|
||||
],
|
||||
individual_pixels=True,
|
||||
)
|
||||
|
||||
pixel_map = [
|
||||
pixel_map_reverse,
|
||||
|
|
@ -130,15 +598,15 @@ pixel_map = [
|
|||
pixel_map_skip,
|
||||
]
|
||||
|
||||
#Set up accelerometer & mic
|
||||
# Set up accelerometer & mic
|
||||
sensor = lsm6ds33.LSM6DS33(i2c)
|
||||
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK,
|
||||
board.MICROPHONE_DATA,
|
||||
sample_rate=16000,
|
||||
bit_depth=16)
|
||||
mic = audiobusio.PDMIn(
|
||||
board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16
|
||||
)
|
||||
|
||||
NUM_SAMPLES = 256
|
||||
samples_bit = array.array('H', [0] * (NUM_SAMPLES+3))
|
||||
samples_bit = array.array("H", [0] * (NUM_SAMPLES + 3))
|
||||
|
||||
|
||||
def power_on(duration):
|
||||
"""
|
||||
|
|
@ -151,6 +619,7 @@ def power_on(duration):
|
|||
break # Stop animating
|
||||
powerup.animate()
|
||||
|
||||
|
||||
def rockstar_tilt(duration):
|
||||
"""
|
||||
Tilt animation - lightning effect with a rotating color
|
||||
|
|
@ -181,6 +650,7 @@ def rockstar_tilt(duration):
|
|||
pixels.show()
|
||||
time.sleep(0.03)
|
||||
|
||||
|
||||
# Cusomize LED Animations ------------------------------------------------------
|
||||
powerup = RainbowComet(pixel_map[3], speed=0, tail_length=25, bounce=False)
|
||||
rainbow = Rainbow(pixel_map[4], speed=0, period=6, name="rainbow", step=2.4)
|
||||
|
|
@ -190,13 +660,13 @@ chase = Chase(pixel_map[1], speed=0.1, color=RED, size=1, spacing=6)
|
|||
rainbow_comet = RainbowComet(pixel_map[2], speed=0, tail_length=80, bounce=True)
|
||||
rainbow_comet2 = RainbowComet(
|
||||
pixel_map[0], speed=0, tail_length=104, colorwheel_offset=80, bounce=True
|
||||
)
|
||||
)
|
||||
rainbow_comet3 = RainbowComet(
|
||||
pixel_map[1], speed=0, tail_length=25, colorwheel_offset=80, step=4, bounce=False
|
||||
)
|
||||
)
|
||||
strum = RainbowComet(
|
||||
pixel_map[3], speed=0, tail_length=25, bounce=False, colorwheel_offset=50, step=4
|
||||
)
|
||||
)
|
||||
lava = Comet(pixel_map[3], speed=0.01, color=ORANGE, tail_length=40, bounce=False)
|
||||
sparkle = Sparkle(pixel_map[4], speed=0.01, color=BLUE, num_sparkles=10)
|
||||
sparkle2 = Sparkle(pixel_map[1], speed=0.05, color=PURPLE, num_sparkles=4)
|
||||
|
|
@ -213,18 +683,18 @@ animations = AnimationSequence(
|
|||
AnimationGroup(
|
||||
sparkle,
|
||||
strum,
|
||||
),
|
||||
),
|
||||
AnimationGroup(
|
||||
sparkle2,
|
||||
rainbow_comet3,
|
||||
),
|
||||
),
|
||||
auto_clear=True,
|
||||
auto_reset=True,
|
||||
)
|
||||
|
||||
|
||||
MODE = 0
|
||||
LASTMODE = 1 # start up in sound reactive mode
|
||||
LASTMODE = 1 # start up in sound reactive mode
|
||||
i = 0
|
||||
|
||||
# Main loop
|
||||
|
|
@ -245,9 +715,9 @@ while True:
|
|||
spectrum[1] = 0
|
||||
peak_idx = np.argmax(spectrum)
|
||||
peak_freq = peak_idx * 16000 / 256
|
||||
# print((peak_idx, peak_freq, spectrum[peak_idx]))
|
||||
# print((peak_idx, peak_freq, spectrum[peak_idx]))
|
||||
magnitude = spectrum[peak_idx]
|
||||
# time.sleep(1)
|
||||
# time.sleep(1)
|
||||
if peak_freq == 812.50 and magnitude > SOUND_THRESHOLD:
|
||||
animations.next()
|
||||
time.sleep(1)
|
||||
|
|
@ -262,10 +732,10 @@ while True:
|
|||
print("mode = 1")
|
||||
LASTMODE = 1
|
||||
time.sleep(1)
|
||||
# Read accelerometer
|
||||
# Read accelerometer
|
||||
x, y, z = sensor.acceleration
|
||||
accel_total = x * x + y * y # x=tilt, y=rotate
|
||||
# print (accel_total)
|
||||
accel_total = x * x + y * y # x=tilt, y=rotate
|
||||
# print (accel_total)
|
||||
if accel_total > ROCKSTAR_TILT_THRESHOLD:
|
||||
MODE = 3
|
||||
print("Tilted: ", accel_total)
|
||||
|
|
@ -273,9 +743,9 @@ while True:
|
|||
VOLUME = magnitude / (VOLUME_CALIBRATOR * 100000)
|
||||
if VOLUME > MAX_BRIGHTNESS:
|
||||
VOLUME = MAX_BRIGHTNESS
|
||||
# print(VOLUME)
|
||||
# print(VOLUME)
|
||||
pixels.brightness = VOLUME
|
||||
# time.sleep(2)
|
||||
# time.sleep(2)
|
||||
animations.animate()
|
||||
elif MODE == 2:
|
||||
pixels.brightness = NORMAL_BRIGHTNESS
|
||||
|
|
|
|||
|
|
@ -12,32 +12,81 @@ import board
|
|||
import audiobusio
|
||||
import displayio
|
||||
from ulab import numpy as np
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
try:
|
||||
from ulab.utils import spectrogram
|
||||
except ImportError:
|
||||
from ulab.scipy.signal import spectrogram
|
||||
|
||||
display = board.DISPLAY
|
||||
|
||||
# Create a heatmap color palette
|
||||
palette = displayio.Palette(52)
|
||||
for i, pi in enumerate((0xff0000, 0xff0a00, 0xff1400, 0xff1e00,
|
||||
0xff2800, 0xff3200, 0xff3c00, 0xff4600,
|
||||
0xff5000, 0xff5a00, 0xff6400, 0xff6e00,
|
||||
0xff7800, 0xff8200, 0xff8c00, 0xff9600,
|
||||
0xffa000, 0xffaa00, 0xffb400, 0xffbe00,
|
||||
0xffc800, 0xffd200, 0xffdc00, 0xffe600,
|
||||
0xfff000, 0xfffa00, 0xfdff00, 0xd7ff00,
|
||||
0xb0ff00, 0x8aff00, 0x65ff00, 0x3eff00,
|
||||
0x17ff00, 0x00ff10, 0x00ff36, 0x00ff5c,
|
||||
0x00ff83, 0x00ffa8, 0x00ffd0, 0x00fff4,
|
||||
0x00a4ff, 0x0094ff, 0x0084ff, 0x0074ff,
|
||||
0x0064ff, 0x0054ff, 0x0044ff, 0x0032ff,
|
||||
0x0022ff, 0x0012ff, 0x0002ff, 0x0000ff)):
|
||||
palette[51-i] = pi
|
||||
for i, pi in enumerate(
|
||||
(
|
||||
0xFF0000,
|
||||
0xFF0A00,
|
||||
0xFF1400,
|
||||
0xFF1E00,
|
||||
0xFF2800,
|
||||
0xFF3200,
|
||||
0xFF3C00,
|
||||
0xFF4600,
|
||||
0xFF5000,
|
||||
0xFF5A00,
|
||||
0xFF6400,
|
||||
0xFF6E00,
|
||||
0xFF7800,
|
||||
0xFF8200,
|
||||
0xFF8C00,
|
||||
0xFF9600,
|
||||
0xFFA000,
|
||||
0xFFAA00,
|
||||
0xFFB400,
|
||||
0xFFBE00,
|
||||
0xFFC800,
|
||||
0xFFD200,
|
||||
0xFFDC00,
|
||||
0xFFE600,
|
||||
0xFFF000,
|
||||
0xFFFA00,
|
||||
0xFDFF00,
|
||||
0xD7FF00,
|
||||
0xB0FF00,
|
||||
0x8AFF00,
|
||||
0x65FF00,
|
||||
0x3EFF00,
|
||||
0x17FF00,
|
||||
0x00FF10,
|
||||
0x00FF36,
|
||||
0x00FF5C,
|
||||
0x00FF83,
|
||||
0x00FFA8,
|
||||
0x00FFD0,
|
||||
0x00FFF4,
|
||||
0x00A4FF,
|
||||
0x0094FF,
|
||||
0x0084FF,
|
||||
0x0074FF,
|
||||
0x0064FF,
|
||||
0x0054FF,
|
||||
0x0044FF,
|
||||
0x0032FF,
|
||||
0x0022FF,
|
||||
0x0012FF,
|
||||
0x0002FF,
|
||||
0x0000FF,
|
||||
)
|
||||
):
|
||||
palette[51 - i] = pi
|
||||
|
||||
|
||||
class RollingGraph(displayio.TileGrid):
|
||||
def __init__(self, scale=2):
|
||||
# Create a bitmap with heatmap colors
|
||||
self._bitmap = displayio.Bitmap(display.width//scale,
|
||||
display.height//scale, len(palette))
|
||||
self._bitmap = displayio.Bitmap(
|
||||
display.width // scale, display.height // scale, len(palette)
|
||||
)
|
||||
super().__init__(self._bitmap, pixel_shader=palette)
|
||||
|
||||
self.scroll_offset = 0
|
||||
|
|
@ -47,14 +96,15 @@ class RollingGraph(displayio.TileGrid):
|
|||
bitmap = self._bitmap
|
||||
|
||||
board.DISPLAY.auto_refresh = False
|
||||
offset = max(0, (bitmap.width-len(data))//2)
|
||||
offset = max(0, (bitmap.width - len(data)) // 2)
|
||||
for x in range(min(bitmap.width, len(data))):
|
||||
bitmap[x+offset, y] = int(data[x])
|
||||
bitmap[x + offset, y] = int(data[x])
|
||||
|
||||
board.DISPLAY.auto_refresh = True
|
||||
|
||||
self.scroll_offset = (y + 1) % self.bitmap.height
|
||||
|
||||
|
||||
group = displayio.Group(scale=3)
|
||||
graph = RollingGraph(3)
|
||||
fft_size = 256
|
||||
|
|
@ -66,11 +116,12 @@ group.append(graph)
|
|||
display.show(group)
|
||||
|
||||
# instantiate board mic
|
||||
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
|
||||
sample_rate=16000, bit_depth=16)
|
||||
mic = audiobusio.PDMIn(
|
||||
board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, bit_depth=16
|
||||
)
|
||||
|
||||
#use some extra sample to account for the mic startup
|
||||
samples_bit = array.array('H', [0] * (fft_size+3))
|
||||
# use some extra sample to account for the mic startup
|
||||
samples_bit = array.array("H", [0] * (fft_size + 3))
|
||||
|
||||
# Main Loop
|
||||
def main():
|
||||
|
|
@ -83,21 +134,22 @@ def main():
|
|||
# spectrum() is always nonnegative, but add a tiny value
|
||||
# to change any zeros to nonzero numbers
|
||||
spectrogram1 = np.log(spectrogram1 + 1e-7)
|
||||
spectrogram1 = spectrogram1[1:(fft_size//2)-1]
|
||||
spectrogram1 = spectrogram1[1 : (fft_size // 2) - 1]
|
||||
min_curr = np.min(spectrogram1)
|
||||
max_curr = np.max(spectrogram1)
|
||||
|
||||
if max_curr > max_all:
|
||||
max_all = max_curr
|
||||
else:
|
||||
max_curr = max_curr-1
|
||||
max_curr = max_curr - 1
|
||||
|
||||
print(min_curr, max_all)
|
||||
min_curr = max(min_curr, 3)
|
||||
# Plot FFT
|
||||
data = (spectrogram1 - min_curr) * (51. / (max_all - min_curr))
|
||||
data = (spectrogram1 - min_curr) * (51.0 / (max_all - min_curr))
|
||||
# This clamps any negative numbers to zero
|
||||
data = data * np.array((data > 0))
|
||||
graph.show(data)
|
||||
|
||||
|
||||
main()
|
||||
|
|
|
|||
Loading…
Reference in a new issue