From dc521b5d48e11fbccbea07b450e21f63c28066ef Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Mon, 18 Oct 2010 18:55:31 +0000 Subject: Replace parse_testcodec.pl with a bit more powerful script. It can compare more than one result file at a time giving additional speedup colums, is more robust (RaaA results don't have the "MHz needed for realtime" line which is handled with this one) and has a mode to output the results in a form readable by spreadsheet software for nice graphs. Needs Ruby 1.9.x git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28305 a1c6a512-1295-4272-9138-f99709370657 --- utils/parse_testcodec.pl | 121 -------------------- utils/parse_testcodec.rb | 284 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 284 insertions(+), 121 deletions(-) delete mode 100755 utils/parse_testcodec.pl create mode 100755 utils/parse_testcodec.rb diff --git a/utils/parse_testcodec.pl b/utils/parse_testcodec.pl deleted file mode 100755 index c31b54ebd0..0000000000 --- a/utils/parse_testcodec.pl +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/perl - -#parse test codec output files and give wiki formatted results. - - -if(scalar(@ARGV) != 2 && scalar(@ARGV) != 1){ - print "Usage: parser_testcodec.pl new_results old_results (compares two results)\n". - " parser_testcodec.pl new_results (formats just one result)\n"; -} - -my %newfile; - -#open new benchmark file -open FILE, $ARGV[0]; -while ($line = ){ - chomp $line; - $filename=$line; - #print $filename."\n"; - - $line = ; - $line = ; - $line =~ m/-\s([0-9\.]*)s/; - $decodetime = $1; - - $line = ; - $line = ; - $line =~ m/([0-9\.]*)\%/; - $realtime = $1; - - $line = ; - $line =~ m/([0-9\.]*)MHz/; - $mhz=$1; - #consume blank line - $line = ; - - #store in hash - $newfile{$filename} = [$realtime, $mhz, $decodetime]; - - #| flac_5.flac | 175906 of 175906 | Decode time - 27.74s | File duration - 175.90s | 634.10% realtime | 12.61MHz | - #print "| $filename | Decode time - $decodetime"."s | $realtime"."% realtime | $mhz"."MHz |\n"; - #print "$filename\t$realtime\t$mhz\n"; - - -} - -#open old benchmark file -my %oldfile; -open FILE, $ARGV[1]; -while ($line = ){ - chomp $line; - $filename=$line; - #print $filename."\n"; - - $line = ; - $line = ; - $line =~ m/-\s([0-9\.]*)s/; - $decodetime = $1; - - $line = ; - $line = ; - $line =~ m/([0-9\.]*)\%/; - $realtime = $1; - - $line = ; - $line =~ m/([0-9\.]*)MHz/; - $mhz=$1; - - #consume blank line - $line = ; - - #store in hash - $oldfile{$filename} = [$realtime, $mhz, $decodetime]; - - - -} - -my @keylist; - -@keylist = sort {$a cmp $b} keys(%newfile); -#print for wiki -my $oldkey = "nothing_"; -foreach $key (@keylist){ - - #check if this is a new format and add the table heading - $oldkey =~ m/([a-z1-9]*)/; - - if(!($key =~ m/$1_/i)){ - print "| *MP3* |||||\n" if($key =~ m/lame/); - print "| *AAC-LC* |||||\n" if($key =~ m/nero/); - print "| *Vorbis* |||||\n" if($key =~ m/vorbis/); - print "| *WMA Standard* |||||\n" if($key =~ m/wma_/); - print "| *WAVPACK* |||||\n" if($key =~ m/wv/); - print "| *Nero AAC-HE* |||||\n" if($key =~ m/aache/); - print "| *Apple Lossless* |||||\n" if($key =~ m/applelossless/); - print "| *Monkeys Audio* |||||\n" if($key =~ m/ape/); - print "| *Musepack* |||||\n" if($key =~ m/mpc/); - print "| *FLAC* |||||\n" if($key =~ m/flac/); - print "| *Cook (RA)* |||||\n" if($key =~ m/cook/); - print "| *AC3 (A52)* |||||\n" if($key =~ m/a52/); - print "| *atrac3* |||||\n" if($key =~ m/atrac3/); - print "| *True Audio* |||||\n" if($key =~ m/true/); - print "| *MP2* |||||\n" if($key =~ m/toolame/); - #potiential future rockbox codecs - print "| *atrac* |||||\n" if($key =~ m/atrac1/); - print "| *WMA Professional* |||||\n" if($key =~ m/wmapro/); - print "| *WMA Lossless* |||||\n" if($key =~ m/wmal/); - - } - - if(defined($oldfile{$key})){ - $str=sprintf("%1.2f",($oldfile{$key}->[1]-$newfile{$key}->[1])/$oldfile{$key}->[1]*100+100 ); - print "| $key | $newfile{$key}->[0]"."% realtime | Decode time - $newfile{$key}->[2]s | ".sprintf("%2.2f",$newfile{$key}->[1])."MHz | ".$str."%|\n"; - }elsif(scalar(@ARGV) ==2){ - print "| $key | $newfile{$key}->[0]"."% realtime | Decode time - $newfile{$key}->[2]s | $newfile{$key}->[1]"."MHz | - |\n"; - } else{ - - print "| $key | ". $newfile{$key}->[0]."% realtime | Decode time - $newfile{$key}->[2]s | ".sprintf("%2.2f",$newfile{$key}->[1])."MHz |\n"; - } - $oldkey=$key; -} \ No newline at end of file diff --git a/utils/parse_testcodec.rb b/utils/parse_testcodec.rb new file mode 100755 index 0000000000..9a2a6e9170 --- /dev/null +++ b/utils/parse_testcodec.rb @@ -0,0 +1,284 @@ +#!/usr/bin/ruby +# (c) 2010 by Thomas Martitz +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +# +# parse test codec output files and give wiki or spreadsheet formatted output +# +class CodecResult + include Comparable +private + + attr_writer :codec + attr_writer :decoded_frames + attr_writer :max_frames + attr_writer :decode_time + attr_writer :file_duration + attr_writer :percent_realtime + attr_writer :mhz_needed + + def get_codec(filename) + case filename + when /.+aache.+/, /nero_he_.+/ + self.codec = "Nero AAC-HE" + when /a52.+/ + self.codec = "AC3 (A52)" + when /ape_.+/ + self.codec = "Monkey Audio" + when /lame_.+/ + self.codec = "MP3" + when /.+\.m4a/ + self.codec = "AAC-LC" + when /vorbis.+/ + self.codec = "Vorbis" + when /wma_.+/ + self.codec = "WMA Standard" + when /wv_.+/ + self.codec = "WAVPACK" + when /applelossless.+/ + self.codec = "Apple Lossless" + when /mpc_.+/ + self.codec = "Musepack" + when /flac_.+/ + self.codec = "FLAC" + when /cook_.+/ + self.codec = "Cook (RA)" + when /atrac3.+/ + self.codec = "Atrac3" + when /true.+/ + self.codec = "True Audio" + when /toolame.+/ + self.codec = "MP2" + when /atrack1.+/ + self.codec = "Atrac1" + when /wmapro.+/ + self.codec = "WMA Professional" + when /wmal.+/ + self.codec = "WMA Lossless" + when /speex.+/ + self.codec = "Speex" + else + self.codec = "CODEC UNKNOWN (#{name})" + end + end + + def file_name=(name) + @file_name = name + get_codec(name) + end + +public + + attr_reader :file_name + attr_reader :codec + attr_reader :decoded_frames + attr_reader :max_frames + attr_reader :decode_time + attr_reader :file_duration + attr_reader :percent_realtime + attr_reader :mhz_needed + + # make results comparable, allows for simple faster/slower/equal + def <=>(other) + if self.file_name != other.file_name + raise ArgumentError, "Cannot compare different files" + end + return self.decode_time <=> other.decode_time + end + + def initialize(text_block, cpu_freq = nil) + # we need an Array + c = text_block.class + if (c != Array && c.superclass != Array) + raise ArgumentError, + "Argument must be an array but is " + text_block.class.to_s + end + + #~ lame_192.mp3 + #~ 175909 of 175960 + #~ Decode time - 8.84s + #~ File duration - 175.96s + #~ 1990.49% realtime + #~ 30.14MHz needed for realtime (not there in RaaA) + + # file name + self.file_name = text_block[0] + + # decoded & max frames + test = Regexp.new(/(\d+) of (\d+)/) + res = text_block[1].match(test) + self.decoded_frames = res[1].to_i + self.max_frames = res[2].to_i + + # decode time, in centiseconds + test = Regexp.new(/Decode time - ([.\d]+)s/) + self.decode_time = text_block[2].match(test)[1].to_f + + # file duration, in centiseconds + test = Regexp.new(/File duration - ([.\d]+)s/) + self.file_duration = text_block[3].match(test)[1].to_f + + # % realtime + self.percent_realtime = text_block[4].to_f + + # MHz needed for rt + test = Regexp.new(/[.\d]+MHz needed for realtime/) + self.mhz_needed = nil + if (text_block[5] != nil && text_block[5].length > 0) + self.mhz_needed = text_block[5].match(test)[1].to_f + elsif (cpu_freq) + # if not given, calculate it as per passed cpu frequency + # duration to microseconds + speed = self.file_duration / self.decode_time + self.mhz_needed = cpu_freq / speed + end + end +end + +class TestCodecResults < Array + def initialize(file_name, cpu_freq) + super() + temp = self.clone + # go through the results, create a CodecResult for each block + # of text (results for the codecs are seperated by an empty line) + File.open(file_name, File::RDONLY) do |file| + file.each_chomp do |line| + if (line.length == 0) then + self << CodecResult.new(temp, cpu_freq);temp.clear + else + temp << line + end + end + end + end + + # sort the results by filename (so files of the same codec are near) + def sort + super { |x, y| x.file_name <=> y.file_name } + end +end + +class File + # walk through each line but have the \n removed + def each_chomp + self.each_line do |line| + yield(line.chomp) + end + end +end + +class Float + alias_method(:old_to_s, :to_s) + # add the ability to use a different decimal seperator in to_s + def to_s + string = old_to_s + string.sub!(/[.]/ , @@dec_sep) if @@dec_sep + string + end + + @@dec_sep = nil + def self.decimal_seperator=(sep) + @@dec_sep=sep + end +end + +#files is an Array of TestCodecResultss +def for_calc(files) + files[0].each_index do |i| + string = files[0][i].file_name + "\t" + for f in files + string += f[i].percent_realtime.to_s + "%\t" + end + puts string + end +end + +#files is an Array of TestCodecResultss +def for_wiki(files) + basefile = files.shift + codec = nil + basefile.each_index do |i| res = basefile[i] + # make a joined row for each codec + if (codec == nil || res.codec != codec) then + codec = res.codec + puts "| *%s* ||||%s" % [codec, "|"*files.length] + end + row = sprintf("| %s | %.2f%%%% realtime | Decode time - %.2fs |" % + [res.file_name, res.percent_realtime, res.decode_time]) + if (res.mhz_needed != nil) # column for mhz needed, | - | if unknown + row += sprintf(" %.2fMHz |" % res.mhz_needed.to_s) + else + row += " - |" + end + for f in files # calculate speed up compared to the rest files + delta = (res.percent_realtime / f[i].percent_realtime)*100 + row += sprintf(" %.2f%%%% |" % delta) + end + puts row + end +end + +# for_xml() anyone? :) + +def help + puts "#{$0} [OPTIONS] FILE [FILES]..." + puts "Options:\t-w\tOutput in Fosswiki format (default)" + puts "\t\t-c\tOutput in Spreadsheet-compatible format (tab-seperated)" + puts "\t\t-s=MHZ\tAssume MHZ cpu frequency for \"MHz needed for realtime\" calculation" + puts "\t\t\t(if not given by the log files, e.g. for RaaA)" + puts "\t\t-d=CHAR\tUse CHAR as decimal seperator in the -c output" + puts "\t\t\t(if your spreadsheed tool localized and making problems)" + puts + puts "\tOne file is needed. This is the basefile." + puts "\tIn -c output, the % realtime values of each" + puts "\tcodec from each file is printed on the screen onto the screen" + puts "\tIn -w output, a wiki table is made from the basefile with one column" + puts "\tfor each additional file representing relative speed of the basefile" + exit +end + +to_call = method(:for_wiki) +mhz = nil +files = [] + +help if (ARGV.length == 0) + +ARGV.each do |e| + a = e.chars.to_a + if (a[0] == '-') # option + case a[1] + when 'c' + to_call = method(:for_calc) + when 'w' + to_call = method(:for_wiki) + when 'd' + if (a[2] == '=') + sep = a[3] + else + sep = a[2] + end + Float.decimal_seperator = sep + when 's' + if (a[2] == '=') + mhz = a[3..-1].join.to_i + else + mhz = a[2..-1].join.to_i + end + else + help + end + else # filename + files << e + end +end + + +tmp = [] +for file in files do + tmp << TestCodecResults.new(file, mhz).sort +end +to_call.call(tmp) # invoke selected method -- cgit v1.2.3