|
| 1 | +import time |
| 2 | +import array |
| 3 | +import board |
| 4 | +import audiobusio |
| 5 | +import simpleio |
| 6 | +import neopixel |
| 7 | + |
| 8 | +#---| User Configuration |--------------------------- |
| 9 | +SAMPLERATE = 16000 |
| 10 | +SAMPLES = 1024 |
| 11 | +THRESHOLD = 100 |
| 12 | +MIN_DELTAS = 5 |
| 13 | +DELAY = 0.2 |
| 14 | + |
| 15 | +FREQ_LOW = 520 |
| 16 | +FREQ_HIGH = 990 |
| 17 | +COLORS = ( |
| 18 | + (0xFF, 0x00, 0x00) , # pixel 0 |
| 19 | + (0xFF, 0x71, 0x00) , # pixel 1 |
| 20 | + (0xFF, 0xE2, 0x00) , # pixel 2 |
| 21 | + (0xAA, 0xFF, 0x00) , # pixel 3 |
| 22 | + (0x38, 0xFF, 0x00) , # pixel 4 |
| 23 | + (0x00, 0xFF, 0x38) , # pixel 5 |
| 24 | + (0x00, 0xFF, 0xA9) , # pixel 6 |
| 25 | + (0x00, 0xE2, 0xFF) , # pixel 7 |
| 26 | + (0x00, 0x71, 0xFF) , # pixel 8 |
| 27 | + (0x00, 0x00, 0xFF) , # pixel 9 |
| 28 | +) |
| 29 | +#---------------------------------------------------- |
| 30 | + |
| 31 | +# Create a buffer to record into |
| 32 | +samples = array.array('H', [0] * SAMPLES) |
| 33 | + |
| 34 | +# Setup the mic input |
| 35 | +mic = audiobusio.PDMIn(board.MICROPHONE_CLOCK, |
| 36 | + board.MICROPHONE_DATA, |
| 37 | + sample_rate=SAMPLERATE, |
| 38 | + bit_depth=16) |
| 39 | + |
| 40 | +# Setup NeoPixels |
| 41 | +pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, auto_write=False) |
| 42 | + |
| 43 | +while True: |
| 44 | + # Get raw mic data |
| 45 | + mic.record(samples, SAMPLES) |
| 46 | + |
| 47 | + # Compute DC offset (mean) and threshold level |
| 48 | + mean = int(sum(samples) / len(samples) + 0.5) |
| 49 | + threshold = mean + THRESHOLD |
| 50 | + |
| 51 | + # Compute deltas between mean crossing points |
| 52 | + # (this bit by Dan Halbert) |
| 53 | + deltas = [] |
| 54 | + last_xing_point = None |
| 55 | + crossed_threshold = False |
| 56 | + for i in range(SAMPLES-1): |
| 57 | + sample = samples[i] |
| 58 | + if sample > threshold: |
| 59 | + crossed_threshold = True |
| 60 | + if crossed_threshold and sample < mean: |
| 61 | + if last_xing_point: |
| 62 | + deltas.append(i - last_xing_point) |
| 63 | + last_xing_point = i |
| 64 | + crossed_threshold = False |
| 65 | + |
| 66 | + # Try again if not enough deltas |
| 67 | + if len(deltas) < MIN_DELTAS: |
| 68 | + continue |
| 69 | + |
| 70 | + # Average the deltas |
| 71 | + mean = sum(deltas) / len(deltas) |
| 72 | + |
| 73 | + # Compute frequency |
| 74 | + freq = SAMPLERATE / mean |
| 75 | + |
| 76 | + print("crossings: {} mean: {} freq: {} ".format(len(deltas), mean, freq)) |
| 77 | + |
| 78 | + # Show on NeoPixels |
| 79 | + pixels.fill(0) |
| 80 | + pixel = round(simpleio.map_range(freq, FREQ_LOW, FREQ_HIGH, 0, 9)) |
| 81 | + pixels[pixel] = COLORS[pixel] |
| 82 | + pixels.show() |
| 83 | + |
| 84 | + time.sleep(DELAY) |
0 commit comments