以下の内容はhttps://tech.guitarrapc.com/entry/2013/02/05/000226より取得しました。


PowerShellでビープ音の「ドレミの歌」を奏でてみよう

次のブログをちらっと見てて、ドレミとかちょっと面白いなと思ったので、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

まとめ

いい利用例ですね。

Akira Sugiura (@urasandesu)

次回は、PowerShellでMMLにてドレミの歌を演奏してみます。




以上の内容はhttps://tech.guitarrapc.com/entry/2013/02/05/000226より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14