Circuit Playground Express の各種機能を試す(音声周り)
マイクを使って音をサンプリングする
ということで、音のサンプリングを実行してみた。
具体的には、音量を検出して、10 個の LED (Pixcel) を段階的に光らせた。
前回のライブラリも利用し、
追加で simpleio
を入れた。
実際のコードはこんな感じ
import board import math import array import audiobusio import simpleio from adafruit_circuitplayground import cp def rms(value): # 音は波なので、波の振れ幅 = 音量。 # 音の振幅の平均値(ここからの振れ幅=音量) dc_offset = int(sum(value) / len(value)) # (1 サンプル毎の音量) の二乗和 (2 乗すると、マイナスがなくなるため) s = sum((i - dc_offset) ** 2 for i in value) # 二乗平均 = 分散 m = s / len(value) # 標準偏差(二乗平均平方根 : root mean square) r = math.sqrt(m) return r cp.pixels.auto_write = False cp.pixels.brightness = 0.3 mic = audiobusio.PDMIn( board.MICROPHONE_CLOCK, board.MICROPHONE_DATA, sample_rate=16000, # サンプリングビットレート 16kHz bit_depth=16 # ビット深度 0 - 65535 の値 ) # サンプリングデータを入れるための空の 配列(長さ 80 のリスト)を作る(H は型コード) # 16kHz, 16000 / 80 = 0.005 sec 分のサンプリング samples = array.array('H', [0] * 80) # samples リストの長さぶんの録音をする mic.record(samples, len(samples)) while True: mic.record(samples, len(samples)) magnitude = rms(samples) i = int(simpleio.map_range(int(magnitude), 0, 1000, 0, 9)) # 0-1000 までの値を 0-9 の値にマップする for p in range(10): cp.pixels[p] = (0, 5, 0) if p < i + 1 else (0, 0, 0) cp.pixels.show()
すると、こんな感じの光り方をする。
近くで「あー」と声を出しながら撮影
咳き込むと一瞬で上がるのだけど、その瞬間を取るわけにも行かず…大音量で音楽聞く訳にも行かなかったので断念…
スピーカーで音を鳴らす
from adafruit_circuitplayground import cp while True: if cp.button_a: cp.start_tone(262) elif cp.button_b: cp.start_tone(294) else: cp.stop_tone()
音声の公開は難しいのでコードだけ。
ボタンを押している間だけビープ音がなります。
数字は周波数。
ちなみにトーンは、秒指定で再生もできるので
from adafruit_circuitplayground import cp cp.play_tone(262, 1) cp.play_tone(294, 1)
こんなんもできた