Raspberry Pi で録音と再生をしてみます。
準備
Linuxでオーディオデバイスを扱う場合、ALSAとPulseAudioが使えます。
[Audio device]-[ALSA]-[PulseAudio]-[Application]
の関係があるので、色々と例外はあるようですが、ここではPulseAudioを使うことにします。そのあたりの詳細は
http://mickey-happygolucky.hatenablog.com/entry/2015/04/04/105512
https://cpplover.blogspot.com/2012/03/pulseaudio.html
を参照ください。
Raspberry Pi 3にはマイク端子がないので、USBマイクか、USBオーディオインターフェイスを使ってマイクを接続します。
録音と再生
マイクを接続した後、デバイスの番号を探します。
$ pactl list sources
今回試した環境では、
Source #0
State: SUSPENDED
Name: alsa_output.usb-0d8c_C-Media_USB_Headphone_Set-00-Set.analog-stereo.monitor
Description: Monitor of Audio Adapter アナログステレオ
<以下略>
Source #1
State: SUSPENDED
Name: alsa_input.usb-0d8c_C-Media_USB_Headphone_Set-00-Set.analog-mono
Description: Audio Adapter アナログモノ
<以下略>
Source #2
State: SUSPENDED
Name: alsa_output.1.analog-stereo.monitor
Description: Monitor of bcm2835 ALSA アナログステレオ
<以下略>
と出力されました。USB接続のマイクは、Source #1が該当するので、マイクから録音するには
$ parecord -d 1 test.wav
とします。
録音できていることを確認するには、
$ paplay -d 0 test.wav
とします。paplayで指定するデバイス番号は、
$ pactl list sinks
で調べます。読み方はsourcesの場合と同様です。
デバイス番号を毎回指定したくないときは、スピーカの場合は、
$ pactl set-default-sink [デバイス番号]
で、マイクの場合は、
$ pactl set-default-source [デバイス番号]
でデフォルトで使うデバイスを指定できます。
別のPCのオーディオデバイスの利用
PulseAudioはネットワーク越しのオーディオデバイスも扱えます。
そこで今回は、Windows PCにつながったスピーカやマイクを使う方法を試してみます。
まず、pulseaudio-1.1のWindows用バイナリをどこかから入手して、各種設定をします。バイナリの入手と設定は
https://vogel.at.webry.info/201711/article_9.html
が参考になります。
今回試すWindows側の default.pa は
load-module module-waveout
load-module module-native-protocol-tcp auth-ip-acl=192.168.0.0/16
としました。
Windowsのコマンドプロンプトから
pulseaudio -F ..\default.pa --exit-idle-time=60000
で起動しておいて、Raspberry Piから
$ paplay -s 192.168.0.1 test.wav
とすると、Windows側から再生されます。WindowsのIPアドレスが192.168.0.1だとしています。
同様に録音も出来ます。
$ parecord -s 192.168.0.1 test.wav
GStreamer
PulseAudioだけだと録音できるだけですが、GStreamer (
https://gstreamer.freedesktop.org/) を経由すると色々遊べます。
まずは、マイク入力を直接スピーカに流してみます。
$ gst-launch-1.0 pulsesrc device=1 ! pulsesink device=0
デバイス番号は、さきほどpactlで調べた番号と同じです。Ctrl+Cで停止できます。
ちょっと遅延しますが、マイクで録音した音がスピーカから流れます。
deviceの番号については、デバイスが存在していれば間違えてもエラーは起きません。代わりに、全くの無音(振幅0)が録音されます。何も音が出ない場合はデバイス番号を間違っていないか、まずはチェックしましょう。
さて、ただ流すだけでは面白くないので、エコーをかけてみます。
$ gst-launch-1.0 pulsesrc device=1 \
! audioecho delay=300000000 intensity=0.5 feedback=0.5 \
! pulsesink device=0
delayの単位はナノ秒なので、この設定では300ミリ秒遅延のエコーになります。詳細は、
$ gst-inspect-1.0 audioecho
を実行して、Element Properties 部分の説明を読んでみてください。
今度は、ローパスフィルタを試してみます。
gst-launch-1.0 pulsesrc device=1 ! audiowsinclimit mode=low-pass cutoff=100 ! pulsesink device=0
cutoffの単位はHzなので、100Hz以下を通過させるフィルタになっています。
声がくぐもった感じになります。
せっかくなので、ハイパスフィルタも試してみます。
$ gst-launch-1.0 pulsesrc device=1 ! audiowsinclimit mode=high-pass cutoff=2000 ! pulsesink device=0
低い音が弱くなります。
wav形式で録音するには、
$ gst-launch-1.0 pulsesrc device=1 ! wavenc ! filesink location="test.wav"
とします。これを使うと、加工した音声も簡単に記録できます。
同様に、録音したwavを再生するには、
$ gst-launch-1.0 filesrc location=test.wav ! decodebin ! pulsesink device=0
とします。
もちろん、GStreamerを使うときもPulseAudioのサーバーに接続できます。
$ gst-launch-1.0 pulsesrc server=192.168.0.1 ! pulsesink server=192.168.0.1
GStreamerの不具合
GStreamerのpulsesrc Ver.1.8.3には不具合があり、どう設定しても無音しか記録できません。
古いバージョン(例えば、1.4.4)または新しいバージョン(1.14.2)では動作します。
不具合修正の場所とコミットメッセージは
https://cgit.freedesktop.org/gstreamer/gst-plugins-good/commit/ext/pulse/pulsesrc.c?id=4833f02e47d5b7fc4284517e92d5976b20188a4a
にあります。2016年9月25日にコミットされています。
ブランチ1.8のログ
https://cgit.freedesktop.org/gstreamer/gst-plugins-good/log/?h=1.8
を見ると、1.8.3のリリースの直後に修正されていることがわかります。
tagが付いている範囲だと、Release 1.9.2とRelease 1.9.90の間で修正されています。
Ubuntu 16.04 LTSを使っている人は気をつけましょう。
デフォルトでインストールされるGStreamerがこの不具合を踏んでいます。