サウンド系仕様確認

まず、音楽系の高水準命令をまとめてみる。

機能 BGM系 BGV系 SE系 VOICE系
ファイルを指定してループ再生する。 BGMPLAY "bgm.ogg" BGVPLAY ch,"bgv.ogg" SELOOP ch,"se.ogg"
ファイルを指定して一周再生する。 BGMPLAYONCE "bgm.ogg" SEPLAY ch,"se.ogg" VOICEPLAY "voice.ogg"{,spd}
再生を止める。 BGMSTOP BGVPLAY ch,"" SESTOP ch
SESTOPALL
VOICEPLAY ""
ボリュームを設定する。 BGMVOLUME vol BGVVOLUME vol SEVOLUME vol VOICEVOLUME vol
ボリュームを個別に設定する。 SECHVOLUME ch,vol
ボリューム設定を取得する。 GETBGMVOLUME GETBGVVOLUME GETSEVOLUME GETVOICEVOLUME
フェードアウト時間設定 BGMFADEOUT milisec BGVFADEOUT milisec SEFADEOUT milisec VOICEFADEOUT milisec
  • ファイルはoggとwavで確認した。この二種がほぼデフォルトスタンダードであろうから、他は確認していない。
  • chはチャンネルで、0〜15の整数になる。これは、どの系統でも同じ。この範囲以外を指定すると、"attempt to index field '?'(a nil value)'"メッセージを出して止まる。非整数でも同様の結果になる。
  • spdは省略可能な引数で「ここに2を指定すると倍速再生になる」と説明されているが、system.luaを調べてみたところ何を指定しても倍速再生になるようになっている。倍速再生したくないのであれば、省略する以外にない。また、倍速再生のみで三倍速などはできないようだ。
  • 再生を止めるには、専用命令を使うか再生ファイル名に空文字列("")を指定するかのどちらかだ。ラッピングした専用命令を作るのもありだろう。(下記BGVPLAYSTOP等を参照)
  • ボリュームは0が最大でマイナスになるほど小さくなる。-10000で完全無音、-2000で事実上無音と説明があり、旧NScripterに慣れた人間からすると直観的ではない。
  • NScripter公式掲示板に対処法があったような記憶もあるが、見つからなかったので再発明してみる。(下記、volume_transの項目を参照のこと)
  • ボリュームの設定はグローバル環境に保存されるらしく、もし、ボリュームが-10000の状態でNScripter2を終了させると、再度起動した時にはやはり-10000から始まってしまうので、無音になる。play系命令とvolume系命令は常に対になるように使用すべし。
  • また、play系命令は完全にvolume系命令と独立しているので、旧NScripterであったような「再生直後に音量設定」はしなくてもよい。
  • それぞれに「現在再生をしているかどうか」を取得する命令がないのが若干不満が残る。

bgvplaystop命令等

defsub bgvstop,"N"
defsub voicestop
@bgvplaystop
	param %ch
	bgvplay %ch,""
return
@voicestop
	voiceplay ""
return

volume_trans命令

第一引数は変換後のボリューム値を返す変数名。第二引数は、旧NScripterでお馴染みの0〜100のボリューム値。

defsub volume_trans,"RN"
@volume_trans
	param %ret,%nscr_vol
	%vol = -10000
	if %nscr_vol>0 then %vol = 33.2*log10(%nscr_vol/100)*100
	if %vol>0 then %vol=0
	if %vol<-10000 then %vol=10000
	vset %ret,%vol
return

システムに対する雑感

BGV系とVOICE系の追加は、なるほどと思う。
BGVは一部のゲームでやっている仕様で、サービスシーンで「BGMと平行してずっと荒い吐息が聞こえる」などの演出を意識したシステムだろう。
VOICE系はSE系から独立させて独自の処理を加えている。VOICEが再生されると、BGVが一時止まるようになっている。逆に、VOICEが終了するとBGVが再開される。
この仕様はよく考えられているとは思うが、VOICEのチャンネルが一つしかないのはこれからの時代若干ネックになることを予想する。
と言うのは、最近ではボイスの多重再生をするシステムが存在するからだ。ボイスの多いシナリオで、プレイヤーがクリックを連打すると、従来のシステムではボイスの頭部分だけが再生されるような状態になる。これを多重再生を許すシステムにすると、全てのボイスを曲がりなりにも聞くことができる。多重再生を許すかどうかは、コンフィグによることが多い。
現状のsystem.luaでは、この多重再生が難しいので、手を加える必要があるだろう。

低水準サウンド機能について。

基本的には、SOUND命令でチャンネルを作り、SPLAYでそのチャンネルにファイルを結びつけて再生し、SSTOPで停止、SDELETEでチャンネルを破棄すると言う流れになる。
とは言え、SDELETEを使う機会がそれほどあるとは思えないが。
当然ながら、SOUND命令で作成していないチャンネル名を指定した場合、エラーになる。
重要なのはSISPLAYINGで、チャンネル名を指定してそのチャンネルが現在再生中かどうかを取得できること。
高水準サウンド機能では内部的にチャンネル名を使用していて、以下のチャンネル名を使用すれば、現在再生中かどうかを判定できる。

BGM
BGM0とBGM1
BGV
BGV0…BGV15
SE
SE0…SE15
VOICE
VOICE

ちなみに、BGMは「新しいファイルを指定すると、従来をフェードアウトさせつつ新しいファイルをフェードイン再生させる」と言う仕様を満たすため、二つのチャンネルを使用している。
また、SPAN、SPAUSE、SRESUMEなどでもこのチャンネル名を使えるので、ボイスなどで「舞台上手から声が聞こえる」などの演出も可能になる。
SVOLUMEなどは注意が必要で、BGMVOLUMEなどで指定したボリュームは別に保存されているので、うかつにSVOLUMEを使うと設定値と実値に乖離が生じるため、バグの元になりやすい。
先に上げたVOICEの多重再生などを考えると、VOICE0などの別のチャンネルを作成して対処すべきかも。

2012/10/19追記

コメントで指摘のあった件、リンク先(http://d.hatena.ne.jp/AtelierDeMuguet/20100203/1265193901)の式を実装してみた。

defsub volume_trans
@volume_trans
	param %ret,%nscr_vol
	%vol = -10000
	if %nscr_vol>0 then %vol = ( %nscr_vol - 100 ) * 24.9
	vset %ret,%vol
return

聴き比べてみたんだけどよくわからない俺の耳は節穴。もし使うのであれば、自分で確かめて使ってください。

さらに追記

SPANの実験してたら、system.luaに明確なエラーがあったので連絡しようそうしよう。
……んで、SPANなんだけど、やっぱり俺の耳が悪いのか本当に動いているのかよくわからない。環境のせいか?