Measure devel notes
From OLPC
Development notes. For the official page, please see Measure
Contents |
[edit] Metadata file associated with Logs
Measure Activity logs metadata file Filename Filename Filename Logname Logname Logname
[edit] Log file format
FIXME: There is no reliable way for the "file" command to identify this data format. It is not clear what parts of this description are to be actually in the file; for example if the first line has 4 "/" characters or if that notation indicates alternatives. It is not clear if "minute" is a 6-character word that should appear in the file or if it is supposed to be a number, etc. The word "stop" at the end will mildly complicate both generators and consumers of this file format. Future extensions are neither prohibited nor defined; it is anyone's guess what might be valid in the future. If I guess the format right, it appears that the three discrete rate choices (a limitation of the current Measure activity) have been enshrined into the data file format. The y_mag and g values, both undocumented, appear to be display-related rather than data-related and thus do not belong in the file.
sec/minute/hour/snapshot time/freq y_mag g freq_range ( l / m /h) 2232 3445 ... ... stop
[edit] Draw dotted log
context.move_to(x,y) context.arc(x,y,r,0,2*pi)
[edit] Convert #RRGGBB to an (R, G, B) tuple
colorstring = colorstring.strip() if colorstring[0] == '#': colorstring = colorstring[1:] r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:] r, g, b = [int(n, 16) for n in (r, g, b)] return (r, g, b)
[edit] Get the XO colors
from sugar import profile color=profile.get_color() fill = color.get_fill_color() stroke = color.get_stroke_color()
[edit] DSP
[edit] Filtering using sinc
- http://www.dspguide.com/ch16/2.htm
- I will precompute h[i] for all the three ranges and apply it to all the three ranges
- See [[1]]
[edit] Scaling - for scale display, and RMS values
- I get a buffer of 16bit values (-32768 to 32768). I need to calculate the corresponding rms value of the voltage
- The correspondence between digital domain values and physical values has been found out experimentally as
v = (m/g)*(s) + 1180 millivolts
where s is a sample value ranging from -32768 to +32768 where m = .0238(i.e. slope when all capture gains are 0dB i.e. g=1) where g is the gain introduced by capture gains. There are two such gains Mic Boost +20dB and Capture Gain. Note that g IS NOT in dB.
- Also let k = m/g and c = 1180
- One option is to scale each sample in voltage domain (which would come out to be a float value) to get rms voltage, Rv = sqrt(sigma(Vi^2)) / N
- The other option is to calculate RMS of all samples s and then convert result to equivalent voltage
- For calculating RMS of samples s and then converting to Rv
- sigma(Vi^2) = (k^2)*(sigma(Xi^2)) + N*c^2 + 2*k*c*sigma(Xi)
- Once we have sigma(Vi^2) we can take square root of that and divide by N
- The big question is which one would be better suited in terms of performance overheads on the XO ? <-- profiling is the answer ?
- You can get rid of the floating point and the division if Python does OK with 64-bit numbers. You do something like this...
G = 1000/g V = s*238*G + 1180*10000000 v = V/10000000
- ...except that you don't immediately divide to get v, and you don't use 10000000. Use 2**32 instead, allowing a 32-bit right shift (free) instead of the division. (so the 1000 has to change, and you don't do .0238*10000 but rather something else appropriate) You may also delay that right shift, adding up the numbers first.
[edit] Profiling
import os
import cProfile
import lsprofcalltree
self._profiler = cProfile.Profile()
self._profiler.enable()
#code to profile#
self._profiler.disable()
k = lsprofcalltree.KCacheGrind(self._profiler)
data = open(os.path.expanduser('/tmp/measure.kgrind'), 'w+')
k.output(data)
data.close()

