はじめに
以前カムロボを PWM で無理やり R2D2 っぽく喋らせるということをやってみたが,これは単純な PWM 出力をそのままスピーカーへ出力していた.
今回はもう少しまともな音声を再生できるように PWM audio を設定してみる.
調査
御託はすっ飛ばしてとにかく設定方法を教えてくれという人は次のセクションに飛んでどうぞ.
RPI Model B 系の音声出力方法は HDMI か 3.5mm ジャックのアナログ出力の 2 択だったが,RPI Zero では 3.5mm ジャックが実装されていない.RPI Zeroで音声を再生する方法はいくつかあるが,簡単な順で選択肢は概ねこんなところ.
- HDMI 接続先から音声出力する
- USB で DAC を使う
- HAT で DAC を使う
- ノイズ除去フィルタを用意して,PWM Audio を設定する
HDMI 出力は一番簡単な音声出力方法.RPI をデスクトップ PC のように利用する場合は,ディスプレイから音声出力すればいい.しかし,小型の LCD や OLED などの HDMI 接続以外の表示器を使う場合はこの手段は使えない.
USB DAC は通常の USB デバイスとして扱えるので,これも比較的簡単に音声出力を実現できる.ただし,RPI Zero では microUSB ポートが 1 つしかない.昨今流通している USB DAC は Type-A か Type-C なので microUSB に合わせてアダプターが必要になる.他の用途で USB を利用する場合はハブも必要になってくる.せっかくコンパクトなRPI Zeroの周りがごちゃごちゃするのは頂けない.ちなみにアダプターはめちゃくちゃ小さくて安価なこれがおすすめ.
HAT DAC は RaspberryPi.com でもいくつか紹介されているが,RPI Zero ザイズの HAT は Codec Zero として紹介されている./boot/config.txt の設定変更や制御ソフトの導入の手間はあるが,比較的簡単に 3.5mm ジャックを追加できる.ただし,他の HAT も使用したい場合は配線が面倒なことになるかもしれない.Amazon で HAT DAC 買うならこんなところか.1000 円前後と値段的には USB DAC と同じくらい.
そして問題の PWM Audio.よく参照されている Adafruit のページでは,2 種類の方法が紹介されている.1 つは DTO(Device Tree Overlay) で PWM 出力ピンを設定する方法.もう 1 つは wiringPi を使って手動で PWM 出力ピンを設定する方法.wiringPi の方は試してないが,DTO の方はこの説明の通り /boot/config.txt を設定しても音声出力デバイスとしてに認識されなかった.これに関しては後述の解決策が見つかったので良いとして,このまま GPIO の出力をスピーカーにつなぐとノイズだらけで大変なことになる.自前でフィルタ回路も用意する必要がある.必要に応じてアンプも用意する必要がある.
PWM audio 設定
環境は次の通り.
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
$ uname -r
5.15.61+
$ cat /sys/firmware/devicetree/base/model
Raspberry Pi Zero W Rev 1.1
config.txt 設定
config.txt の末尾に次の行を追加して再起動する.
dtoverlay=audremap,pins_12_13
ちなみに設定内容は次の通り.Adafruit の説明では pwm-2chan を設定するよう記載されている.pwm-2chan を設定するとたしかに GPIO の PWM 出力ピンとして設定されるが,音声出力デバイスとして alsa が認識できない.
Name: audremap
Info: Switches PWM sound output to GPIOs on the 40-pin header
Load: dtoverlay=audremap,<param>=<val>
Params: swap_lr Reverse the channel allocation, which will also
swap the audio jack outputs (default off)
enable_jack Don't switch off the audio jack output
(default off)
pins_12_13 Select GPIOs 12 & 13 (default)
pins_18_19 Select GPIOs 18 & 19
Name: pwm-2chan
Info: Configures both PWM channels
Legal pin,function combinations for each channel:
PWM0: 12,4(Alt0) 18,2(Alt5) 40,4(Alt0) 52,5(Alt1)
PWM1: 13,4(Alt0) 19,2(Alt5) 41,4(Alt0) 45,4(Alt0) 53,5(Alt1)
N.B.:
1) Pin 18 is the only one available on all platforms, and
it is the one used by the I2S audio interface.
Pins 12 and 13 might be better choices on an A+, B+ or Pi2.
2) The onboard analogue audio output uses both PWM channels.
3) So be careful mixing audio and PWM.
4) Currently the clock must have been enabled and configured
by other means.
Load: dtoverlay=pwm-2chan,<param>=<val>
Params: pin Output pin (default 18) - see table
pin2 Output pin for other channel (default 19)
func Pin function (default 2 = Alt5) - see above
func2 Function for pin2 (default 2 = Alt5)
clock PWM clock frequency (informational)
再起動後は出力デバイスとして認識されるので,~/.asoundrc で出力先として設定する.
$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 2: vc4hdmi [vc4-hdmi], device 0: MAI PCM i2s-hifi-0 [MAI PCM i2s-hifi-0]
Subdevices: 1/1
Subdevice #0: subdevice #0
$ cat .asoundrc
pcm.!default {
type asym
playback.pcm {
type plug
slave.pcm "output"
}
capture.pcm {
type plug
slave.pcm "input"
}
}
pcm.output {
type hw
card 0 # 出力先に card 0 を指定
}
ctl.!default {
type hw
card 0
}
この状態でスピーカーに接続すれば,一応音声が出力できるがノイズがひどい.試したい方はこちらをどうぞ.
# どちらでもどうぞ
$ aplay /usr/share/sounds/alsa/Front_Center.wav
$ speaker-test -t sine -p 32
音鳴らした後はチュルチュル音が鳴り止まなくてつらい.
フィルタ回路作成
このままだとノイズがひどいので次のページを参考に RC フィルタを作る.
必要なものは次の通り.L か R の片方だけでいいなら部品数は半分で済む.
- 抵抗 150Ω 2個
- 抵抗 270Ω 2個
- コンデンサ 33nF 2個
- コンデンサ 10uF 2個
実態配線図は次の通り.
フィルタの効果はこんな感じ.よく聞けばまだ完全にノイズは消えてないが,実用レベルで問題なし.
おわりに
思いの外簡単に実装できた.Adafruit のページを見て挫折していた人は参考にどうぞ.
抵抗 2 つとコンデンサ 2 つ程度ならまだカムロボの頭に入りそう.
コメント