Add sound reactive ear code
This commit is contained in:
parent
c66fb01228
commit
734f96ed10
1 changed files with 111 additions and 0 deletions
111
Sound_Reactive_Ears/code.py
Normal file
111
Sound_Reactive_Ears/code.py
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
"""
|
||||||
|
Circuit Playground Express sounds activated ears.
|
||||||
|
|
||||||
|
Adafruit invests time and resources providing this open source code.
|
||||||
|
Please support Adafruit and open source hardware by purchasing
|
||||||
|
products from Adafruit!
|
||||||
|
|
||||||
|
Written by Dave Astels for Adafruit Industries
|
||||||
|
Copyright (c) 2018 Adafruit Industries
|
||||||
|
Licensed under the MIT license.
|
||||||
|
|
||||||
|
All text above must be included in any redistribution.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import time
|
||||||
|
import math
|
||||||
|
import array
|
||||||
|
import board
|
||||||
|
import audiobusio
|
||||||
|
import simpleio
|
||||||
|
from adafruit_circuitplayground.express import cpx
|
||||||
|
|
||||||
|
# Exponential scaling factor.
|
||||||
|
# Should probably be in range -10 .. 10 to be reasonable.
|
||||||
|
CURVE = 2
|
||||||
|
SCALE_EXPONENT = math.pow(10, CURVE * -0.1)
|
||||||
|
|
||||||
|
# Number of samples to read at once.
|
||||||
|
NUM_SAMPLES = 90
|
||||||
|
|
||||||
|
# the trigger threshhold
|
||||||
|
THRESHOLD = 6
|
||||||
|
|
||||||
|
left_ear = simpleio.Servo(board.A1)
|
||||||
|
right_ear = simpleio.Servo(board.A2)
|
||||||
|
|
||||||
|
cpx.pixels.fill((0, 0, 0))
|
||||||
|
left_ear.angle = 0
|
||||||
|
right_ear.angle = 0
|
||||||
|
|
||||||
|
# Restrict value to be between floor and ceiling.
|
||||||
|
|
||||||
|
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)
|
||||||
|
|
||||||
|
|
||||||
|
# Remove DC bias before computing RMS.
|
||||||
|
|
||||||
|
def normalized_rms(values):
|
||||||
|
minbuf = int(mean(values))
|
||||||
|
samples_sum = sum(
|
||||||
|
float(sample - minbuf) * (sample - minbuf)
|
||||||
|
for sample in values
|
||||||
|
)
|
||||||
|
|
||||||
|
return math.sqrt(samples_sum / len(values))
|
||||||
|
|
||||||
|
|
||||||
|
def mean(values):
|
||||||
|
return sum(values) / len(values)
|
||||||
|
|
||||||
|
|
||||||
|
mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
|
||||||
|
sample_rate=16000, bit_depth=16)
|
||||||
|
|
||||||
|
|
||||||
|
# Record an initial sample to calibrate. Assume it's quiet when we start.
|
||||||
|
samples = array.array('H', [0] * NUM_SAMPLES)
|
||||||
|
mic.record(samples, len(samples))
|
||||||
|
# Set lowest level to expect, plus a little.
|
||||||
|
input_floor = normalized_rms(samples) + 10
|
||||||
|
|
||||||
|
# Corresponds to sensitivity: lower means ears perk up at lower volumes
|
||||||
|
# Adjust this as you see fit.
|
||||||
|
input_ceiling = input_floor + 750
|
||||||
|
|
||||||
|
ears_up = False
|
||||||
|
|
||||||
|
while True:
|
||||||
|
samples_read = mic.record(samples, len(samples))
|
||||||
|
if samples_read < NUM_SAMPLES:
|
||||||
|
print("MISSING SAMPLES, only: {0}".format(samples_read))
|
||||||
|
magnitude = normalized_rms(samples)
|
||||||
|
# You might want to print this to see the values.
|
||||||
|
# print(magnitude)
|
||||||
|
|
||||||
|
# Compute scaled logarithmic reading in the range 0 to 10
|
||||||
|
c = log_scale(constrain(magnitude, input_floor, input_ceiling),
|
||||||
|
input_floor, input_ceiling, 0, 10)
|
||||||
|
|
||||||
|
|
||||||
|
if c >= THRESHOLD and not ears_up:
|
||||||
|
ears_up = True
|
||||||
|
left_ear.angle = 90
|
||||||
|
right_ear.angle = 90
|
||||||
|
time.sleep(1.0)
|
||||||
|
elif c < THRESHOLD and ears_up:
|
||||||
|
ears_up = False
|
||||||
|
left_ear.angle = 0
|
||||||
|
right_ear.angle = 0
|
||||||
|
time.sleep(1.0)
|
||||||
|
else:
|
||||||
|
time.sleep(0.1)
|
||||||
Loading…
Reference in a new issue