FixHole.lua
ver 1.0.0.1
指定長以下のノートの隙間を埋める
Download: FixHole100.zip
コレは何?
VOCALOID 3 Editor 用、Jobpluginです。
ノートとノートの間にある隙間を埋めます。
隙間の大きさは指定できます。
つかいかた
※JobPluginのインストールの方法は割愛します。
※sample.vsqxを同梱していますので、こちらで試してみてください。
- ノートが2つ以上入ったパートを選択状態にし、このJobPluginを実行します。(ノートが1つしかない場合は直ちに終了します)
- ダイアログが出てくるので埋めたい穴の大きさを指定します。
- 「埋める隙間の大きさ(1/n休符)」……埋めたい穴の大きさを指定します。1/64休符〜1/2休符まで対応。例えば「8」を指定すると、1/8休符以下の隙間を埋める事になります。
- 「指定長ちょうどの隙間を埋める」……チェックすると、例えば1/8を指定した場合、1/8休符ちょうどの大きさの穴まで埋まります。チェックしない場合は、1/8休符「より小さい穴」だけを埋めます。
- OKを押すと、指定にしたがって隙間が埋まります。
注意点など
- このスクリプトには V3JobPlugin API Wrapper を使用しています。作者の TomomiSaito 氏に感謝いたします。
- 個人的には現状の仕様で不自由ないですが要望がありましたら考えます。
- お問い合わせ先: Twitter: @chom (ちょむP) / あるいはメール
解説
というわけで今回はJobPluginである。VOCALOIDの調教をする時でも、自動化したいと少しでも思ったものはスクリプトを書いてしまう性分である。
JobPluginの言語はLuaなので、C#などとは少し勝手が違う。例えば リマークは「//」でなく「–」だし、「a += 1」みたいな記述はできないし、「cotinue」などもない。
JobPluginのAPIはデータ構造にアクセスする最低限の手段しか用意されておらず、まじめに操作しようとすると割と面倒くさい。YAMAHA自身はこの貧弱なAPIで本当に何かを作る気があるのか不思議だったが、YAMAHAがJobPluginを利用している商品はいまのところ「ぼかりす」のみで、スクリプトの中身を覗いてみたらただ外部DLLを呼び出しているだけだった…。
だがTomomiSaito氏が公開されているV3JobPlugin API Wrapperのお陰でかなり楽になった。APIWrapperにはDataListオブジェクトにノート情報を格納し、インデックスマーカーを移動させながらスキャンするのに便利な関数が多数用意されている。「現在のノートの終了から次のノートの開始までの間隔を取得する」というまさにこのスクリプトのためにあるようなgetIntervalNextNoteTick()という関数も用意されていたが、なぜか動かなかった(nilがかえってくる)ので今回は自前で計算している。
--
-- FixHole.lua
-- 指定以下の長さの穴を埋める
--
-- Copyright (C) 2015 ちょむP/VOCALOMAKETS
--
--
-- プラグインマニフェスト関数.
--
function manifest()
myManifest = {
name = "FixHole",
comment = "指定長以下のノートの隙間を埋める",
author = "ちょむP/VOCALOMAKETS",
pluginID = "{f77caeec-4582-4a5b-9487-84373d3671da}",
pluginVersion = "1.0.0.1",
apiVersion = "3.0.0.1"
}
return myManifest
end
-- スクリプトのエントリポイント関数.
--
function main(processParam, envParam)
-- 終了コード
local endStatus = 0
-- スクリプトからの相対パスでVSWを読み込みます
assert(loadfile(envParam.scriptDir .. "./V3JobPluginAPIWrapper.lua"))()
VSWrapper:import()
-- **********************************************************
-- ダイアログより前にノート数チェックをしたいので
-- 先にノートを取得します
local noteExList = VSWrapper:listNoteEx()
if (noteExList:count() < 2) then
MsgBox:ok("ノートは2つ以上必要です")
return 0
end
-- **********************************************************
-- ダイアログの生成
local dialog = Dialog:new()
dialog:setTitle("FixHole")
local combolist = {"64","32","16","8","4","2"}
dialog:addList("holewidth", "埋める隙間の大きさ(1/n休符)", combolist )
dialog:addCheckbox("isJust", "指定長ちょうどの隙間を埋める", false)
if not dialog:show():isOk() then
-- OKボタンが押されなかったら終了
return 0
end
-- ダイアログから入力値を取得
local dlgStatus = dialog:values()
widthnum = dlgStatus.holewidth -- コンボ内の値がそのまま返る
-- 埋めるべき穴の大きさの計算
local holeDur = 1920 / widthnum
-- 「ちょうどチェック」の考慮
if( not dlgStatus.isJust ) then
holeDur = holeDur - 1
end
-- **********************************************************
-- 取得したノートイベントをスキャン
-- カーソル初期化
noteExList:reset()
-- スキャン開始
while ( noteExList:next() ~= nul ) do
-- これが最後のノートなら飛ばす
if ( noteExList:getNext() ~= nul ) then
-- リスト内現在位置のノート
local curNote = noteExList:current()
local curDur = curNote:durTick()
local curPos = curNote:posTick()
-- 次のノート
local nexNote = noteExList:getNext() -- getNextはリスト位置カーソルを動かさない
local nexPos = nexNote:posTick()
-- 現在のノートの終了から次のノートの開始までの間隔を取得する
local holewidth = (nexPos) - (curPos + curDur)
-- 穴の大きさが指定長以下なら
if ( holewidth <= holeDur ) then
-- 穴を埋める
curNote:durTick( curDur + holewidth )
-- 更新
if not curNote:update() then
MsgBox:ok("更新エラー発生")
return 1
end
end
end
end
return endStatus
end
とはいうもののやはりダイアログボックスのダサさや気が効いてなさはいかんともしがたいのでJobPluginの今後のアップデートで期待したいところだが、V4出ちゃったし、JobPlugin自体があまり盛り上がってないし、なによりYAHAMAの体質から言ってJobPluginのアップデートはもうないだろうな…。