18
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

はじめに

自宅不在時の来客を通知してくれるシステムが欲しいなーと思い実装することにしました。
(コロナの影響で外出の機会が極端に減ったが...)

検知方法は、家に設置しているラズパイにマイクを接続し、生活音の中からチャイム音を検出しようと考えています。
また、使用言語はpython、パッケージPyAudioを使って生活音を取得します。

本記事では、PyAudioを使ってチャイム音を取得し、FFTでチャイム音の特徴を抽出するところまで記載します。

実装

ラズパイでいきなり動かす前に、macbookでPyAudio使ってみました。
その際の手順、コードを記載します。

環境

$ brew --version
Homebrew 2.2.15-35-g11f50cf
$ pip3 -V
pip 19.0.3
$ python3 -V
Python 3.7.3

PyAudioのインストール

pyaudioのインストールにportaudioが必要なため、先にportaudioをインストールします。

$ brew install portaudio
$ pip3 install pyaudio

接続中の入力デバイスの確認

PyAudioを使う際に、入力デバイス(マイク)の情報を設定する必要があります。
下記のコードで入力デバイスの情報を確認できます。

check_audio_device.py
import pyaudio

audio = pyaudio.PyAudio()
for i in range(audio.get_device_count()):
    print(audio.get_device_info_by_index(i))

↓実行した結果

$ python3 check_audio_device.py 
{'index': 0, 'structVersion': 2, 'name': 'Built-in Microphone', 'hostApi': 0, 'maxInputChannels': 2, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.0029478458049886623, 'defaultLowOutputLatency': 0.01, 'defaultHighInputLatency': 0.01310657596371882, 'defaultHighOutputLatency': 0.1, 'defaultSampleRate': 44100.0}
{'index': 1, 'structVersion': 2, 'name': 'Built-in Output', 'hostApi': 0, 'maxInputChannels': 0, 'maxOutputChannels': 2, 'defaultLowInputLatency': 0.01, 'defaultLowOutputLatency': 0.010929705215419501, 'defaultHighInputLatency': 0.1, 'defaultHighOutputLatency': 0.02108843537414966, 'defaultSampleRate': 44100.0}
{'index': 2, 'structVersion': 2, 'name': 'USB PnP Audio Device', 'hostApi': 0, 'maxInputChannels': 1, 'maxOutputChannels': 0, 'defaultLowInputLatency': 0.0057083333333333335, 'defaultLowOutputLatency': 0.01, 'defaultHighInputLatency': 0.015041666666666667, 'defaultHighOutputLatency': 0.1, 'defaultSampleRate': 48000.0}
seakanoMacBook-Pro:chime_recognition seaka$ 

今回はUSB接続した(ラズパイでも使用する)マイクで音声データを取得するため、indexが2のデバイス情報を参照します。

  • index ... 2
  • maxInputChannels ... 1
  • defaultSampleRate ... 48000.0

使用するデバイスの情報を取得したので、早速コードを書いてみましょう。
下記のコードを実行すると、音声データを取得しはじめます。
Ctrl+Cで停止させると、実行開始から終了までの音声データをプロットし、その後FFTした結果が表示されます。
(横軸は時間(秒)、縦軸は振幅)

audio_plot.py
import pyaudio
import numpy as np
import matplotlib.pyplot as plt
from scipy.fftpack import fft

FORMAT      = pyaudio.paInt16
CHANNELS    = 1         # maxInputChannels
RATE        = 48000     # defaultSampleRate
CHUNK       = 1024
IDINDEX     = 2         # index

count = 0
x = []
y = []

audio = pyaudio.PyAudio()
stream = audio.open(
     format = FORMAT
    ,channels = CHANNELS
    ,rate = RATE
    ,frames_per_buffer=CHUNK
    ,input=True
    ,output=False
)

while stream.is_active():
    try:
        input = stream.read(CHUNK, exception_on_overflow=False)
        ndarray = np.frombuffer(input, dtype='int16')
        for i in ndarray:
            count = count + 1
            data = i.item()
            seconds = count/RATE    # 経過時間を取得
            x.append(seconds)
            y.append(data)
            # print(seconds, data)
    except KeyboardInterrupt:
        break

plt.plot(x, y)
plt.show()

freq = np.linspace(0, RATE, count)
yf = np.abs(fft(y))
yf = yf * yf
plt.plot(freq[0:int(count/2)], yf[0:int(count/2)])
plt.show()


stream.stop_stream()
stream.close()
stream.terminate()

チャンネル数やサンプリング数を正確に設定しないと、エラーが発生するため注意が必要です。
私はここで少しつまづきました。

作成後、テストで1000Hzの音声を流してプロット結果を表示してみました。以下がその結果です。

図1. 1000Hz音声の波形
スクリーンショット 2020-12-13 15.47.19.png

図1より音声を取得できてそうなことがわかります。

図2. 1000Hz音声をFFTした結果
スクリーンショット 2020-12-13 15.48.37.png

図2より、1000Hz(横軸)らへんでピークが立っていることが分かります。正常にFFTできてそうです。

次に、チャイム音を取得してプロットしてみました。

図3. チャイム音の波形
スクリーンショット 2020-12-13 15.52.29.png

チャイムぽい波形が出てます。

図4. チャイム音をFFTした結果
スクリーンショット 2020-12-13 15.53.19.png

ちょっと見にくいですが、1500Hz、2000Hz、3500Hzらへんでピークが立っています。
この特徴を使えば、生活音からチャイム音を抽出できそうです。

今後

本記事では、ラズパイとマイクを使って、生活音からチャイム音を抽出する方法について書きました。
次は、今回わかった特徴を元に、実際にチャイム検知システムを作りたいと思います。
最終的には、チャイム検出→Line等で通知まで実装する予定です。

18
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?