Raspberry Pi 3、Python3を使ってマイクから取得した音をWaveファイルとして書き出す方法について説明します。今回は簡単な録音までを紹介しますが、発展として波形の可視化や合成、周波数の解析ができます。

なお、こちらの記事ではRaspberry Piの初期化やネットワーク接続が終わり、Raspberry Piのターミナル操作ができる状態になっていることを前提としております。

Raspberry Piのセットアップ

Raspberry Piにはオーディオ入力がないため、マイクを使う場合はUSBマイクやUSBオーディオ変換アダプタが必要です。記事の中ではPLUGABLE USB オーディオ変換アダプタと市販のコンデンサマイクを使用していますが、その他のUSBデバイスでも構いません。

USBマイクをRaspberry Piに接続し、ターミナルから以下のコマンドを実行します。

$ aplay -l

こちらのコマンドはOSが認識しているサウンドデバイスの一覧を表示します。次のような表示が確認できればデバイスを正しく認識できています。aplayコマンド自体は音源ファイルの再生などに使用されます。(詳細はこちら

card 1: Device [USB Audio Device], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0

 

ソフトウェアのインストール

Pythonでマイクから入力された信号を処理するために、ソフトウェアのインストール作業を行います。まずPython3をインストールします。

$ sudo apt-get update
$ sudo apt-get install python3.4-dev

次にPythonのパッケージマネージャであるpipをインストールします。今回インストールしたPythobn3.4.2ではensurepipが使えないため、以下の方法でインストールしています。

$ wget https://bootstrap.pypa.io/get-pip.py
$ sudo python3.4 get-pip.py

マイクからの入力を受け取るためにPyaudioライブラリを使用します。PyaudioはクロスプラットフォームのオーディオAPIであるPortAudioのPythonバインディングです。そのため、PortAudio先にインストールしておく必要があります。

$ sudo apt-get install libportaudio2 libportaudiocpp0 portaudio19-dev

Pyaudioをインストールします。必要に応じてvirtualenvなどで環境を切り分けてください。グローバルにインストールする場合はsudoコマンドが必要になります。

$ pip install pyaudio

マイクから入力された音をwaveファイルに書き出す

最後に、簡単なPythonのスクリプトを作成してマイクからの入力をwaveファイルに書き出します。スクリプトの全体像は以下のようになります。

#-*-coding:utf-8-*-
#!/usr/bin/python
import pyaudio
import wave
import sys
import time

FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
CHUNK = 2**11
RECORD_SECONDS = 3

try:
    WAVE_FILE = sys.argv[1]
except:
    print('File name is required as an argument.')
    sys.exit(1)

audio = pyaudio.PyAudio()
frames = []

def callback(in_data, frame_count, time_info, status):
    frames.append(in_data)
    return(None, pyaudio.paContinue)

stream = audio.open(
    format=FORMAT,
    channels=CHANNELS,
    rate=RATE,
    input=True,
    input_device_index=0,
    frames_per_buffer=CHUNK,
    start=False,
    stream_callback=callback
)

if __name__ == '__main__':
    stream.start_stream()
    time.sleep(RECORD_SECONDS)

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

    wf = wave.open(WAVE_FILE, 'wb')
    wf.setnchannels(CHANNELS)
    wf.setsampwidth(audio.get_sample_size(FORMAT))
    wf.setframerate(RATE)
    wf.writeframes(b''.join(frames))
    wf.close()

マイクからの入力データは別スレッドとして実行されるcallback関数に渡されます。用意した配列にデータを追加していき、入力が終わった後連結してwaveファイルとして書き出しています。引数に保存するファイル名を指定して実行すると、3秒間音声を録音します。

$ python3.4 record.py sample.wav

録音した音声はRaspberry PiのオーディオアウトやGPIOで出力できます。

 

XSHELLは他にもRaspberryPiで電子ペーパーを動かしたり、音声の方向測位が出来るモジュールを試したり、RaspberryPiを使った様々な開発例をサンプルコード付きでご紹介しています。

RaspberryPiに興味をお持ちの方は是非そちらも合わせてご覧ください。

ブログの更新やイベントのお知らせは随時告知して参ります。ぜひ@xshell_incをフォローしてください。


isaax

IoT向けの継続的デリバリーサービス isaax (アイザックス) isaaxを使えば1アクションで数百・数千のデバイスをアップデートできます。 IoTシステムの構築をより簡単にします。