code.py
1 # SPDX-FileCopyrightText: 2019 Carter Nelson for Adafruit Industries 2 # 3 # SPDX-License-Identifier: MIT 4 5 import time 6 import array 7 import board 8 import audiobusio 9 10 #---| User Configuration |--------------------------- 11 SAMPLERATE = 16000 12 SAMPLES = 1024 13 THRESHOLD = 100 14 MIN_DELTAS = 5 15 DELAY = 0.2 16 17 # octave = 1 2 3 4 5 6 7 8 18 NOTES = { "C" : (33, 65, 131, 262, 523, 1047, 2093, 4186), 19 "D" : (37, 73, 147, 294, 587, 1175, 2349, 4699), 20 "E" : (41, 82, 165, 330, 659, 1319, 2637, 5274), 21 "F" : (44, 87, 175, 349, 698, 1397, 2794, 5588), 22 "G" : (49, 98, 196, 392, 785, 1568, 3136, 6272), 23 "A" : (55, 110, 220, 440, 880, 1760, 3520, 7040), 24 "B" : (62, 123, 247, 494, 988, 1976, 3951, 7902)} 25 #---------------------------------------------------- 26 27 # Create a buffer to record into 28 samples = array.array('H', [0] * SAMPLES) 29 30 # Setup the mic input 31 mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, 32 board.MICROPHONE_DATA, 33 sample_rate=SAMPLERATE, 34 bit_depth=16) 35 36 while True: 37 # Get raw mic data 38 mic.record(samples, SAMPLES) 39 40 # Compute DC offset (mean) and threshold level 41 mean = int(sum(samples) / len(samples) + 0.5) 42 threshold = mean + THRESHOLD 43 44 # Compute deltas between mean crossing points 45 # (this bit by Dan Halbert) 46 deltas = [] 47 last_xing_point = None 48 crossed_threshold = False 49 for i in range(SAMPLES-1): 50 sample = samples[i] 51 if sample > threshold: 52 crossed_threshold = True 53 if crossed_threshold and sample < mean: 54 if last_xing_point: 55 deltas.append(i - last_xing_point) 56 last_xing_point = i 57 crossed_threshold = False 58 59 # Try again if not enough deltas 60 if len(deltas) < MIN_DELTAS: 61 continue 62 63 # Average the deltas 64 mean = sum(deltas) / len(deltas) 65 66 # Compute frequency 67 freq = SAMPLERATE / mean 68 69 print("crossings: {} mean: {} freq: {} ".format(len(deltas), mean, freq)) 70 71 # Find corresponding note 72 for note in NOTES: 73 for octave, note_freq in enumerate(NOTES[note]): 74 if note_freq * 0.97 <= freq <= note_freq * 1.03: 75 print("-"*10) 76 print("NOTE = {}{}".format(note, octave + 1)) 77 print("-"*10) 78 79 time.sleep(DELAY)