forked from len0rd/rockbox
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
This commit is contained in:
parent
df867fa44c
commit
dc521b5d48
2 changed files with 284 additions and 121 deletions
|
@ -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 = <FILE>){
|
|
||||||
chomp $line;
|
|
||||||
$filename=$line;
|
|
||||||
#print $filename."\n";
|
|
||||||
|
|
||||||
$line = <FILE>;
|
|
||||||
$line = <FILE>;
|
|
||||||
$line =~ m/-\s([0-9\.]*)s/;
|
|
||||||
$decodetime = $1;
|
|
||||||
|
|
||||||
$line = <FILE>;
|
|
||||||
$line = <FILE>;
|
|
||||||
$line =~ m/([0-9\.]*)\%/;
|
|
||||||
$realtime = $1;
|
|
||||||
|
|
||||||
$line = <FILE>;
|
|
||||||
$line =~ m/([0-9\.]*)MHz/;
|
|
||||||
$mhz=$1;
|
|
||||||
#consume blank line
|
|
||||||
$line = <FILE>;
|
|
||||||
|
|
||||||
#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 = <FILE>){
|
|
||||||
chomp $line;
|
|
||||||
$filename=$line;
|
|
||||||
#print $filename."\n";
|
|
||||||
|
|
||||||
$line = <FILE>;
|
|
||||||
$line = <FILE>;
|
|
||||||
$line =~ m/-\s([0-9\.]*)s/;
|
|
||||||
$decodetime = $1;
|
|
||||||
|
|
||||||
$line = <FILE>;
|
|
||||||
$line = <FILE>;
|
|
||||||
$line =~ m/([0-9\.]*)\%/;
|
|
||||||
$realtime = $1;
|
|
||||||
|
|
||||||
$line = <FILE>;
|
|
||||||
$line =~ m/([0-9\.]*)MHz/;
|
|
||||||
$mhz=$1;
|
|
||||||
|
|
||||||
#consume blank line
|
|
||||||
$line = <FILE>;
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
284
utils/parse_testcodec.rb
Executable file
284
utils/parse_testcodec.rb
Executable file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue