@set @EXIT_SUCCESS = 0
@set @EXIT_FAILURE = 1
@set @DEFAULT_RMS_PEAK_DB = -12
var Opt = new struct_options();
main();
exit();
function echo(text)
{
Script.Echo(text);
}
function exit(exit_code)
{
Script.Quit(exit_code);
}
function print_usage(error_msg)
{
echo(Script.ScriptName);
echo(" [peak_level] [/rms | /srms] [/force]");
echo();
echo(" peak_level ピーク レベル指定 (dB)。既定は瞬間ピークなら 0,");
echo(" rms なら " + @DEFAULT_RMS_PEAK_DB + "。");
echo(" /rms rms ピーク レベルを指定レベルにする。");
echo(" /srms 局所 rms ピーク レベルを指定レベルにする。");
echo(" /force 瞬間ピーク レベルが 1 を超えるのを容認する。");
echo();
}
function struct_options()
{
this.Peak = 1.0;
this.Rms = false;
this.SRms = false;
this.Force = false;
}
function read_options()
{
var args = Script.Arguments;
if (args.Named.Exists("?")) {
print_usage();
exit(@EXIT_FAILURE);
}
var e, key;
for (e = new Enumerator(args.Named); !e.atEnd(); e.moveNext()) {
key = e.item().toLowerCase();
if (key == "rms") {
Opt.Rms = true;
Opt.SRms = false;
}
else if (key == "srms") {
Opt.Rms = false;
Opt.SRms = true;
}
else if (key == "force")
Opt.Force = true;
else {
echo("エラー: 不明なオプション " + e.item());
exit(@EXIT_FAILURE);
}
}
var peak_db = 0;
if (Opt.Rms || Opt.SRms)
peak_db = @DEFAULT_RMS_PEAK_DB;
if (args.Unnamed.length) {
if (args.Unnamed.length > 1) {
echo("エラー: コマンド ライン オプションが多すぎます。");
exit(@EXIT_FAILURE);
}
peak_db = parseFloat(args.Unnamed(0));
if (isNaN(peak_db) || (peak_db > 0)) {
echo("エラー: ピーク レベルは負数の dB で指定してください。");
exit(@EXIT_FAILURE);
}
}
Opt.Peak = Math.pow(10, peak_db / 20);
}
function main()
{
read_options();
var e, doc, wi;
var ch, peak, gain, tmp;
for (e = new Enumerator(Application.Documents); !e.atEnd(); e.moveNext()) {
doc = e.item();
echo(doc.Title);
if (Opt.SRms)
doc.AddOffset();
doc.SelectionFrom = 0;
doc.SelectionTo = doc.Length;
wi = doc.GetWaveformInfo();
peak = 0;
for (ch = 0; ch < doc.Channels; ++ch) {
tmp = Math.abs(wi("InstantMax", ch) - wi("Offset", ch));
if (peak < tmp)
peak = tmp;
tmp = Math.abs(wi("InstantMin", ch) - wi("Offset", ch));
if (peak < tmp)
peak = tmp;
}
if (!Opt.SRms)
doc.AddOffset(-wi("Offset", 0), -wi("Offset", 1));
if (peak < 1e-5)
continue;
if (Opt.Rms) {
tmp = 0;
for (ch = 0; ch < doc.Channels; ++ch)
tmp += wi("Variance", ch);
gain = Opt.Peak / Math.sqrt(tmp / doc.Channels);
}
else if (Opt.SRms)
gain = Opt.Peak / wi("ShortRmsPeak");
else
gain = Opt.Peak / peak;
if (!Opt.Force) {
if (peak * gain > 1)
gain = 1 / peak;
}
doc.AddGain(gain);
}
exit(@EXIT_SUCCESS);
}