# num2wav.pl # 参考 # http://www.kk.iij4u.or.jp/~kondo/wave/ # http://www.angel.ne.jp/~mike/about_mp3/riff_wave.html # # pack ('I', $num) ... unsigned int # pack ('C', $num) ... unsigned char # pack ('s', $num) ... signed short &error ("2 つの引数 (入力ファイル、出力ファイル) が必須です") if $ARGV[1] eq ''; $input = $ARGV[0]; $output = $ARGV[1]; &error ("ファイル $output は既に存在します") if -e $output; open (IN, $input) || &error ("入力ファイル $input を開けません"); open (OUT, "+>$output") || &error ("出力ファイル $config を書き込みオープンできません"); binmode OUT; $head = ; ($head =~ /^num2wav\t(\d+)ch\t(\d+)Hz\t(\d+)bit/) || &error ("入力ファイル $input の書式が間違っています"); ($ch, $Hz, $bit) = ($1, $2, $3); $size_of_fmtchunk = pack ('a4', pack ('I', 16)); # リニア PCM 決め打ち $format_id = pack ('a2', pack ('I', 1)); # リニア PCM 決め打ち $number_of_channel = pack ('a2', pack ('I', $ch)); $sampling_rate = pack ('a4', pack ('I', $Hz)); $data_rate = pack ('a4', pack ('I', $ch * $Hz * $bit / 8)); $block_size = pack ('a2', pack ('I', $ch * $bit / 8)); $quantization_bit_rate = pack ('a2', pack ('I', $bit)); print OUT 'RIFF' # RIFF ヘッダ . '....' # ファイルサイズ -8 Bytes . 'WAVE' # WAVE ヘッダ . 'fmt ' # fmt チャンク . $size_of_fmtchunk # fmt チャンクのサイズ . $format_id # フォーマット ID . $number_of_channel # チャンネル数 . $sampling_rate # サンプリングレート . $data_rate # データレート . $block_size # ブロックサイズ . $quantization_bit_rate # 量子化ビット数 . 'data' # data チャンク . '....'; # data チャンク (波形データ) のサイズ # [ファイルサイズ -44 Bytes] $samples = $1; @packtype1 = ('C', 's'); @packtype2 = ('a', 'a2'); $is16bit = ($bit == 16? 1: 0); while ($data = ) { if ($ch == 2) { ($left, $right) = split /\t/, $data; print OUT pack ($packtype2[$is16bit], pack ($packtype1[$is16bit], $left)); print OUT pack ($packtype2[$is16bit], pack ($packtype1[$is16bit], $right)); } else { print OUT pack ($packtype2[$is16bit], pack ($packtype1[$is16bit], $data)); } } $filesize = tell OUT; seek OUT, 4, 0; print OUT pack ('a4', pack ('I', $filesize - 8)); seek OUT, 40, 0; print OUT pack ('a4', pack ('I', $filesize - 44)); close OUT; close IN; sub error { print "ERROR : $_[0]\n"; exit; }