開発

XF86AudioPlayの謎:Linuxで音声キーが異常発生した原因と解決法

LinuxデスクトップでXF86AudioPlayキーイベントが数秒おきに異常発生した問題を、libinputやudevadmを使った調査で解決した過程を紹介する。

8分で読める SINGULISM 編集チームが確認・編集

XF86AudioPlayの謎:Linuxで音声キーが異常発生した原因と解決法
Photo by Alexander Sinn on Unsplash

Emacsのステータスバーに繰り返し表示された不可解なエラー Linuxデスクトップ環境で長く使っていると、時折説明のつかない現象に遭遇することがある。

デベロッパーのMichael

Prokop氏が公開したブログ記事は、まさにそうした「謎のバグ」を追いかけた過程を克明に記録したものだ。 問題はシンプルだった。Emacsのステータスバーに「<XF86AudioPlay> is undefined」というメッセージが2〜3秒おきに表示され続けるというものだ。XF86AudioPlayとは、キーボードのメディア再生キーに対応するX11のキーシンボル名である。このメッセージ自体は、Emacsがそのキーイベントを受け取ったものの、対応するキーバインドが定義されていない場合に表示されるものだ。 奇妙だったのは、この現象がEmacs上でだけ観測されたことだ。システムログにも関連するエントリは見つからず、他のアプリケーションでは異常は確認できなかった。しかし、メッセージは止まらなかった。

swayのキーバインドで「犯人」を絞り込む

Prokop氏は再起動せずに原因を突き止めようと、まず自身のsway(Waylandベースのウィンドウマネージャー)の設定を変更した。XF86AudioPlayキーの押下イベントに対して、音楽プレイヤーの再生・一時停止を実行するコマンドを紐付けたのだ。 ``` bindsym XF86AudioPlay exec playerctl play-pause


## USBキーボードは無関係だった 次に疑われたのは物理的なキーボードの故障だ。キーが物理的に押しっぱなしの状態になっていれば、同じイベントが繰り返し発生するはずだ。

しかし、USBキーボードをシステムから取り外しても現象は変わらなかった。キーボード側の問題ではないことは明らかだった。 では、どのデバイスがこのキーイベントを送出しているのか。ここで登場するのがlibinput-toolsだ。 

## libinputで犯人デバイスを特定

Prokop氏は`libinput debug-events`コマンドを実行し、入力デバイスのイベントをリアルタイムで監視した。その結果、以下のような出力が得られた。 ```
event12 KEYBOARD_KEY +0.000s KEY_PLAYPAUSE (164) pressed
event12 KEYBOARD_KEY +0.000s KEY_PLAYPAUSE (164) released
event12 KEYBOARD_KEY +2.887s KEY_PLAYPAUSE (164) pressed
event12 KEYBOARD_KEY +2.887s KEY_PLAYPAUSE (164) released
event12 KEYBOARD_KEY +5.773s KEY_PLAYPAUSE (164) pressed
event12 KEYBOARD_KEY +5.774s KEY_PLAYPAUSE (164) released
``` 約2.887秒間隔でKEY_PLAYPAUSEイベントが`event12`というデバイスから送出されていることが確認された。キーコード164はKEY_PLAYPAUSEに対応し、XF86AudioPlayキーシンボルとしてシステムに解釈される。 

## udevadmで正体を暴く `event12`の正体を調べるため、Prokop氏は`udevadm info`コマンドを利用した。

その結果、event12のデバイスパスは以下のようになっていた。 ```
/devices/pci0000:00/0000:00:1f.3/skl_hda_dsp_generic/sound/card0/input17/event12
``` PCIバス上のIntelオーディオサブシステム(skl_hda_dsp_generic)に関連付けられたサウンドカードの入力デバイスであることが判明した。さらに`udevadm info -a`で詳細情報を取得すると、デバイス名は「sof-hda-dsp Headphone」となっていた。 SOF(Sound Open Firmware)は、Intelが開発したオープンソースのオーディオDSPフレームワークだ。HDA(High Definition Audio)と組み合わせた「sof-hda-dsp」は、近年のIntel搭載ノートPCで広く使われているオーディオドライバーの構成である。 evtestコマンドでも同様に、event12が「sof-hda-dsp Headphone」デバイスであることが確認された。 

## 犯人はIntelオーディオドライバーだった

結局のところ、問題の原因はIntelのオーディオサブシステムが送出する偽のKEY_PLAYPAUSEイベントだった。sof-hda-dsp Headphoneデバイスが、実際のヘッドフォン操作とは無関係に、一定間隔でメディア再生キーイベントをシステムに送信し続けていたのだ。 この種の問題は、SOFドライバーと特定のハードウェアの組み合わせで発生すると報告されている。ヘッドフォンの接続状態を検知する仕組みや、DSPの省電力モードからの復帰処理に起因する可能性があるが、Prokop氏の記事では根本原因の詳細には踏み込んでいない。 

## 調査手法のポイント この事例が示すのは、Linuxシステムで不可解な入力イベントが発生した際の効果的な調査手順だ。 まず、swayやi3などのウィンドウマネージャーのキーバインド設定を利用して、問題のキーイベントが実際に発生していることを視覚的・動作的に確認する。

次に、libinput-toolsの`debug-events`コマンドでどの入力デバイスがイベントを送出しているかを特定する。最後に、udevadmやevtestでデバイスの実体を突き止めるという流れだ。 USBキーボードやマウスのような外部デバイスではなく、内蔵オーディオサブシステムのような「入力デバイスとは思えない」デバイスがキーイベントを送出しているケースは、見落とされやすい。本件のようにlibinputのイベントログを地道に確認することが、問題解決への近道となる。 

## Linuxデスクトップに潜む「見えない入力」 Linuxデスクトップ環境では、udevやlibinputの仕組みを通じて、多様なハードウェアデバイスが入力イベントを送出できる。

キーボードやマウスだけでなく、電源ボタン、スリープボタン、オーディオコントロール、さらにはノートPCのファンクションキーなど、さまざまなデバイスがinputサブシステムを経由してイベントを発行する。

今回のケースは、そうした入力イベントの一つが、ユーザーの意図とは無関係に定期的に送出され続けた事例だ。Emacsのようなキーバインドに敏感なアプリケーションを利用していると、こうした隠れたイベントが表面化しやすい。逆に言えば、Emacsのステータスバーエラーがなければ、この問題に気づかなかった可能性もある。 普段は意識することのないLinuxの入力サブシステムが、時に予期せぬ動作を引き起こす。本件は、デスクトップLinuxユーザーにとって、libinputやudevadmといったツールの使い方を知っておく価値を改めて示す好例と言えるだろう。

よくある質問

XF86AudioPlayエラーはEmacsのバグですか?
いいえ、Emacsのバグではありません。EmacsはXF86AudioPlayキーイベントを受け取った際に、対応するキーバインドがないことを通知しているだけです。問題の根本原因は、Intelのオーディオサブシステム(sof-hda-dsp)が偽のKEY_PLAYPAUSEイベントを定期的に送出していたことです。
libinput debug-eventsコマンドで入力デバイスを特定する方法は?
root権限で`sudo libinput debug-events`を実行すると、すべての入力デバイスからのイベントがリアルタイムで表示されます。問題のイベントが発生した際、どのevent番号のデバイスから送出されているかを確認し、`sudo udevadm info /dev/input/eventXX`(XXは該当する番号)でデバイスの詳細情報を調べることができます。
sof-hda-dspとは何ですか?
sof-hda-dspは、IntelのSound Open Firmware(SOF)とHigh Definition Audio(HDA)を組み合わせたオーディオドライバー構成です。近年のIntel搭載PCで広く使用されており、DSP(デジタルシグナルプロセッサー)を活用したオーディオ処理を担当します。特定のハードウェアとの組み合わせでは、今回のような偽のキーイベント送出の問題が報告されています。
出典: Lobsters

コメント

← トップへ戻る