PowerShellによるMMLファイル監視 – 同期版

PowerShellによるMMLファイル監視 – 同期版

 windows上のppmckやnsd.Libで使用するPowerShellスクリプトをつくりました。
PowerShellを使ったmmlファイル更新チェッカとして機能するものです。

ppmckとnsd.Libの著作権については、以下のとおりです

— ppmck
ライセンス形態–GPLライセンス?で運用、以下は著作権表示となります。

nesasm: NES assembler J.H.Van Ornum,David Michel,Dave Shadoff,Charles Doty様
mck: NES Sound Driver Izumi様
mckc: mck用mmlコンバータ Manbow-J様
pmck/pmckc: mck/mckc拡張版 boukichi様
ppmck: mck/mckc改良版 h7様

— nsd.Lib
ライセンス形態–FreeBSDライセンス(2条項BSD)著作権はS.W.様となります

 mmlファイルをドロップすると監視を始め、mmlファイルがエディタで保存されたら、
即時にコンパイルしてプレイヤーで再生までを自動化するスクリプトです。
linuxでのmmlファイル監視をwindowsでもできたら..と思いつつ組みました。

確認はXPのみ。以降のOSでも多分問題なく動くはずです

 ファイル監視に、PowerShellを使います。
win 7以降では、標準でインストール済みのものです。このPowerShellスクリプトをふたつつくります。それとふたつバッチファイルが必要です。
ひとつは、PowerShellを呼び出すバッチファイル、もう一つはコンパイラとプレイヤーへ送出するためのものです。
及びppmckのバッチファイル、set_envs.batと、mknsf.batを空白パスに対応したものを用意しました

もし試して頂けるのであれば、全てのスクリプトがあるmml_watch.zipを置きました。よろしければ、ダウンロードしてみて下さい

注: mml_watchは、ver2bにアップデートしたため当該ファイルは、圧縮ファイル内の旧版ver1となります

 なおこの監視スクリプトは、バッチファイルを主体として組んだものとなってます。
もし、パワーシェル仕様の非同期処理版にも興味があるならば非同期版を見てみて下さい

 

□ vistaXP – PowerShellのインストール 
 ではまず手始めとして、vistaXPであれば、PowerShellを入れなければ何もできません。

パワーシェルは、更新ファイルを入手することでインストールできます。
実行環境はPowerShell 2.0から動くので、XPsp3向け2.0のリンクを貼りますが、適時自分の環境に合わせて選択してください

 ここからは本題の、4つのスクリプトを順に載せていきます。
Powershellを使ったファイル監視スクリプトの説明及び、その使用法です

 


 

□ Drop.bat – PowerShellを呼び出すバッチ 
 PowerShellを呼び出すバッチファイルDrop.batをまず用意します。
拡張子ps1は、ファイルドロップができないのとポリシーの設定があるため、このバッチファイルから呼び出します。

フィルドロップのケースでは、プロファイルフォルダにカレントが残るので、
まず、cd /d %~dp0を打ち、スクリプト自身のフォルダにカレントディレクトリを移動、
PowerShellを走らせるため、プロセスのみポリシーに実行権限を付与する、という内容を行ってます

Drop.bat

— ppmck,nsd共通

@rem Drop.bat
@echo on

cd /d %~dp0
powershell -ExecutionPolicy RemoteSigned -File .\chk_mml.ps1 “%~f1”

参考url

 


 

□ chk_mml.ps1 – PowerShellによるファイルパスチェック 
 PowerShellによるファイルパスチェックスクリプトchk_mml.ps1を用意します。
ファイルの存在を確認し、必要となるパス情報をここで集めてます

chk_mml.ps1

— ppmck,nsd共通

function err_out($num){
    switch($num){
    1{ echo “//パラメータ数があわない//`r`n” }
    2{ echo “//ファイル指定がない//`r`n” }
    3{ echo (“//”+ $f+ “ファイルが見つからない//`r`n”) }
    } #sw
    Read-Host “続けるにはENTERキーを押して下さい” | Out-Null
} #func

if($args.Length -ne 1){ # args chk
    err_out 1
}else{

    if($Args[0] -eq “”){ # path chk
        err_out 2
    }else{

        $p= [System.IO.Path]::GetDirectoryName($Args[0])
        $n= [System.IO.Path]::GetFileNameWithoutExtension($Args[0])
        $f= $n+ “.mml”

        echo “”
        echo (“Path :”+ $p)
        echo (“File :”+ $f+ “`r`n”)

        if((Test-Path ($p+ “\”+ $f)) -eq $false){ # file chk
            err_out 3
        }else{

            .$dpn= $p+ “\”+ $n
            .\mml_watch.ps1 $dpn $p $f
        }
    }
}

参考url

 


 

□ mml_watch.ps1 – PowerShellの監視スクリプト 
 PowerShellの監視スクリプトmml_watch.ps1を用意します。同期処理版です

必要となるパス情報を受け付けたら後、繰り返しファイル変更を監視し、随時バッチファイルを実行する、という内容です

mml_watch.ps1

— ppmck,nsd共通

$Args_path = $Args

$w = New-Object System.IO.FileSystemWatcher
$w.Path = $Args_path[1]
$w.Filter = $Args_path[2]
$w.NotifyFilter = [System.IO.NotifyFilters]::LastWrite

while(1){
    .\nsf_trans.bat $Args_path[0] # Command

    echo “”
    echo “Setting up watches.”
    echo “Watches established.`r`n”

    $changeResult = $w.WaitForChanged([System.IO.WatcherChangeTypes]::Changed)
    echo ($changeResult.Name+ ” MODIFY`r`n”)

} #

参考url

 


 

□ nsf_trans.bat – mmlコンパイラとプレイヤーを呼び出す変換バッチ 
 mmlコンパイラとプレイヤーを呼び出す変換バッチファイルnsf_trans.batを用意します。if elseだとうまくエラーレベルが取得できなかったため、ラベルとgoto文での記述となってます。

 コンパイラを呼出し後、別プロセスでプレイヤーを演奏するという中身のため、
当バッチファイルのみ、2行だけ環境に合わせて、プレイヤーパスを記述し直す必要があります。

このため、set exe_pathに記述してある、プレイヤーのパスを的確に指定して下さい。
空白のあるファイルパスにも対応します。ただしsetコマンドの仕様上、= 以降は、不必要な空白を入れないように気をつけて下さい。

相対パス指定であれば、スクリプトのあるフォルダを起点とします。
Forコマンドで絶対パスに変換されるとき、スクリプトのあるディレクトリが起点になるためです。

凡例にある..\はカレントディレクトリから一つ上へあがるという意味なので..\..\VirtuaNSF\VirtuaNSFであれば、2つ上の階層へあがりVirtuaNSFフォルダにあるVirtuaNSFを呼び出すことを表しています
再生プレイヤーとしてnsfplayとVirtuaNSFを記載しましたので、
@remの付け外しにより、どちらかを選択して下さい

nsf_trans.bat

— ppmck,nsd共通

@rem nsf_trans.bat
@echo off

cd /d %~dp0

@rem set exe_player=”..\..\nsfplay\nsfplay.exe”
set exe_player=”..\..\VirtuaNSF\VirtuaNSF.exe”

set exe_nsc=”..\bin\nsc.exe”

if not exist .\mck_script\mknsf.bat goto nsd

call .\mck_script\mknsf.bat %1
goto mck
:nsd

for %%I in (%exe_nsc%) do set nsc_path=%%~dpI
cd %nsc_path%

for %%I in (%exe_nsc%) do set nsc_name=%%~nxI
%nsc_name% -n -e “%~1.mml”
:mck

echo.
echo errorlevel :%errorlevel%
if errorlevel 1 goto err

for %%I in (%exe_player%) do set ply_path=%%~dpI
cd %ply_path%

for %%I in (%exe_player%) do set ply_name=%%~nxI
start %ply_name% “%~1.nsf”

goto fin
:err

echo.
echo // NSFfile: failure !//
:fin

参考url

 以上、4つのスクリプトを、ppmck,nsd.Libのbinと同じ階層となる、mck\mml_watch, nsd\mml_watch のような単一フォルダに全て入れます。
次に、ppmckのみ必要になる、修正済みバッチファイルを説明します。

 


 

□ mknsf.bat – set_envs.batとmknsf.batを単体化 
 set_envs.batとmknsf.batを単体化し、mmlファイルパス上に空白があっても、稼働できるようにしたものです。このバッチファイルmknsf.batを、mck\mml_watch\mck_script下に置きます。

 ppmck,nsd.Libを切り換えは、先ほど説明した上位スクリプトnsf_trans.batにより、
このバッチファイル.\mck_script\mknsf.batの有無をチェックすることで判断しています。このため、ppmck側のmck\mml_watchのみに、置く必要があります

 まず、set_envs.bat側の修正点を説明します。
DMC_INCLUDEを有効にし、mmlファイルのあるパスを、この環境変数に代入するようにしました。
DMC_INCLUDEはこの後、mmlファイルに書かれた相対パスが組み込まれると思われ、ファイルパス名を ” で挟まず、最後の \ を取り去ることでdmcが読み込めるようになりました

 続いてmknsf.bat側の修正点です。
空白のあるパス対策にダブルバックスラッシュでファイルパスを囲った点、ファイル移動を追加した点と、errorlevelを返すように変更した点が主な修正ポイントです。
このファイルの最後に書かれた、exit /b %errorlevel%は、上位スクリプトにエラーレベルの出力を返すことを意味します

mknsf.bat

— ppmck

@rem set_envs.bat ———————

set PPMCK_BASEDIR=..
set NES_INCLUDE=%PPMCK_BASEDIR%\nes_include

set DMC_INCLUDE=%~dp1
set DMC_INCLUDE=%DMC_INCLUDE:~0,-1%

@rem mknsf.bat ————————

if not exist .\effect.h goto compile
del .\effect.h
:compile

%PPMCK_BASEDIR%\bin\ppmckc -i “%~1.mml”

if not exist .\effect.h goto err
if not exist .\ppmck.nes goto assemble
del .\ppmck.nes
:assemble

%PPMCK_BASEDIR%\bin\nesasm -s -raw ppmck.asm

if not exist .\ppmck.nes goto err

move /y .\ppmck.nes “%~1.nsf”
:err

exit /b %errorlevel%

参考url

 これで全ての準備が整いました。ここからは、監視スクリプトを順にテストします。

 


 

□ nsf_trans.bat – 変換バッチファイルのテスト 
 変換バッチファイルのテストをまず行います。

まず、mck\mml_watch と、nsd\mml_watch のフォルダに、それぞれに対応したsample.mml を置きます。
各フォルダ上でコマンドプロンプトを立ち上げ、以下のワンライナーを打って、順に確認してみて下さい

 > nsf_trans.bat sample

 無事nsfファイルが出力され、滞りなくプレイヤーが再生したらテストは終了です。
 もし、コンパイルされないのであれば、以下のケースをチェックしてみてください。

・スクリプトを置く場所が間違っている、つまりbinが置いてあるフォルダと同じ階層にmml_watchフォルダがないため、mmlコンパイラが呼び出せない。

・もしく、ppmckに必要な.\mck_script\mknsf.batがないため認識できない、
 逆に.\mck_script\mknsf.batがあるため、nsd.Libと認識できないなどの理由も考えられます。mck_scriptフォルダ、mknsf.batの存在を確認してみて下さい。

・nsd.Libから、../../nsd.bin: No such file or directory などと返される場合は、
 MMLの記述を、#Code “../bin/nsd.bin”のように変更してください。カレントからの相対パスとして見えるようになります。

・プレイヤーが自動起動しないのであれば、恐らくnsf_trans.batのプレイヤーパスの記述が間違っている可能性があります

  ここまでの手順が無事、終わったなら残りはわずかです。

 

□ Drop.bat – 監視スクリプトの起動 
 監視スクリプトの起動テストをします。

Drop.batにsample.mml をドロップしてみて下さい。
コマンドプロンプトが立ち上がりファイル監視を始めると思います。
エディタなどでsample.mml を開き、a>cf などとmmlを入力して再保存すれば、即座に反映するはずです。
監視をやめたい時はウィンドウを閉じるのみでokです

 ちなみに、mml_watchフォルダ上で起動したコマンドプロンプト上でも、
>drop sample とコマンドすることで、同様の監視が始まります。

もしどうしても、コマンドプロンプト上で終了処理したいのであれば、まずCtrl+C の後、再度、sample.mml をエディタで保存してみて下さい。
すると、シェルのwaitが外れてバッチ ジョブを終了しますか (Y/N)?と返してきます

 最後に使用する上でのワンポイントです。 Drop.batのショートカットをつくっておくと良いかもしれません。このショートカットにドロップするだけでも、ファイル監視が始められるからです

 

□ 注意点として 
 現在わかっている注意点をふたつばかり上げておきます。

 空白が入るパスであっても試聴ができ、運用も可能ではありますが、nsd.Libのヘルプを見る限りでは、厳密にはファイルパスに空白を入れないことを推奨しているようです。
空白が入りずらくなるよう、コンパイラとプレイヤーの近くにmmlファイルを置いて運用するのが望ましいと思います

 また、非力なマシンの場合のみですが、nsdとNSFPlayの組合せにおいて、演奏をかけたまま即時MMLコンパイルするつかの間、再生しているプレイヤーからノイズのようなぶちぶち音が出ることがわかってます。
この症状が出るケースでは、瞬間的にCPUの処理能力を使いきったとも考えられるため、もし気になるようであれば、NSFPlayの再生周波数を一時的に下げるなどの対処によって改善してみて下さい

広告

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中