Created
October 23, 2023 18:18
-
-
Save BenjaminSantiago/204a98e9da8d0c5cf4ca3e7eb6f76b52 to your computer and use it in GitHub Desktop.
SOUND METER (Annotated)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#importz | |
#----------------------------------------------------------------- | |
import array | |
import math | |
import audiobusio | |
import board | |
from adafruit_circuitplayground.express import cpx | |
#----------------------------------------------------------------- | |
#functions | |
#mathy stuff | |
#----------------------------------------------------------------- | |
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, 0.630957) * (output_max - output_min) | |
def normalized_rms(values): | |
minbuf = int(sum(values) / len(values)) | |
return math.sqrt(sum(float(sample - minbuf) * | |
(sample - minbuf) for sample in values) / len(values)) | |
#----------------------------------------------------------------- | |
#----------------------------------------------------------------- | |
# For CircuitPython 2.x: | |
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, | |
frequency=16000, bit_depth=16) | |
# For CircuitPython 3.0 and up, "frequency" is now called "sample_rate". | |
# Comment out the mic and frequency lines above and uncomment those lines below. | |
# mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, | |
# sample_rate=16000, bit_depth=16) | |
samples = array.array('H', [0] * 160) | |
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 | |
#----------------------------------------------------------------- | |
#MAIN LOOP | |
#----------------------------------------------------------------- | |
while True: | |
#THIS CODE "RECORDS" or takes in sound | |
#---------------------------------------- | |
#record something | |
mic.record(samples, len(samples)) | |
#normalize the values | |
magnitude = normalized_rms(samples) | |
#show us what is happening | |
#(this syntax means we can use the plotter in mu) | |
print((magnitude,)) | |
#---------------------------------------- | |
#convert audio to linear values | |
""" | |
audio volume is in a unit called a decibel | |
decibels scale logarithmically rather than linearly | |
This is to make more intrinsic sense to | |
how humans perceive audio | |
(when we perceive something as "twice as loud" as it was before | |
the actual volume of that sound was more than twice as loud as it | |
was before. Logarithmic values are helpful for aligning with | |
our perception of reality, however this means we must | |
CONVERT the values to scale linearly. This code does that) | |
""" | |
c = log_scale(constrain(magnitude, input_floor, input_ceiling), | |
input_floor, input_ceiling, 0, 10) | |
#clear everything out each loop through | |
cpx.pixels.fill((0, 0, 0)) | |
#go through all pixels | |
for i in range(10): | |
#if the current pixel is not the value we are trying to | |
#represent, show the color | |
if i < c: | |
#make the pixel "redness" proportional | |
#to the curent value of i | |
cpx.pixels[i] = (i * (255 // 10), 50, 0) | |
#now we're finding the peak or highest value | |
#peak starts at 0 (see above) | |
# this looks like it is needed to figure out, | |
# how many pixels to light up | |
if c >= peak: | |
peak = min(c, 10 - 1) | |
elif peak > 0: | |
peak = peak - 1 | |
if peak > 0: | |
cpx.pixels[int(peak)] = (80, 0, 255) | |
#I was trying to ascertain if this is a deprecated | |
#(old) function, not sure exactly happens here. | |
cpx.pixels.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment