/ examples / circuitplayground_sound_meter.py
circuitplayground_sound_meter.py
 1  """This example uses the sound sensor, located next to the picture of the ear on your board, to
 2  light up the NeoPixels as a sound meter. Try talking to your CPX or clapping, etc, to see the
 3  NeoPixels light up!"""
 4  import array
 5  import math
 6  import audiobusio
 7  import board
 8  from adafruit_circuitplayground.express import cpx
 9  
10  
11  def constrain(value, floor, ceiling):
12      return max(floor, min(value, ceiling))
13  
14  
15  def log_scale(input_value, input_min, input_max, output_min, output_max):
16      normalized_input_value = (input_value - input_min) / (input_max - input_min)
17      return output_min + math.pow(normalized_input_value, 0.630957) * (output_max - output_min)
18  
19  
20  def normalized_rms(values):
21      minbuf = int(sum(values) / len(values))
22      return math.sqrt(sum(float(sample - minbuf) *
23                           (sample - minbuf) for sample in values) / len(values))
24  
25  
26  mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
27                         sample_rate=16000, bit_depth=16)
28  
29  samples = array.array('H', [0] * 160)
30  mic.record(samples, len(samples))
31  input_floor = normalized_rms(samples) + 10
32  
33  # Lower number means more sensitive - more LEDs will light up with less sound.
34  sensitivity = 500
35  input_ceiling = input_floor + sensitivity
36  
37  peak = 0
38  while True:
39      mic.record(samples, len(samples))
40      magnitude = normalized_rms(samples)
41      print((magnitude,))
42  
43      c = log_scale(constrain(magnitude, input_floor, input_ceiling),
44                    input_floor, input_ceiling, 0, 10)
45  
46      cpx.pixels.fill((0, 0, 0))
47      for i in range(10):
48          if i < c:
49              cpx.pixels[i] = (i * (255 // 10), 50, 0)
50          if c >= peak:
51              peak = min(c, 10 - 1)
52          elif peak > 0:
53              peak = peak - 1
54          if peak > 0:
55              cpx.pixels[int(peak)] = (80, 0, 255)
56      cpx.pixels.show()