Measure devel notes

From OLPC
Jump to: navigation, search

Development notes. For the official page, please see Measure


Metadata file associated with Logs

Measure Activity logs metadata file
Filename
Filename
Filename
Logname
Logname
Logname

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

Draw dotted log

context.move_to(x,y)
context.arc(x,y,r,0,2*pi)


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)

Get the XO colors

from sugar import profile
color=profile.get_color()
fill = color.get_fill_color()
stroke = color.get_stroke_color()

DSP

Filtering using sinc


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.

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()