Lifebookのbeepを鳴らすメモ
意外と鳴らない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
を起動。メインボリュームとbeepをm
してミュートを解除、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) Hzに限られます。PC Speakerの 1193182 / (20 ... 32767) Hzと比べるとやや大雑把な音律で、メロディとして聴くなら5歳児のアカペラくらいの印象になるかと思います。
7. ハードウェア事情など
BeepデバイスがPC Speakerという名前であるのはIBM PCに遡るらしいですね。Intel C8253というタイマーICで矩形波を出すことができたのが専らBeepとして利用されるようになったそうです。時代の流れでタイマーで音を鳴らさなくてもよくなりましたが、データシートを見るかぎり8254互換の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)