俺と俺のカップルチャンネル

物忘れが激しいのでタイムカプセル感覚で記憶を埋めていきたいと思います。

Lifebookのbeepを鳴らすメモ

f:id:nosei:20210326152804p:plain

意外と鳴らないbeepを鳴らすメモです。以下にbeepを鳴らさない方法が色々書いてあるので反対のことをすればだいたいなんとかなる模様。 https://wiki.archlinux.org/index.php/PC_speaker

1. 環境

2. モジュールについて

とりあえずlsmodしてpcspkrがロードされていることを確認します。ubuntuでは/etc/modprobe.d/blacklist.confでロードされないようになっているらしいですがdebianではそういったことはなかった。pcspkrの代わりにsnd_pcspでもbeepできますがわざわざこれを使う意味はなかろう。

3. ミュート解除

デフォ消音につき、apt install alsa-utilsしてalsamixerを起動。メインボリュームとbeepmしてミュートを解除、Gainを0dbまで上げておきます。Loopbackもenabledにする必要があります。

4. パーミッションのチェック

非rootでbeep --verboseするとpermission deniedされている事象について。

4-1. udevのデフォルトルール

beepの出力先デバイスのpermissionはudevで設定されています。ルールは/lib/udev/rules.d/70-beep.rulesにあり、ACLでuaccessが設定されるのでローカルにloginしているユーザなら誰でも出力可能ですがsshやらジョブキューから実行していると弾かれることになります。

4-2. udevで権限付与

beepの出力先をaudioグループ所有に変更して書き込みできるようにします。audioグループがない場合まず

# addgroup audio
# usermod -aG audio わしじゃよ

などとして準備します。70-beep.rulesを/etc/udev/rules.dにコピーして編集。udevのルールは1行で、マッチ条件に続いてAssignmentを記述することになっているので

ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="PC Speaker", \
ENV{DEVNAME}!="", TAG+="uaccess", GROUP="audio", MODE="0660"

のように書きます。これでPC Speakerなるinputデバイスがaddされたときにグループとrwが割り当てられる。さっそく適用してみましょう。ルールをリロードしてaddトリガを発行。

# udevadm control --reload
# udevadm trigger -c add /dev/input/by-path/platform-pcspkr-event-spkr

パーミッションエラーが消えればヨシ。fmv-820mgはこれでよかったのですがp772ではエラーはでないが音が鳴らなかったため続きます。

5. PC Speakerが鳴らないケース

beepはまず/dev/input/by-path/platform-pcspkr-event-spkrへ出力を試みます。このファイルは/dev/input/eventNへのシンボリックリンクになっていますがそもそもこいつが鳴らないようです。

5-1. PC SpeakerとHDA Digital PCBeep

PC Speakerは伝統的なPITの出力を使ったBeepで、後者はIntel High Definition AudioのBeep機能です。p772には両方あります。

udevはPC Speakerをbeepバイスとしてセットアップしてくれるが鳴らない…。Digital~のほうを鳴らした直後だけうっすら鳴るのでどうも存在はするらしいが常時給電されているわけではないのか詰んだのでDigital PCBeepを使うことにしました。

まずデバイスを探すわけですが方法は至って簡単で手当り次第に# beep -e /dev/input/eventNして鳴ったやつがそれ。一応デバイスのリストからも確認してみます。udevadm info -eすると

P: /devices/pci0000:00/0000:00:1b.0/sound/card0/input14
L: 0
E: DEVPATH=/devices/pci0000:00/0000:00:1b.0/sound/card0/input14
E: SUBSYSTEM=input
E: PRODUCT=1/10ec/269/1
E: NAME="HDA Digital PCBeep" 
E: PHYS="card0/codec#0/beep0"
E: PROP=0
E: EV=40001
E: SND=6
E: MODALIAS=input:b0001v10ECp0269e0001-e0,12,kramls1,2,fw
E: USEC_INITIALIZED=3517421
E: ID_INPUT=1
E: ID_PATH=pci-0000:00:1b.0
E: ID_PATH_TAG=pci-0000_00_1b_0
E: ID_FOR_SEAT=input-pci-0000_00_1b_0
E: TAGS=:seat:

のようなブロックが見つかりました。このデバイスにリンクするようudevのルールを更新します。マッチ条件に使える属性はudevadm info -a -n input/eventNなどで得られます。

5-2 Digital PCBeep用のudevルール

ルールを上書きしたいので/etc/udev/rules.d/70-pcspkr-beep.rulesを作って

ACTION=="add", SUBSYSTEM=="input", ATTRS{name}=="HDA Digital PCBeep", \
KERNEL=="event?*", SYMLINK="input/by-path/platform-pcspkr-event-spkr", \
TAG+="uaccess", GROUP="audio", MODE="0660"

としました。これでHDA Digital PCBeepというデバイスが追加されるとリンクが貼られてパーミッションも設定されます。リンクを触りたくなければalias beep='beep -e /dev/input/event8'などでよいでしょう。

6. HDA Digital PCBeepの制約

AC'97・HDAの仕様でBeepジェネレータのトーンレジスタは8bitしかなく、生成可能な周波数は 48000 / (1 .. 255 * 4) に限られます。PC Speakerの 1193182 / (20 ... 32767) と比べるとやや大雑把な音律で、メロディとして聴くなら5歳児のアカペラくらいの印象になるかと思います。

7. ハードウェア事情など

BeepバイスがPC Speakerという名前であるのはIBM PCに遡るらしいですね。Intel C8253というタイマーICで矩形波を出すことができたのが専らBeepとして利用されるようになったそうです。時代の流れでタイマーで音を鳴らさなくてもよくなりましたが、データシートを見るかぎり82C54互換のPITがチップセット(ich-mやpch)に統合されて生き残っていまして、オーディオコーデックにもPCBeep入力ピンが残っているところ、繋げばLineに出せる作りになっているようです。しかし今回調べていて分かったことはBeepを鳴らしたい人より止めたい人のほうがずっと多いこと。コストや電力の問題が解決したとて需要がなければBeepの消滅は必定かもしれんすね。個人的にはサウンドBeepの用途は別だと思いますし実機のブザーはいい音なので存続してほしい気持ちは多少ありますが。

beep -f 523 -l 300 -D 100 \
-n -f 698 -l 800 \
-n -f 880 -l 300 -D 100 \
-n -f 784 -l 800 \
-n -f 523 -l 300 -D 100 \
-n -f 698 -l 800 \
-n -f 880 -l 400 \
-n -f 784 -l 400 \
-n -f 880 -l 400 \
-n -f 932 -l 400 \
-n -f 1047 -l 400 \
-n -f 880 -l 400 \
-n -f 698 -l 400 \
-n -f 784 -l 700 -D 100 \
-n -f 523 -l 400 \
-n -f 698 -l 1200

Daisy Bell (A Bicycle Built for Two)

参考