なにか終わったらRingRingしたい話
FreeBSD 12.1-R4/amd64で、ある程度時間がかかるスクリプトを実行している中で、終わったら適当な音を出して知らせてくれる機能をお遊び半分で調べて書いたもの。
条件は、追加Portsは一切なし。FreeBSD 12.1-R4/amd64インストール直後でも実行可能であること。サウンドカードの設定はここでは書かないが、デバイスを認識し音声出力ができること。
通常であれば、mpg123で適当な音声を流してみたり、soxコマンドを使って音を生成しつつそれをスピーカに出力する方式を取ると思うが、今回はそれができない。Linux ALSAのようなaplayコマンドの搭載もないので、FreeBSD標準の状態では音声を出力するコマンドはないことになる。しかしFreeBSDハンドブックを読んだことがあれば、 音声出力のテストコマンドとして、 # cat /dev/random > /dev/dsp を投入することで雑音が流れることはご存知だと思われる。またスピーカーから音を出すことにこだわらなければ、beep音としてspeaker.koを使える。これは音程をつけてメロディを流すこともできる。
まずは、手っ取り早く実現できそうなspeaker機能を試す。標準ではカーネルモジュールをロードしておかないと/devディレクトリには見えない。なので、下記のコマンドをrootユーザで実行する。
# kldload speaker
すると、/dev/speakerというデバイスが現れる。このデバイスに向かって音階の記号を流す。
# echo "CDEFGAB" > /dev/speaker
CDE・・・は馴染みづらいが、昔は音階がラ:Aから始まり、シ:B、ド:Cとなっているという話で、記法が分かればそれほど理解に苦労しない。
参考: https://duckduckgo.com/?q=%E3%83%89%E3%83%AC%E3%83%9F+CDE
# echo "CDECDEGEDCDED" > /dev/speaker
上記のコマンドを実行すると、小学校で習う簡単なメロディが流れるはずだ、ったのだがspeakerはパソコンによっては聴こえないことがあるらしい。beep音が流れるようにBIOS/UEFIで調整するなり、マザーボードのspeakerのピンに適切なパーツを挿せばおそらくは鳴る。(ノートパソコンなどでは代替で音声スピーカから音が出力されることもある)
マニュアルを読んでみるとspkrtestコマンドというものがあるらしいので、先程のコマンドよりは凝った音楽が流れると思われる。
参考: http://www.koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=spkrtest&dir=jpman-12.1.2%2Fman§=0
ところが、私の環境では/dev/speakerで音を出力する手段が頓挫してしまった。上記コマンドを実行しても実行はしているみたいだが音がでない。マザーボードのspeakerピンに挿すべきパーツも持っていなければ、/etc/rc.confなどでbeep音を抑制しているわけでもないが、理由がわからないのでここで諦める他ない。(# printf "\a" でも音が鳴らない。)
仕方がないので、FreeBSDハンドブックにあるような # cat /dev/random > /dev/dsp でそれっぽいものができないか試してみることにする。/dev/randomを使う場合、音量は特に注意が必要で、特にヘッドホンを使っている場合は一回外しておいたほうが良いかもしれない。FreeBSDにもmixerというコマンドはあるので、下記のコマンドで音量を下げておく。
# mixer vol 50
/dev/randomを出力した場合、常にランダムな値を出力し続ける→これを/dev/dspに解釈させて音声出力とするという形なので、catプロセスが破壊されるか/dev/randomからEOFが来なければずっと雑音を流し続けることになる。
雑音を作業終了の合図として使うのもどうかと思うので、適当な値を突っ込んでみて良さげな音がないか探してみる。下記はコマンド例。
# yes 1 > /dev/dsp
yesコマンドは引数に指定された文字列を改行区切りで出力するコマンド。なので、特にパイプなり逆くちばしに渡さなければ、下記のような出力が行われる。
root@freebsd[/root] # yes 1
1
1
1
1
1
1
〜プロセスが中断されるまで上記出力が継続〜
なので、# yes 1 > /dev/dsp を実行すると、1[改行]をひたすら/dev/dspに出力し続けることになる。
これで音を探っていくと、どうやら16の階乗で音が変わることがわかったので、下記のようなコマンドで終了を知らせることができる。(おそらくこの理解は誤りである)
# yes 8192 > /dev/dsp
yesコマンドは特にケアしなければずっと出力を続けるため、止めなければずっと音を流し続ける。これではやかましいだけなので、ちょっとスクリプトを書いて5秒ぐらいで止めてみることにする。
# less ringring.sh
#!/bin/sh
alarm=8192
yes ${alarm} | /dev/dsp &
pid=${!}
sleep 5
kill ${pid}
特にコマンドについては解説しないが、これで5秒ぐらいで音が停止するはず。
これで音を鳴らして合図するようなものができた。
〜〜蛇足〜〜
FreeBSDではいつからか不明だが、sleepコマンドに対して、10ミリ秒単位での指定が可能になったらしい。実際 先程のスクリプトをtimeコマンドを噛ましてみると0.50でコマンドが終了していることが確認できる。
ということは、先程のスクリプトももう少し手を加えたら、変わった音が出せそうだ。ということで書いてみたのが下記のスクリプトである。(sleepコマンドに指定すべき数値が誤っていたので修正(2020/05/20)
#!/bin/sh
alarm_a=8192
alarm_b=16384
cnt=5
while [ ! 1 -eq ${cnt} ]
do
yes ${alarm_a} | /dev/dsp &
pid=${!}
sleep 0.5
kill ${pid}
yes ${alarm_b} | /dev/dsp &
pid=${!}
sleep 0.5
kill ${pid}
cnt=`expr ${cnt} - 1`
done
条件は、追加Portsは一切なし。FreeBSD 12.1-R4/amd64インストール直後でも実行可能であること。サウンドカードの設定はここでは書かないが、デバイスを認識し音声出力ができること。
通常であれば、mpg123で適当な音声を流してみたり、soxコマンドを使って音を生成しつつそれをスピーカに出力する方式を取ると思うが、今回はそれができない。Linux ALSAのようなaplayコマンドの搭載もないので、FreeBSD標準の状態では音声を出力するコマンドはないことになる。しかしFreeBSDハンドブックを読んだことがあれば、 音声出力のテストコマンドとして、 # cat /dev/random > /dev/dsp を投入することで雑音が流れることはご存知だと思われる。またスピーカーから音を出すことにこだわらなければ、beep音としてspeaker.koを使える。これは音程をつけてメロディを流すこともできる。
まずは、手っ取り早く実現できそうなspeaker機能を試す。標準ではカーネルモジュールをロードしておかないと/devディレクトリには見えない。なので、下記のコマンドをrootユーザで実行する。
# kldload speaker
すると、/dev/speakerというデバイスが現れる。このデバイスに向かって音階の記号を流す。
# echo "CDEFGAB" > /dev/speaker
CDE・・・は馴染みづらいが、昔は音階がラ:Aから始まり、シ:B、ド:Cとなっているという話で、記法が分かればそれほど理解に苦労しない。
参考: https://duckduckgo.com/?q=%E3%83%89%E3%83%AC%E3%83%9F+CDE
# echo "CDECDEGEDCDED" > /dev/speaker
上記のコマンドを実行すると、小学校で習う簡単なメロディが流れるはずだ、ったのだがspeakerはパソコンによっては聴こえないことがあるらしい。beep音が流れるようにBIOS/UEFIで調整するなり、マザーボードのspeakerのピンに適切なパーツを挿せばおそらくは鳴る。(ノートパソコンなどでは代替で音声スピーカから音が出力されることもある)
マニュアルを読んでみるとspkrtestコマンドというものがあるらしいので、先程のコマンドよりは凝った音楽が流れると思われる。
参考: http://www.koganemaru.co.jp/cgi-bin/mroff.cgi?subdir=man&lc=1&cmd=&man=spkrtest&dir=jpman-12.1.2%2Fman§=0
ところが、私の環境では/dev/speakerで音を出力する手段が頓挫してしまった。上記コマンドを実行しても実行はしているみたいだが音がでない。マザーボードのspeakerピンに挿すべきパーツも持っていなければ、/etc/rc.confなどでbeep音を抑制しているわけでもないが、理由がわからないのでここで諦める他ない。(# printf "\a" でも音が鳴らない。)
仕方がないので、FreeBSDハンドブックにあるような # cat /dev/random > /dev/dsp でそれっぽいものができないか試してみることにする。/dev/randomを使う場合、音量は特に注意が必要で、特にヘッドホンを使っている場合は一回外しておいたほうが良いかもしれない。FreeBSDにもmixerというコマンドはあるので、下記のコマンドで音量を下げておく。
# mixer vol 50
/dev/randomを出力した場合、常にランダムな値を出力し続ける→これを/dev/dspに解釈させて音声出力とするという形なので、catプロセスが破壊されるか/dev/randomからEOFが来なければずっと雑音を流し続けることになる。
雑音を作業終了の合図として使うのもどうかと思うので、適当な値を突っ込んでみて良さげな音がないか探してみる。下記はコマンド例。
# yes 1 > /dev/dsp
yesコマンドは引数に指定された文字列を改行区切りで出力するコマンド。なので、特にパイプなり逆くちばしに渡さなければ、下記のような出力が行われる。
root@freebsd[/root] # yes 1
1
1
1
1
1
1
〜プロセスが中断されるまで上記出力が継続〜
なので、# yes 1 > /dev/dsp を実行すると、1[改行]をひたすら/dev/dspに出力し続けることになる。
これで音を探っていくと、どうやら16の階乗で音が変わることがわかったので、下記のようなコマンドで終了を知らせることができる。(おそらくこの理解は誤りである)
# yes 8192 > /dev/dsp
yesコマンドは特にケアしなければずっと出力を続けるため、止めなければずっと音を流し続ける。これではやかましいだけなので、ちょっとスクリプトを書いて5秒ぐらいで止めてみることにする。
# less ringring.sh
#!/bin/sh
alarm=8192
yes ${alarm} | /dev/dsp &
pid=${!}
sleep 5
kill ${pid}
特にコマンドについては解説しないが、これで5秒ぐらいで音が停止するはず。
これで音を鳴らして合図するようなものができた。
〜〜蛇足〜〜
FreeBSDではいつからか不明だが、sleepコマンドに対して、10ミリ秒単位での指定が可能になったらしい。実際 先程のスクリプトをtimeコマンドを噛ましてみると0.50でコマンドが終了していることが確認できる。
ということは、先程のスクリプトももう少し手を加えたら、変わった音が出せそうだ。ということで書いてみたのが下記のスクリプトである。(sleepコマンドに指定すべき数値が誤っていたので修正(2020/05/20)
#!/bin/sh
alarm_a=8192
alarm_b=16384
cnt=5
while [ ! 1 -eq ${cnt} ]
do
yes ${alarm_a} | /dev/dsp &
pid=${!}
sleep 0.5
kill ${pid}
yes ${alarm_b} | /dev/dsp &
pid=${!}
sleep 0.5
kill ${pid}
cnt=`expr ${cnt} - 1`
done
コメント
コメントを投稿