2015年2月14日土曜日

[Linux][Fedora] PulseAudioでHDMIの5.1/7.1chを鳴らしたい!

概要

かなり前にも一度チャレンジして、鳴らすこと自体はできたんだけど弊害も大きそうだったんで放置してたPulseAudioでのHDMIマルチチャネル再生設定。
今回久しぶりにまたやってみようってことでいろいろとググったらうまく行ったので備忘録として記録しとこうかなと。

ぶっちゃけ海外の質問サイトに書いてあったことをそのまんま実行しただけなんだけどね!

前置き

実のところ、PulseAudioのデフォルト設定ではアナログデバイスについてはサラウンド設定をきちんとプロファイルとして拾ってくれるんですが、HDMIについてはなぜかプロファイルを拾ってこない。例えつないでいるアンプがマルチチャンネルに対応していようとも「そんなの関係ねぇ!」である。

ただ、それはPulseAudio(というかudev?)に自動検出させた場合。デバイスの自動検出を無効化して、搭載しているデバイスごとにチャンネル数とチャンネルマップを指定すればマルチチャンネル再生するHDMIデバイスを認識できる。
だがこの場合、2つの弊害がある。
  • プロファイルではないので「ステレオ」「5.1ch」「7.1ch」などを切り替えられない
  • 自動検出を殺しているので複数のサウンドデバイスを使っている場合は各々の設定を自分で行う必要がある
1つめの弊害については実用上それほど問題にならないと思うが、2つめは割と面倒。
USBオーディオI/Fなんかを使っている場合は割とデバイス番号が変わったりするのでその都度修正が必要に鳴る可能性があるのと、新しいサウンドデバイスを追加しても当然それも手動設定。このご時世それはあまりに嬉しくない。。。

自動認識させよう!

ってことで、デバイスは自動認識させつつ、HDMIのマルチチャネルをプロファイルとして認識させる方法を調査。
そしたらaudio - How do I configure PulseAudio for 7.1 Surround Sound over HDMI? - Unix & Linux Stack Exchangeなるページを見つけました。
ドンピシャです。この通りに実行してもらったら大丈夫だよ!って話なんですが、せっかくなので手順を書いておこうと思います。
ぶっちゃけ、そのまんまなぞってるので、英語でも平気だぜ!って人は以下は読まなくて平気です。

まずは下準備

上記Q&Aによると、どうも /usr/share/pulseaudio/alsa-mixier/profile-sets/extra-hdmi.conf にHDMIのサラウンド設定について記載があるようなんですね。
読んでみると確かにHDMIのサラウンドに関する記載が・・・。
[Mapping hdmi-stereo]
device-strings = hdmi:%f
description = Digital Stereo (HDMI)
paths-output = hdmi-output-0
channel-map = left,right
priority = 4
direction = output

[Mapping hdmi-surround]
description = Digital Surround 5.1 (HDMI)
device-strings = hdmi:%f
paths-output = hdmi-output-0
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
priority = 3
direction = output
上記は一部抜粋です。しっかりHDMIのマルチチャネル設定があることがわかります・・・。
だったらPulseAudioでも頑張ってくれよ・・・!

で、こちらのAnswerでも
このドキュメントによると、udev-basedによる自動認識を無効化して、全部を手動で設定しなくちゃいけないらしい
って書いてあります(超意訳)。
でも設定ファイルはあるようなので、そいじゃってことでudevの検出ルールを作っちゃおうぜ!ってのが今回の趣旨っぽい!

udevルールを作ろう!

残念ながらここの設定をすべて理解できているわけではないのですが、どうもPulseAudioのProfileとして先のドキュメントのようにサラウンド設定を追加しよう、ということみたいです。
具体的には下記のファイルを /etc/udev/rules.d/95-local-pulseaudio.rules に作成します。
ATTRS{vendor}=="0x1002", ATTRS{device}=="0x1714", ENV{PULSE_PROFILE_SET}="/etc/pulse/my-hdmi.conf"
なお、「ATTRS{vender}」と「ATTRS{devices}」の数値は各自の環境に合わせて変更ください。
自身のデバイスID等のチェックは lspci -nn コマンドにて確認できます。
$ lspci -nn | grep -i hdmi
00:01.1 Audio device [0403]: Advanced Micro Devices, Inc. [AMD/ATI] BeaverCreek HDMI Audio [Radeon HD 6500D and 6400G-6600G series] [1002:1714]
こちらに書いてある末尾の2組をそれぞれ転記すればOKっぽい!

で、次に
udevadm trigger -ssound
なるコマンドをroot権限で実行すれば先のudevルールが登録されるようです。きちんと登録されたかどうかについては
udevadm info --query=all --path /sys/class/sound/card0
なるコマンドを実行すれば確認できます。なお、card0 のカード番号についても各自の環境に合わせて確認ください。実行してみてHDMI端子の情報じゃなければ1なり2なりに変えてみて確認していけばそのうち当たります。きっちりと確認するなら aplay -L コマンドなどで確認ください。。。

上記コマンドを実行した際、
E: PULSE_PROFILE_SET=/etc/pulse/my-hdmi.conf
なる文字列が見つかればOKです。

これを確認できたらinitramfsを再生成して再起動後も適用されるようにします。
元のQ&AではUbuntuかDebianかなんかなので update-initramfs -u なるコマンドでinitramfsを再生成していますが、Fedoraの場合はdracutなのでさくっと生成します。
# cp /boot/initramfs-`uname -r`.img /boot/initramfs-`uname-r`.img.org
# dracut /boot/initramfs-`uname -r`.img `uname -r`
これでinitramfsが再生成されました。

HDMIサウンドデバイスのプロファイルを作るよ!

下記内容のファイルを /etc/pulse/my-hdmi.conf として生成します。
[General]
auto-profiles = yes

[Mapping hdmi-stereo]
device-strings = hdmi:%f
channel-map = front-left,front-right
description = Digital Stereo (HDMI)
priority = 4
direction = output
paths-output = hdmi-output-0

[Mapping hdmi-surround-40]
device-strings = hdmi:%f
channel-map = front-left,front-right,rear-left,rear-right
description = Digital Quadrophonic (HDMI)
priority = 1
direction = output
paths-output = hdmi-output-0

[Mapping hdmi-surround-51]
device-strings = hdmi:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe
description = Digital Surround 5.1 (HDMI)
priority = 2
direction = output
paths-output = hdmi-output-0

[Mapping hdmi-surround-71]
description = Digital Surround 7.1 (HDMI)
device-strings = hdmi:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
priority = 3
direction = output
paths-output = hdmi-output-0
なお、人によってはチャンネルマップがコレとは異なる場合が有ります。その場合は以下のサウンドチェックでチャンネルを確認して、入れ替わっているところを修正してください。
$ pulseaudio -k
$ speaker-test -c 8 -f 800


おまけの設定!

これでひとまずマルチチャネルのプロファイルが登録されましたが、さらにサンプリングレートやビット深度についても設定しておきます。
デフォルトでは44.1kHz/16bitですが、まぁもっとハイスペックな設定で十分鳴らせるだけのスペックを持っていると思いますので。
まずは /etc/pulse/daemon.conf を $HOME/.pulse/ にコピーします。ユーザごとに設定しておくほうがトラブルが少なくていいでしょう。
$ cp /etc/pulse/daemon.conf $HOME/.pulse/
続いてコピーしてきたファイルを適当なテキストファイルで開き、下記の行をそれぞれ編集します。 なお、このファイルでは「;」以降がコメントとして扱われます。
default-sample-format
こちらはビット深度の設定です。デフォルトはs16leで、これが16bit整数です。HDMIであればs32leで32bit設定にしておくといいでしょう。
default-sample-rate
こちらはサンプリングレートの設定です。アンプ等が対応している最大のレートを指定しておけばいいでしょう。192000で192kHzです。
PulseAudioを経由する音声はここで設定されたサンプリングレートにリサンプリングされます。
resample-method
こちらはリサンプリング時のアルゴリズム指定です。品質を高くするほどCPU負荷が高くなります。とりあえず最高品質で設定して、途切れたり負荷が高くなりすぎるようであれば元に戻せばいいと思います。
最高品質は src-sinc-best-quality です。

これらの設定を変更したあとは必ず pulseaudio -k で一度PulseAudioを殺して再起動してください。そうしないと設定が読み込まれません。

まとめ

以上、PulseAudioでHDMIのマルチチャネル再生の設定でした。
ぶっちゃけ音周りはLinuxはほんと面倒ですねぇ・・・。 ドライバ的には対応しているけれど設定方法が全然こなれていないというか・・・。
今回の設定も標準で成されていて欲しいもんだがなぁ。できそうなもんだけど。

ディストリによってはきちんと設定されているかもしれません。Arch LinuxのWikiにはHDMIの5.1/7.1ch再生ができないってことに言及が有ります。
ただ、今回のような細かい設定は書かれておらず、基本的には自動認識されるはずという扱いなのかな・・・?

で、とりあえず鳴らせるようにはしたものの、ぶっちゃけ活かしどころはない・・・w
マルチチャネルのFLACとかを配信サイトから購入するような状況が日常的になれば意味が生まれてくるんだけど、今のところそういう音源持ってないしなぁ・・・。
DVDとかBDはPS3で見るし。ハイレゾ音源はちょくちょく購入するようになったんだけどまだまだマルチチャネル音源は出回ってないからなぁ。

ま、そこいらは今後の潮流を眺めながらってことで。PC側の設定方法は分かったんだし、まーどうにでもなるでしょう。

ってことで、よいLinuxライフを!