clndogg.pl Ver 2.0

やはり生データを出力するだけでは物足りなくなって、標準でループに対応するようにした。一応ループ回数とフェードアウトする時間が指定できるようになってるけど、各数値は勝手に決めただけなので、各自最適な値をみつけてほしい(それを教えてくれたりするとなお嬉しい)。なお、曲名とループ開始時間はclndwavのデータを使わせてもらった。

 #!/usr/bin/perl -w

#Usage: clndogg.pl [-o outpath] infiles ...

use strict;
use vars qw($nwatowav $oggenc %title);

use Getopt::Std;

$nwatowav="./nwatowav";
$oggenc="oggenc";

%nwainfo=(
    "BGM01"  => [ 269364, 960000, 1, "町、時の流れ、人"],
    "BGM02A" => [ 297558, 960000, 1, "渚"],
    "BGM02B" => [7612858, 960000, 1, "渚〜坂の下の別れ(ゲーム用)"],
    "BGM02C" => [      0,      0, 1, "渚〜坂の下の別れ(MusicMode用)"],
    "BGM03A" => [ 165459, 960000, 1, "それは風のように"],
    "BGM04A" => [ 601260, 960000, 1, "は〜りぃすたーふぃっしゅ"],
    "BGM05A" => [ 298070, 960000, 1, "Etude pour les petites supercordes"],
    "BGM05B" => [ 162150,      0, 2, "TOE(前半)"],
    "BGM05C" => [  10569,      0, 1, "TOE(後半)"],
    "BGM05D" => [   9757,      0, 1, "TOE"],
    "BGM05E" => [  88205, 960000, 1, "Etude pour les petites supercordes(short)"],
    "BGM06"  => [  74020, 960000, 1, "彼女の本気"],
    "BGM07B" => [ 641474, 960000, 1, "資料室のお茶会"],
    "BGM08A" => [ 165080, 960000, 1, "東風 -Tempo up-"],
    "BGM08B" => [ 243803, 960000, 1, "東風 -Afternoon-"],
    "BGM08C" => [ 195701, 960000, 1, "東風"],
    "BGM08D" => [   9814, 960000, 1, "東風 -Piano-"],
    "BGM09A" => [ 214302, 960000, 1, "有意義な時間の過ごし方"],
    "BGM09B" => [ 214453, 960000, 1, "有意義な時間の過ごし方 -Guitar-"],
    "BGM09C" => [ 214139, 960000, 1, "有意義な時間の過ごし方 -Sax-"],
    "BGM10"  => [ 121368, 960000, 1, "馬鹿ふたり"],
    "BGM10B" => [ 186127, 960000, 1, "ダム"],
    "BGM11"  => [ 719220, 960000, 1, "灰燼に帰す"],
    "BGM13"  => [   9588, 960000, 1, "同じ高みへ"],
    "BGM14"  => [ 428352, 960000, 1, "田舎小径"],
    "BGM15"  => [   9683, 960000, 1, "日々の遑"],
    "BGM16A" => [ 265896, 960000, 1, "存在"],
    "BGM16B" => [3278263, 960000, 1, "存在 -Piano-"],
    "BGM16C" => [ 138712, 960000, 1, "存在 -E.Piano-"],
    "BGM20B" => [   9647, 960000, 1, "遥かな年月 -Piano-"],
    "BGM17A" => [ 240141, 960000, 1, "空に光る"],
    "BGM18A" => [   9669, 960000, 1, "潮鳴り"],
    "BGM18B" => [ 356571, 960000, 1, "潮鳴り II"],
    "BGM25B" => [ 136689, 960000, 1, "願いが叶う場所"],
    "BGM19"  => [ 173614, 960000, 1, "白詰草"],
    "BGM20A" => [   9547, 960000, 1, "遥かな年月"],
    "BGM21"  => [ 121834, 960000, 1, "夏時間"],
    "BGM23"  => [2302999, 960000, 1, "カントリートレイン"],
    "BGM24"  => [ 961245, 960000, 1, "雪野原"],
    "BGM25A" => [   9656, 960000, 1, "願いが叶う場所 II"],
    "BGM26A" => [1479991, 960000, 1, "幻想"],
    "BGM26B" => [ 815727, 960000, 1, "幻想II"],
    "BGM28"  => [ 682597, 960000, 1, "月の位相"],
    "BGM29"  => [1429243, 960000, 1, "無間"],
    "BGM30"  => [ 146841, 960000, 1, "汐"],
    "BGM31"  => [      0,      0, 1, "メグメル"],
    "BGM32A" => [ 327284, 960000, 1, "Ana"],
    "BGM32B" => [      0,      0, 1, "Ana (Long Version)"],
    "BGM33"  => [      0,      0, 1, "-影二つ-"],
    "BGM34"  => [      0,      0, 1, "小さな手のひら"],
    "BGM35"  => [      0,      0, 1, "マ・メール・ロワ"],
);

sub new_wavhdr {
    my($wavhdr,$new_data_size)=@_;
    my($riff_sig,               # [A4]"RIFF"
       $riff_size,              # [V]
       $wave_sig,               # [A4]"WAVE"
       $fmt_sig,                # [A4]"fmt "
       $fmt_size,               # [V]
       $tag,                    # [v]
       $channels,               # [v]
       $sample_per_sec,         # [V]
       $byte_per_sec,           # [V]
       $block_align,            # [v]
       $bit_per_sample,         # [v]
       $data_sig,               # [A4]
       $data_size,              # [V]
       )=unpack("A4VA4A4Vv2V2v2A4V",$wavhdr);

    return pack("A4VA4A4Vv2V2v2A4V",
                $riff_sig, $new_data_size+0x24,
                $wave_sig,
                $fmt_sig, $fmt_size,
                $tag, $channels,
                $sample_per_sec,
                $byte_per_sec,
                $block_align,
                $bit_per_sample,
                $data_sig, $new_data_size);
}

sub main {
    my(%opts,$out,$loop,$nomod);

    &getopts("o:n",\%opts);
    $out=$opts{"o"} || ".";
    $nomod=$opts{"n"};

    my($file);
    foreach $file (@ARGV) {
        my($base)=($file=~/([^\/.]+)\.nwa$/i) ? $1 : $file;

        my($info)=$nwainfo{$base};
        my($skip)=0;
        my($fadeout)=5*48000*(16/8)*2;
        my($loop)=1;
        my($title)="";
        ($skip,$fadeout,$loop,$title)=@{$info} if $info;

        print STDERR "$file: `$title'\n";

        if ($nomod) {
            $skip=0;
            $fadeout=0;
            $loop=1;
        }

        open(IN,"$nwatowav '$file' |") || die "Can't open input pipe.";
        binmode(IN);

        my($wavhdr);
        read(IN,$wavhdr,0x2c);

        my($head,$body,$tail);
        if ($skip>0) {
            read(IN,$head,$skip*4);
        } else {
            $head="";
        }

        local($/)=undef;
        $body=;

        if (($skip>0)&&($fadeout>0)) {
            $tail=substr($body,0,$fadeout);
            my($n)=$fadeout/2;
            my($i)=$n;
            $tail=pack("v*",map { $_-=0x10000 if $_&0x8000; $_*($i--)/$n; } unpack("v*",$tail));
        } else {
            $tail="";
        }

#       open(OUT,">$base.wav") || die "Can't open output file.";
        open(OUT, join(' ', "|", "$oggenc -Q",
                                    ($title ? "-t '$title'" : ""),
                                    "-o '$out/$base.ogg' -"))
            || die "Can't open output pipe.";
        binmode(OUT);
        my($size)=length($head)+length($body)*$loop+length($tail);
        print OUT &new_wavhdr($wavhdr,$size);
        print OUT $head;
        for (1..$loop) {
            print OUT $body;
        }
        print OUT $tail;
        close(OUT);

        close(IN);
    }
}
&main;