2014/12/22
PowerShellでMMLシーケンサーを作ってみた(その2)
はじめに
この記事はPowerShell Advent Calendar 2014の22日目の記事です。
前回はMMLをパースし、音楽をBeepで再生するところまで作りました。
MMLはテキストデータなので、テキストエディタで入力しても良いのですが、どうせなら、PowerShellでエディタも作ってしまいましょう。
コード
いきなりですが、エディタの本体コードを。
function Enter-MusicEditor { $keyMap=@{ A="<G+4>" Z="<A4>" S="<A+4>" X="<B4>" C="C4" F="C+4" V="D4" G="D+4" B="E4" N="F4" J="F+4" M="G4" K="G+4" ","="A4" L="A+4" "."="B4" "/"=">C4<" ":"=">C+4<" "\"=">D4<" "]"=">D+4<" "R"="R4" } $mml=@() cls while($true) { $k = [System.Console]::ReadKey($true) if($k.Key -eq [System.ConsoleKey]::Escape -or $k.Key -eq [System.ConsoleKey]::Enter) { cls break } elseif($k.Key -eq [System.ConsoleKey]::Backspace) { if($mml.length -eq 1) { $mml=@() } elseif($mml.length -ge 2) { $mml=$mml[0..($mml.length-2)] } cls [console]::write((-join $mml)) } else { $key=$k.KeyChar.ToString().ToUpper() if($keyMap.Contains($key)) { $mml+=$keyMap[$key] [console]::write($keyMap[$key]) Invoke-Mml $keyMap[$key] } } } -join $mml }
使い方
PowerShellコンソール上(ISEは不可)で、前回公開した、ConvertFrom-MML、Invoke-Beep、Invoke-Mmlの3つの関数をまず読み込み、続いて上記のEnter-MusicEditor関数を読み込みます。
この状態でコンソール上でEnter-MusicEditorを実行すると、MMLエディタモードに入ります。
MMLエディタモードでは、PCのキーボードを鍵盤代わりにして入力できます。
たとえば、Cキーを押下すると、「ド」の音がBeepで鳴り、コンソールに"C4"と出力されます。同様にFキー押下で「ド♯」が鳴り"C+4"と出力されます。どのキーがどの音に対応しているかは、上記コードの$keyMap変数に格納された連想配列を参照してください。
(なんとなくですけど、楽器の鍵盤の配置と合わせてあります)
Backspaceキーを押下すると、直前の入力を削除できます。
EnterキーかEscapeキーを押下すると、エディタモードを終了します。
出力したMMLは、コンソール上に表示が残るので、あとはコピーしてInvoke-Mml関数に渡してやると演奏することができます。
また、$mml=Enter-MusicEditorとしてやると、入力したMMLをそのまま変数に格納できます。この場合だとInvoke-Mml $mmlと実行すれば演奏できます。
解説
技術的には全然大したことをしてないですが、一応解説。
まず、[System.Console]::ReadKey()で入力したキーコードを判別します。引数に$trueを指定すると、入力したキー名をそのままコンソールに出力するのを抑制できます。
ReadKeyメソッドはConsoleKeyInfoオブジェクトを返します。アルファベットキーについてはKeyCharプロパティの値、特殊キーについてはConsoleKey列挙体を返すKeyプロパティの値で調べることができます。
あとは入力キーから対応する音名を連想配列$keyMapから取ってきて、その音名を[System.Console]::Write()でコンソール出力すると同時に、Invoke-Mml関数でその音をBeepとして鳴らしているだけです。
まとめ
入力も再生もできるようになったので、これはもう完全にシーケンサーですね! いや、やはり無理があるか…。
しかし、他のMMLコンパイラと併用して、ちょっと演奏しながらMML入力したいな、というときにもしかすると役に立つかもしれません。
ちょっと機能が少なすぎるんで、せめて↑で半音上げ↓で半音下げ、→で伸ばす←で短く、くらいはそのうち実装してみたいですね。
まあ、MML作成にはあんまり役に立たないかもしれませんが、PowerShellでコンソールの入出力を制御するのは、こういう単純なものなら意外と簡単にできるという、サンプルにはなるかと思います。
プライバシーポリシー