summaryrefslogtreecommitdiffstats
path: root/utils/parse_testcodec.rb
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 /utils/parse_testcodec.rb
parentdf867fa44cfb492dac8537ba3cce090404378ef4 (diff)
downloadrockbox-dc521b5d48e11fbccbea07b450e21f63c28066ef.tar.gz
rockbox-dc521b5d48e11fbccbea07b450e21f63c28066ef.tar.bz2
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
Diffstat (limited to 'utils/parse_testcodec.rb')
-rwxr-xr-xutils/parse_testcodec.rb284
1 files changed, 284 insertions, 0 deletions
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