ネタです。 次のブログをちらっと見てて、ドレミとかちょっと面白いなと思ったので、 PowerShell を使用してコマンドラインでドレミ音を鳴らす方法 早速やってみました。
ビープをどうやって鳴らすの?
.NET のSystem.Console.Beep()を利用します。
Console.Beep メソッド (Int32, Int32)
PowerShellでStatic Methodを呼び出すには次のようにします。
[console]::Beep(int32 frequency, int32 duration)
frequency 型 : System.Int32 ビープ音の周波数。37 Hz から 32767 Hz の範囲で指定できます。 duration 型 : System.Int32 ビープ音の再生時間。ミリ秒単位で指定します。
音価を定義
一々音価を書いていられませんので、先に定義してしまいます。 こうすることで、曲のテンポも簡単に調整できます。
#notes $whole = 800 #全音符 $half = $whole / 2 #2分音符 $fter = $whole / 4 #4分音符 $qver = $whole / 8 #8分音符 $haft = $half + $fter #付点付2分音符 $ftqv = $fter + $qver #付点付4分音符
休符はどうする
PowerShellならStart-Sleepがあるので休符に利用します。 .Beep()同様に、ミリ秒で指定も出来るので連動可能です。
Start-Sleep コマンドレットの使用 -m パラメータを使用してミリ秒で指定することもできます
Script Blockで定義しておきます。
#rest $fterrest = {sleep -m $fter} #4分休符 $qverrest = {sleep -m $qver} #8分休符
実行するときは"." か "&" を頭につけます。
. $fterrest
キーを定義
キーは周波数で定まります。 440Hz (A4)を基準音、とするのはどうかと思いますがいったんは決めましょう。最近は440Hzが基準音とは限らないのでご自由にどうぞ。
A3からC5までの周波数を求めます。
3..17 | %{ [int]( [Math]::Pow( 2, $_ / 12.0 ) * 220.0 ) }
int型で算出された周波数をキーに当てはめます。
#keys $do = 262 $dos = 277 $re = 294 $res = 311 $mi = 330 $fa = 349 $fas = 370 $so = 392 $sos = 415 $la = 440 $sif = 466 $si = 494 $doO = 523 $doOs = 554 $reO = 587
ちなみにこんなサイトもありました。
ドレミファ音階のHz対応表
楽譜はどこ
耳コピでも、記憶の通りでもいいです。楽譜を使うのもいいでしょう。
ドレミの歌「DO-RE-MI」(Em)
どうやって音をBeep()に渡す
foreach で渡すのはメンテしにくくなります。
foreach($v in @(262,294,330,349,392,440,494,523)){[Console]::beep($v,200)}
ForEach-Object で渡すと少しは扱いやすくなります。
(262,294,330,349,392,440,494,523) | % {[Console]::beep($_,200)}
変数にセットした、音符と音価を一緒に渡すので2次元配列で書けます。 ※ドレミの初めの2小節
(($do,$ftqv),($re,$qver),($mi,$ftqv),($do,$qver),($mi,$fter),($do,$fter),($mi,$half)) | % {[console]::Beep($_[0],$_[1])}
Get-BeepをFilter化
毎回 | % {[console]::Beep($_[0],$_[1])}
と書くのはつらいのでfilterにします。 ※filterはForeach-Objectが、実際に行っている中身だと思えばイメージしやすいです。
filter Get-Beep { param( [Parameter(ValueFromPipeline=$true)] [int[]]$keyNote ) [console]::Beep($keyNote[0],$keyNote[1]) }
Beep()に渡す記述がすっきりします。
(($do,$ftqv),($re,$qver),($mi,$ftqv),($do,$qver),($mi,$fter),($do,$fter),($mi,$half)) | Get-Beep
Doremiの歌もFunction化して実行
あとは楽譜通りに入力するだけです。
#notes $whole = 800 #全音符 $half = $whole / 2 #2分音符 $fter = $whole / 4 #4分音符 $qver = $whole / 8 #8分音符 $haft = $half + $fter #付点付2分音符 $ftqv = $fter + $qver #付点付4分音符 #rest $fterrest = {sleep -m $fter} #4分休符 $qverrest = {sleep -m $qver} #8分休符 #keys $do = 262 $dos = 277 $re = 294 $res = 311 $mi = 330 $fa = 349 $fas = 370 $so = 392 $sos = 415 $la = 440 $sif = 466 $si = 494 $doO = 523 $doOs = 554 $reO = 587 filter Get-Beep { param( [Parameter(ValueFromPipeline=$true)] [int[]]$keyNote ) [console]::Beep($keyNote[0],$keyNote[1]) } function doremi-song { param( ) begin{ } process{ 1..2 | %{ (($do,$ftqv),($re,$qver),($mi,$ftqv),($do,$qver),($mi,$fter),($do,$fter),($mi,$half)) | Get-Beep (($re,$ftqv),($mi,$qver),($fa,$qver),($fa,$qver),($mi,$qver),($re,$qver),($fa,$whole)) | Get-Beep . $fterrest (($mi,$ftqv),($fa,$qver),($so,$ftqv),($mi,$qver),($so,$fter),($mi,$fter),($so,$half)) | Get-Beep (($fa,$ftqv),($so,$qver),($la,$qver),($la,$qver),($so,$qver),($fa,$qver),($la,$whole)) | Get-Beep . $fterrest (($so,$ftqv),($do,$qver),($re,$qver),($mi,$qver),($fa,$qver),($so,$qver),($la,$whole)) | Get-Beep . $fterrest (($la,$ftqv),($re,$qver),($mi,$qver),($fas,$qver),($so,$qver),($la,$qver),($si,$whole)) | Get-Beep . $fterrest (($si,$ftqv),($mi,$qver),($fas,$qver),($sos,$qver),($la,$qver),($si,$qver),($doO,$whole)) | Get-Beep (($si,$qver),($sif,$qver),($la,$fter),($fa,$fter),($si,$fter),($so,$fter),($doO,$haft)) | Get-Beep . $fterrest } . $fterrest (($do,$fter),($re,$fter),($mi,$fter)) | Get-Beep (($fa,$fter),($so,$fter),($la,$fter),($si,$fter),($doO,$fter),($doO,$fter),($si,$fter),($la,$fter)) | Get-Beep (($so,$fter),($fa,$fter),($mi,$fter),($re,$fter),($do,$fter),($mi,$fter),($mi,$half)) | Get-Beep (($mi,$fter),($so,$fter),($so,$half),($re,$fter),($fa,$fter),($fa,$half)) | Get-Beep (($la,$fter),($si,$fter),($si,$half),($do,$qver),($mi,$qver),($mi,$fter)) | Get-Beep . $qverrest (($mi,$qver),($so,$qver),($so,$fter)) | Get-Beep . $qverrest (($re,$qver),($fa,$qver),($fa,$fter)) | Get-Beep . $qverrest (($la,$qver),($si,$qver),($si,$fter)) | Get-Beep . $qverrest (($so,$half),($do,$half)) | Get-Beep (($la,$half),($fa,$half),($mi,$half),($do,$half),($re,$whole)) | Get-Beep (($so,$half),($do,$half),($la,$half),($si,$half),($doO,$half),($reO,$half),($doO,$whole)) | Get-Beep } end{ } } doremi-song
まとめ
いい利用例ですね。
PowerShellを使えば、寒々としたサーバー室にドレミの歌が!
— Akira Sugiura (@urasandesu) February 2, 2013
次回は、PowerShellでMMLにてドレミの歌を演奏してみます。