CDイメージのロスレス圧縮とmp3エンコード手順
- CDをドライブに入れて、EACで「アクション - CDイメージをコピーしCUEシートを作成」で hoge.wav + hoge.cue を作る。cueファイルにタグ情報も含まれるが、年は入らない。
- WavPack で hoge.wavを hoge.wv に変換する。この状態でもfoobar2kで(compornentがあれば)聴ける。
- acdir で hoge.wv+hoge.cue をトラックごとのmp3に変換する。
必要なもの
コマンドライン詳細
…毎回叩くの面倒そうだったんでperlスクリプトにしますた。
#!perl -w use strict; use warnings; use Getopt::Long; ############ # オプション類 our $verbose=0; our $lame = 'F:\\oyama\\bin\\razorlame111\\lame.exe --preset extreme --athaa-sensitivity 9 --lowpass 20 --lowpass-width 1 --add-id3v2 --pad-id3v2 --id3v2-only'; our $acdir = 'F:\\oyama\\bin\\acdir-0.12\\acdir.exe'; our $wavpack = 'F:\\oyama\\bin\\wavpack\\wavpack.exe -h -m -q'; our $flac = '"D:\\Program Files\\FLAC\\flac.exe" -s -6 -V '; sub usage(@){ @_ and warn join("\n",@_),"\n"; die <<"END"; usage: $0 wv *.wav \n\t.wav => .wv (using wavpack) $0 flac *.wav \n\t.wav => .flac (using flac) $0 v2m *.cue \n\t.cue + .wv => .mp3 (using acdir,lame) $0 f2m *.cue \n\t.cue + .flac => .mp3 (using acdir,lame) options: --acdir <string> \n\tset path and option. default: $acdir --lame <string> \n\tset path and option. default: $lame --wavpack <string>\n\tset path and option. default: $wavpack --flac <string> \n\tset path and option. default: $flac END } sub parse_options(){ GetOptions( "verbose:+",\$verbose, "wavpack=s",\$wavpack, "acdir=s" ,\$acdir, "flac=s" ,\$flac, "lame=s" ,\$lame, ) or usage "bad options.\n"; } ############ sub cmd($){ my($cmd)=@_; warn "## $cmd\n"; system $cmd; return 1 if $?==0; if( $? == -1 ){ warn "NG failed to execute: $!\n"; } elsif( $? & 127 ){ printf STDERR "NG child died with signal %d, %s coredump\n",($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf STDERR "NG child exited with value %d\n", $? >> 8; } return 0; } our $count=0; sub findfiles($$$){ my($mask,$rList,$callback)=@_; for(@ARGV){ for (glob (-d $_)?"$_\\$mask":$_){ eval{ $callback->($_); }; $@ and warn $@; ++$count; } } } sub wav_compress($$$){ my($action,$rList,$ext,$exec)=@_; findfiles("*.wav",$rList,sub{ my($src)=@_; my $dst=$src; $dst =~ s/\.wav$/\.$ext/; my $cue=$src; $cue =~ s/\.wav$/\.cue/; # 両方ある時は処理しない (-e $dst) and die "?? both $src and .$ext exists\n"; # *.cue があれば--cuesheetオプションを付ける $cue = (-e $cue )?qq( --cuesheet "$cue"):''; ($ext eq 'flac') or $cue=''; # flacのみ対応 # 変換してみる (cmd qq($exec$cue "$src")) and die "OK convert $src to .$ext\n"; # 失敗したら出力ファイルを消してみる if(-e $dst ){ unlink($dst) or warn "NG cannot delete $dst :$!\n"; } }); } sub call_acdir{ my($action,$rList,$srcext)=@_; my $tmp="tmp.cue"; findfiles("*.cue",$rList,sub{ my($cue)=@_; # 拡張子$srcext のファイル my $src=$cue; $src =~ s/\.cue$/\.$srcext/; # 存在確認 (-f $cue ) or die "NG $cue is not regular file\n"; (-f $src ) or die "NG $src is not regular file\n"; warn qq(__ found "$cue" "$src"\n); # cue ファイルを一部変更する open(IN ,$cue) or die "NG $cue $!\n"; open(OUT,">$tmp") or die "NG $tmp $!\n"; binmode IN; binmode OUT; while(<IN>){ s/^FILE "([^"]*)" WAVE/FILE "$src" WAVE/; print OUT; } close(IN) or die "NG $cue $!\n"; close(OUT) or die "NG $tmp $!\n"; #acdirを実行する my $cmd=qq($acdir --output "\$~a-\$~T-\$n\$~t.mp3" --pipe "$lame \$x --tt \$#t --ta \$#a --tl \$#T --tn \$#n - \$#o" $tmp); (cmd $cmd) and die "OK.\n"; }); if(-e $tmp){ (unlink $tmp) or warn "NG unlink $tmp :$!\n";} } ############ if(not caller){ parse_options; @ARGV or usage; my $action = lc shift; for( ['wv' ,\&wav_compress,'wv' ,$wavpack], ['flac' ,\&wav_compress,'flac',$flac ], ['v2m' ,\&call_acdir ,'wv' ], ['f2m' ,\&call_acdir ,'flac'], ){ my($act,$func,@extra)=@$_; if($act eq $action){ $func->($act,\@ARGV,@extra); warn "__ $count files proccessed.\n"; exit; } } usage "NG unsupported action $action\n"; }