Back to: Multiplier Event Luxembourg
import array import audiobusio import board import math import time from adafruit_circuitplayground import cp # Define color of the peak pixel. PEAK_COLOR = (80, 0, 255) # Exponential scaling factor. # Should probably be in range -10 .. 10 to be reasonable. # CURVE is used to make # - the readings more or less sensitive and # - the display more or less jumpy. CURVE = 10 SCALE_EXPONENT = math.pow(10, CURVE * -0.1) # Define the number of samples that should be read at once. NUM_SAMPLES = 160 # Return a normalized root mean square (RMS) average. # Calculate the RMS value to measure the average loudness of a sound waveform. def normalized_rms(samples): mean = sum(samples) / len(samples) return math.sqrt(sum((sample - mean) * (sample - mean) for sample in samples) / len(samples)) # Configure the microphone object and the samples variable. mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate = 16000, bit_depth = 16) samples = array.array('H', [0] * NUM_SAMPLES) # Initialize the mic object. Assume that it is quiet when started. mic.record(samples, len(samples)) # Set the lowest expected level, plus a slight increase. input_floor = normalized_rms(samples) + 10 # OR # Use a fixed floor #input_floor = 50 # Lower sensitivity number means more sensitive; more NeoPixels will light up with less sound. # If the meter seems too sensitive, the sensitivity number can be adjusted. sensitivity = 500 input_ceiling = input_floor + sensitivity peak = 0 # Loop forever while True: # Sound samples are taken by the mic object. mic.record(samples, len(samples)) # Use the normalized RMS to calculate the average of a set of samples, namely the magnitude of this set of samples. magnitude = normalized_rms(samples) # Compute scaled logarithmic reading in the range 0 to 10, # as 10 NeoPixels are built into the Circuit Playground Express board. constrain = max(input_floor, min(magnitude, input_ceiling)) scale = math.pow((constrain - input_floor) / (input_ceiling - input_floor), SCALE_EXPONENT) * 10 # The pixels below the scaled and interpolated magnitude are lit up. cp.pixels.fill((0, 0, 0)) for p in range(10): if p < scale: cp.pixels[p] = (200, p * (255 // 10), 0) # Light up the peak pixel and animate it slowly dropping. if scale >= peak: peak = min(scale, 9) elif peak > 0: peak = peak - 1 if peak > 0: cp.pixels[int(peak)] = PEAK_COLOR # Depending on the switch, write to # * the serial console (if True, i.e. left), or to # * the CircuitPython storage (if False, i.e. right). if cp.switch: print("The magnitude of the set of samples is", magnitude) print( (magnitude, ) ) else: f = open("magnitude.csv", "a") f.write(repr(magnitude) + "\n") f.close()
import storage from adafruit_circuitplayground import cp storage.remount("/", readonly=cp.switch)