summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-10-18 18:55:31 +0000
committerThomas Martitz <kugel@rockbox.org>2010-10-18 18:55:31 +0000
commitdc521b5d48e11fbccbea07b450e21f63c28066ef (patch)
tree2c9be086996b587496c468fcbd3cbaad80ff3e77
parentdf867fa44cfb492dac8537ba3cce090404378ef4 (diff)
downloadrockbox-dc521b5d48e11fbccbea07b450e21f63c28066ef.tar.gz
rockbox-dc521b5d48e11fbccbea07b450e21f63c28066ef.zip
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
-rwxr-xr-xutils/parse_testcodec.pl121
-rwxr-xr-xutils/parse_testcodec.rb284
2 files changed, 284 insertions, 121 deletions
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 @@
1#!/usr/bin/perl
2
3#parse test codec output files and give wiki formatted results.
4
5
6if(scalar(@ARGV) != 2 && scalar(@ARGV) != 1){
7 print "Usage: parser_testcodec.pl new_results old_results (compares two results)\n".
8 " parser_testcodec.pl new_results (formats just one result)\n";
9}
10
11my %newfile;
12
13#open new benchmark file
14open FILE, $ARGV[0];
15while ($line = <FILE>){
16 chomp $line;
17 $filename=$line;
18 #print $filename."\n";
19
20 $line = <FILE>;
21 $line = <FILE>;
22 $line =~ m/-\s([0-9\.]*)s/;
23 $decodetime = $1;
24
25 $line = <FILE>;
26 $line = <FILE>;
27 $line =~ m/([0-9\.]*)\%/;
28 $realtime = $1;
29
30 $line = <FILE>;
31 $line =~ m/([0-9\.]*)MHz/;
32 $mhz=$1;
33 #consume blank line
34 $line = <FILE>;
35
36 #store in hash
37 $newfile{$filename} = [$realtime, $mhz, $decodetime];
38
39 #| flac_5.flac | 175906 of 175906 | Decode time - 27.74s | File duration - 175.90s | 634.10% realtime | 12.61MHz |
40 #print "| $filename | Decode time - $decodetime"."s | $realtime"."% realtime | $mhz"."MHz |\n";
41 #print "$filename\t$realtime\t$mhz\n";
42
43
44}
45
46#open old benchmark file
47my %oldfile;
48open FILE, $ARGV[1];
49while ($line = <FILE>){
50 chomp $line;
51 $filename=$line;
52 #print $filename."\n";
53
54 $line = <FILE>;
55 $line = <FILE>;
56 $line =~ m/-\s([0-9\.]*)s/;
57 $decodetime = $1;
58
59 $line = <FILE>;
60 $line = <FILE>;
61 $line =~ m/([0-9\.]*)\%/;
62 $realtime = $1;
63
64 $line = <FILE>;
65 $line =~ m/([0-9\.]*)MHz/;
66 $mhz=$1;
67
68 #consume blank line
69 $line = <FILE>;
70
71 #store in hash
72 $oldfile{$filename} = [$realtime, $mhz, $decodetime];
73
74
75
76}
77
78my @keylist;
79
80@keylist = sort {$a cmp $b} keys(%newfile);
81#print for wiki
82my $oldkey = "nothing_";
83foreach $key (@keylist){
84
85 #check if this is a new format and add the table heading
86 $oldkey =~ m/([a-z1-9]*)/;
87
88 if(!($key =~ m/$1_/i)){
89 print "| *MP3* |||||\n" if($key =~ m/lame/);
90 print "| *AAC-LC* |||||\n" if($key =~ m/nero/);
91 print "| *Vorbis* |||||\n" if($key =~ m/vorbis/);
92 print "| *WMA Standard* |||||\n" if($key =~ m/wma_/);
93 print "| *WAVPACK* |||||\n" if($key =~ m/wv/);
94 print "| *Nero AAC-HE* |||||\n" if($key =~ m/aache/);
95 print "| *Apple Lossless* |||||\n" if($key =~ m/applelossless/);
96 print "| *Monkeys Audio* |||||\n" if($key =~ m/ape/);
97 print "| *Musepack* |||||\n" if($key =~ m/mpc/);
98 print "| *FLAC* |||||\n" if($key =~ m/flac/);
99 print "| *Cook (RA)* |||||\n" if($key =~ m/cook/);
100 print "| *AC3 (A52)* |||||\n" if($key =~ m/a52/);
101 print "| *atrac3* |||||\n" if($key =~ m/atrac3/);
102 print "| *True Audio* |||||\n" if($key =~ m/true/);
103 print "| *MP2* |||||\n" if($key =~ m/toolame/);
104 #potiential future rockbox codecs
105 print "| *atrac* |||||\n" if($key =~ m/atrac1/);
106 print "| *WMA Professional* |||||\n" if($key =~ m/wmapro/);
107 print "| *WMA Lossless* |||||\n" if($key =~ m/wmal/);
108
109 }
110
111 if(defined($oldfile{$key})){
112 $str=sprintf("%1.2f",($oldfile{$key}->[1]-$newfile{$key}->[1])/$oldfile{$key}->[1]*100+100 );
113 print "| $key | $newfile{$key}->[0]"."% realtime | Decode time - $newfile{$key}->[2]s | ".sprintf("%2.2f",$newfile{$key}->[1])."MHz | ".$str."%|\n";
114 }elsif(scalar(@ARGV) ==2){
115 print "| $key | $newfile{$key}->[0]"."% realtime | Decode time - $newfile{$key}->[2]s | $newfile{$key}->[1]"."MHz | - |\n";
116 } else{
117
118 print "| $key | ". $newfile{$key}->[0]."% realtime | Decode time - $newfile{$key}->[2]s | ".sprintf("%2.2f",$newfile{$key}->[1])."MHz |\n";
119 }
120 $oldkey=$key;
121} \ 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 @@
1#!/usr/bin/ruby
2# (c) 2010 by Thomas Martitz
3#
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 2 of the License, or
7# (at your option) any later version.
8
9#
10# parse test codec output files and give wiki or spreadsheet formatted output
11#
12class CodecResult
13 include Comparable
14private
15
16 attr_writer :codec
17 attr_writer :decoded_frames
18 attr_writer :max_frames
19 attr_writer :decode_time
20 attr_writer :file_duration
21 attr_writer :percent_realtime
22 attr_writer :mhz_needed
23
24 def get_codec(filename)
25 case filename
26 when /.+aache.+/, /nero_he_.+/
27 self.codec = "Nero AAC-HE"
28 when /a52.+/
29 self.codec = "AC3 (A52)"
30 when /ape_.+/
31 self.codec = "Monkey Audio"
32 when /lame_.+/
33 self.codec = "MP3"
34 when /.+\.m4a/
35 self.codec = "AAC-LC"
36 when /vorbis.+/
37 self.codec = "Vorbis"
38 when /wma_.+/
39 self.codec = "WMA Standard"
40 when /wv_.+/
41 self.codec = "WAVPACK"
42 when /applelossless.+/
43 self.codec = "Apple Lossless"
44 when /mpc_.+/
45 self.codec = "Musepack"
46 when /flac_.+/
47 self.codec = "FLAC"
48 when /cook_.+/
49 self.codec = "Cook (RA)"
50 when /atrac3.+/
51 self.codec = "Atrac3"
52 when /true.+/
53 self.codec = "True Audio"
54 when /toolame.+/
55 self.codec = "MP2"
56 when /atrack1.+/
57 self.codec = "Atrac1"
58 when /wmapro.+/
59 self.codec = "WMA Professional"
60 when /wmal.+/
61 self.codec = "WMA Lossless"
62 when /speex.+/
63 self.codec = "Speex"
64 else
65 self.codec = "CODEC UNKNOWN (#{name})"
66 end
67 end
68
69 def file_name=(name)
70 @file_name = name
71 get_codec(name)
72 end
73
74public
75
76 attr_reader :file_name
77 attr_reader :codec
78 attr_reader :decoded_frames
79 attr_reader :max_frames
80 attr_reader :decode_time
81 attr_reader :file_duration
82 attr_reader :percent_realtime
83 attr_reader :mhz_needed
84
85 # make results comparable, allows for simple faster/slower/equal
86 def <=>(other)
87 if self.file_name != other.file_name
88 raise ArgumentError, "Cannot compare different files"
89 end
90 return self.decode_time <=> other.decode_time
91 end
92
93 def initialize(text_block, cpu_freq = nil)
94 # we need an Array
95 c = text_block.class
96 if (c != Array && c.superclass != Array)
97 raise ArgumentError,
98 "Argument must be an array but is " + text_block.class.to_s
99 end
100
101 #~ lame_192.mp3
102 #~ 175909 of 175960
103 #~ Decode time - 8.84s
104 #~ File duration - 175.96s
105 #~ 1990.49% realtime
106 #~ 30.14MHz needed for realtime (not there in RaaA)
107
108 # file name
109 self.file_name = text_block[0]
110
111 # decoded & max frames
112 test = Regexp.new(/(\d+) of (\d+)/)
113 res = text_block[1].match(test)
114 self.decoded_frames = res[1].to_i
115 self.max_frames = res[2].to_i
116
117 # decode time, in centiseconds
118 test = Regexp.new(/Decode time - ([.\d]+)s/)
119 self.decode_time = text_block[2].match(test)[1].to_f
120
121 # file duration, in centiseconds
122 test = Regexp.new(/File duration - ([.\d]+)s/)
123 self.file_duration = text_block[3].match(test)[1].to_f
124
125 # % realtime
126 self.percent_realtime = text_block[4].to_f
127
128 # MHz needed for rt
129 test = Regexp.new(/[.\d]+MHz needed for realtime/)
130 self.mhz_needed = nil
131 if (text_block[5] != nil && text_block[5].length > 0)
132 self.mhz_needed = text_block[5].match(test)[1].to_f
133 elsif (cpu_freq)
134 # if not given, calculate it as per passed cpu frequency
135 # duration to microseconds
136 speed = self.file_duration / self.decode_time
137 self.mhz_needed = cpu_freq / speed
138 end
139 end
140end
141
142class TestCodecResults < Array
143 def initialize(file_name, cpu_freq)
144 super()
145 temp = self.clone
146 # go through the results, create a CodecResult for each block
147 # of text (results for the codecs are seperated by an empty line)
148 File.open(file_name, File::RDONLY) do |file|
149 file.each_chomp do |line|
150 if (line.length == 0) then
151 self << CodecResult.new(temp, cpu_freq);temp.clear
152 else
153 temp << line
154 end
155 end
156 end
157 end
158
159 # sort the results by filename (so files of the same codec are near)
160 def sort
161 super { |x, y| x.file_name <=> y.file_name }
162 end
163end
164
165class File
166 # walk through each line but have the \n removed
167 def each_chomp
168 self.each_line do |line|
169 yield(line.chomp)
170 end
171 end
172end
173
174class Float
175 alias_method(:old_to_s, :to_s)
176 # add the ability to use a different decimal seperator in to_s
177 def to_s
178 string = old_to_s
179 string.sub!(/[.]/ , @@dec_sep) if @@dec_sep
180 string
181 end
182
183 @@dec_sep = nil
184 def self.decimal_seperator=(sep)
185 @@dec_sep=sep
186 end
187end
188
189#files is an Array of TestCodecResultss
190def for_calc(files)
191 files[0].each_index do |i|
192 string = files[0][i].file_name + "\t"
193 for f in files
194 string += f[i].percent_realtime.to_s + "%\t"
195 end
196 puts string
197 end
198end
199
200#files is an Array of TestCodecResultss
201def for_wiki(files)
202 basefile = files.shift
203 codec = nil
204 basefile.each_index do |i| res = basefile[i]
205 # make a joined row for each codec
206 if (codec == nil || res.codec != codec) then
207 codec = res.codec
208 puts "| *%s* ||||%s" % [codec, "|"*files.length]
209 end
210 row = sprintf("| %s | %.2f%%%% realtime | Decode time - %.2fs |" %
211 [res.file_name, res.percent_realtime, res.decode_time])
212 if (res.mhz_needed != nil) # column for mhz needed, | - | if unknown
213 row += sprintf(" %.2fMHz |" % res.mhz_needed.to_s)
214 else
215 row += " - |"
216 end
217 for f in files # calculate speed up compared to the rest files
218 delta = (res.percent_realtime / f[i].percent_realtime)*100
219 row += sprintf(" %.2f%%%% |" % delta)
220 end
221 puts row
222 end
223end
224
225# for_xml() anyone? :)
226
227def help
228 puts "#{$0} [OPTIONS] FILE [FILES]..."
229 puts "Options:\t-w\tOutput in Fosswiki format (default)"
230 puts "\t\t-c\tOutput in Spreadsheet-compatible format (tab-seperated)"
231 puts "\t\t-s=MHZ\tAssume MHZ cpu frequency for \"MHz needed for realtime\" calculation"
232 puts "\t\t\t(if not given by the log files, e.g. for RaaA)"
233 puts "\t\t-d=CHAR\tUse CHAR as decimal seperator in the -c output"
234 puts "\t\t\t(if your spreadsheed tool localized and making problems)"
235 puts
236 puts "\tOne file is needed. This is the basefile."
237 puts "\tIn -c output, the % realtime values of each"
238 puts "\tcodec from each file is printed on the screen onto the screen"
239 puts "\tIn -w output, a wiki table is made from the basefile with one column"
240 puts "\tfor each additional file representing relative speed of the basefile"
241 exit
242end
243
244to_call = method(:for_wiki)
245mhz = nil
246files = []
247
248help if (ARGV.length == 0)
249
250ARGV.each do |e|
251 a = e.chars.to_a
252 if (a[0] == '-') # option
253 case a[1]
254 when 'c'
255 to_call = method(:for_calc)
256 when 'w'
257 to_call = method(:for_wiki)
258 when 'd'
259 if (a[2] == '=')
260 sep = a[3]
261 else
262 sep = a[2]
263 end
264 Float.decimal_seperator = sep
265 when 's'
266 if (a[2] == '=')
267 mhz = a[3..-1].join.to_i
268 else
269 mhz = a[2..-1].join.to_i
270 end
271 else
272 help
273 end
274 else # filename
275 files << e
276 end
277end
278
279
280tmp = []
281for file in files do
282 tmp << TestCodecResults.new(file, mhz).sort
283end
284to_call.call(tmp) # invoke selected method