code.py
 1  # SPDX-FileCopyrightText: 2018 Kattni Rembor for Adafruit Industries
 2  #
 3  # SPDX-License-Identifier: MIT
 4  
 5  import array
 6  import math
 7  import audiobusio
 8  import board
 9  from adafruit_circuitplayground.express import cpx
10  
11  
12  def constrain(value, floor, ceiling):
13      return max(floor, min(value, ceiling))
14  
15  
16  def log_scale(input_value, input_min, input_max, output_min, output_max):
17      normalized_input_value = (input_value - input_min) / (input_max - input_min)
18      return output_min + math.pow(normalized_input_value, 0.630957) * (output_max - output_min)
19  
20  
21  def normalized_rms(values):
22      minbuf = int(sum(values) / len(values))
23      return math.sqrt(sum(float(sample - minbuf) *
24                           (sample - minbuf) for sample in values) / len(values))
25  
26  
27  # For CircuitPython 2.x:
28  mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
29                         frequency=16000, bit_depth=16)
30  # For CircuitPython 3.0 and up, "frequency" is now called "sample_rate".
31  # Comment out the mic and frequency lines above and uncomment those lines below.
32  # mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA,
33  #                        sample_rate=16000, bit_depth=16)
34  
35  
36  samples = array.array('H', [0] * 160)
37  mic.record(samples, len(samples))
38  input_floor = normalized_rms(samples) + 10
39  
40  # Lower number means more sensitive - more LEDs will light up with less sound.
41  sensitivity = 500
42  input_ceiling = input_floor + sensitivity
43  
44  peak = 0
45  while True:
46      mic.record(samples, len(samples))
47      magnitude = normalized_rms(samples)
48      print((magnitude,))
49  
50      c = log_scale(constrain(magnitude, input_floor, input_ceiling),
51                    input_floor, input_ceiling, 0, 10)
52  
53      cpx.pixels.fill((0, 0, 0))
54      for i in range(10):
55          if i < c:
56              cpx.pixels[i] = (i * (255 // 10), 50, 0)
57          if c >= peak:
58              peak = min(c, 10 - 1)
59          elif peak > 0:
60              peak = peak - 1
61          if peak > 0:
62              cpx.pixels[int(peak)] = (80, 0, 255)
63      cpx.pixels.show()