2018年8月5日日曜日

Raspberry Pi で録音と再生

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がこの不具合を踏んでいます。

0 件のコメント :