-
Notifications
You must be signed in to change notification settings - Fork 1
/
cpx_sound_meter.py
69 lines (50 loc) · 1.82 KB
/
cpx_sound_meter.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
import array
import audiobusio
import board
import math
import neopixel
CURVE = 2
SCALE_EXPONENT = math.pow(10, CURVE * -0.1)
PEAK_COLOR = (80, 0, 255)
NUM_PIXELS = 10
NUM_SAMPLES = 160
def constrain(value, floor, ceiling):
return max(floor, min(value, ceiling))
def log_scale(input_value, input_min, input_max, output_min, output_max):
normalized_input_value = (input_value - input_min) / (input_max - input_min)
return output_min + math.pow(normalized_input_value, SCALE_EXPONENT) * (output_max - output_min)
def normalized_rms(values):
minbuf = int(mean(values))
return math.sqrt(sum(float(sample - minbuf) * (sample - minbuf) for sample in values) / len(values))
def mean(values):
return sum(values) / len(values)
def volume_color(i):
return i * (255 // NUM_PIXELS), 50, 0
pixels = neopixel.NeoPixel(board.NEOPIXEL, NUM_PIXELS, brightness=0.1, auto_write=False)
pixels.fill(0)
pixels.show()
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, frequency=16000, bit_depth=16)
samples = array.array('H', [0] * NUM_SAMPLES)
mic.record(samples, len(samples))
input_floor = normalized_rms(samples) + 10
# Lower number means more sensitive - more LEDs will light up with less sound.
sensitivity = 500
input_ceiling = input_floor + sensitivity
peak = 0
while True:
mic.record(samples, len(samples))
magnitude = normalized_rms(samples)
print((magnitude),)
c = log_scale(constrain(magnitude, input_floor, input_ceiling),
input_floor, input_ceiling, 0, NUM_PIXELS)
pixels.fill(0)
for i in range(NUM_PIXELS):
if i < c:
pixels[i] = volume_color(i)
if c >= peak:
peak = min(c, NUM_PIXELS - 1)
elif peak > 0:
peak = peak - 1
if peak > 0:
pixels[int(peak)] = PEAK_COLOR
pixels.show()