]>
vault307.fbx.one Git - Sensory_Wall.git/blob - cpxtest.py
1 # SPDX-FileCopyrightText: 2017 Dan Halbert for Adafruit Industries
2 # SPDX-FileCopyrightText: 2017 Tony DiCola for Adafruit Industries
3 # SPDX-FileCopyrightText: 2017 Kattni Rembor for Adafruit Industries
5 # SPDX-License-Identifier: MIT
7 # The MIT License (MIT)
9 # Copyright (c) 2017 Dan Halbert for Adafruit Industries
10 # Copyright (c) 2017 Kattni Rembor, Tony DiCola for Adafruit Industries
12 # Permission is hereby granted, free of charge, to any person obtaining a copy
13 # of this software and associated documentation files (the "Software"), to deal
14 # in the Software without restriction, including without limitation the rights
15 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 # copies of the Software, and to permit persons to whom the Software is
17 # furnished to do so, subject to the following conditions:
19 # The above copyright notice and this permission notice shall be included in
20 # all copies or substantial portions of the Software.
22 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30 # Circuit Playground Sound Meter
38 # Color of the peak pixel.
39 PEAK_COLOR
= (100, 0, 255)
40 # Number of total pixels - 10 build into Circuit Playground
43 # Exponential scaling factor.
44 # Should probably be in range -10 .. 10 to be reasonable.
46 SCALE_EXPONENT
= math
.pow(10, CURVE
* -0.1)
48 # Number of samples to read at once.
52 # Restrict value to be between floor and ceiling.
53 def constrain(value
, floor
, ceiling
):
54 return max(floor
, min(value
, ceiling
))
57 # Scale input_value between output_min and output_max, exponentially.
58 def log_scale(input_value
, input_min
, input_max
, output_min
, output_max
):
59 normalized_input_value
= (input_value
- input_min
) / \
60 (input_max
- input_min
)
62 math
.pow(normalized_input_value
, SCALE_EXPONENT
) \
63 * (output_max
- output_min
)
66 # Remove DC bias before computing RMS.
67 def normalized_rms(values
):
68 minbuf
= int(mean(values
))
70 float(sample
- minbuf
) * (sample
- minbuf
)
74 return math
.sqrt(samples_sum
/ len(values
))
78 return sum(values
) / len(values
)
81 def volume_color(volume
):
82 return 200, volume
* (255 // NUM_PIXELS
), 0
87 # Set up NeoPixels and turn them all off.
88 pixels
= neopixel
.NeoPixel(board
.NEOPIXEL
, NUM_PIXELS
, brightness
=0.1, auto_write
=False)
92 mic
= audiobusio
.PDMIn(board
.MICROPHONE_CLOCK
, board
.MICROPHONE_DATA
,
93 sample_rate
=16000, bit_depth
=16)
95 # Record an initial sample to calibrate. Assume it's quiet when we start.
96 samples
= array
.array('H', [0] * NUM_SAMPLES
)
97 mic
.record(samples
, len(samples
))
98 # Set lowest level to expect, plus a little.
99 input_floor
= normalized_rms(samples
) + 10
100 # OR: used a fixed floor
103 # You might want to print the input_floor to help adjust other values.
106 # Corresponds to sensitivity: lower means more pixels light up with lower sound
107 # Adjust this as you see fit.
108 input_ceiling
= input_floor
+ 500
112 mic
.record(samples
, len(samples
))
113 magnitude
= normalized_rms(samples
)
114 # You might want to print this to see the values.
117 # Compute scaled logarithmic reading in the range 0 to NUM_PIXELS
118 c
= log_scale(constrain(magnitude
, input_floor
, input_ceiling
),
119 input_floor
, input_ceiling
, 0, NUM_PIXELS
)
121 # Light up pixels that are below the scaled and interpolated magnitude.
123 for i
in range(NUM_PIXELS
):
125 pixels
[i
] = volume_color(i
)
126 # Light up the peak pixel and animate it slowly dropping.
128 peak
= min(c
, NUM_PIXELS
- 1)
132 pixels
[int(peak
)] = PEAK_COLOR