/
tune.py
executable file
·89 lines (68 loc) · 2.72 KB
/
tune.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env python3
import pymongo, sys, subprocess, time
from housepy import drawing, config, log, sound, util, osc
from mongo import db, ASCENDING
import signal_processing as sp
import numpy as np
from spectrometer import spectrum
def main(session_id):
result = db.branches.find({'session': session_id}).sort([('t', ASCENDING)])
if not result.count():
print("NO DATA!")
exit()
log.info("Start processing...")
result = list(result)
ts = [r['t'] for r in result]
rms = [r['sample'][3] for r in result]
duration = ts[-1] - ts[0]
SAMPLING_RATE = 60 # hz
log.info("DURATION %fs" % duration)
signal = sp.resample(ts, rms, duration * SAMPLING_RATE)
signal = sp.remove_shots(signal)
signal = sp.normalize(signal)
signal = sp.smooth(signal, 15)
# this number should match some lower frequency bound. ie, put this in hz.
# the smaller the number, the more it will affect small motion
# so this should be higher than the slowest motion we care about
# ie, dont care about motion over 0.5hz, which is 120 samples
trend = sp.smooth(signal, 120)
signal -= trend
signal += 0.5
atrend = sp.smooth(signal, 500)
## autocorrelation
auto = sp.autocorrelate(signal)
# this should be small -- if 60hz, fastest gesture would reasonably be half of that, so 30
peaks, valleys = sp.detect_peaks(auto, 10)
peaks = [peak for peak in peaks[1:] if peak[1] > 0.5]
partials = []
for peak in peaks:
frequency = SAMPLING_RATE / peak[0]
partial = frequency * 1000
partials.append([partial, float(peak[1])])
log.info("%d samps\t%fhz\t%f magnitude\t%f map" % (peak[0], frequency, peak[1], partial))
log.info(partials)
ctx = drawing.Context(2000, 750)
ctx.plot(auto, stroke=(0.0, 0.0, 0.0, 1.0), thickness=2.0)
for peak in peaks:
x = peak[0] / len(auto)
ctx.line(x, 0.0, x, peak[1], stroke=(1.0, 0.0, 0.0, 1.0))
ctx.output("graphs")
## audio
audio_signal = sp.make_audio(signal)
spectrum(audio_signal, SAMPLING_RATE)
AUDIO_RATE = 11025
filename = "%s.wav" % util.timestamp()
sound.write_audio(audio_signal, filename, AUDIO_RATE)
subprocess.call(["open", filename])
log.info("AUDIO DURATION %fs" % (duration / (AUDIO_RATE / SAMPLING_RATE)))
ctx = drawing.Context(2000, 750)
ctx.plot(signal, stroke=(0.0, 0.0, 0.0, 1.0), thickness=2.0)
ctx.plot(trend, stroke=(1.0, 0.0, 0.0, 1.0), thickness=2.0)
ctx.plot(atrend, stroke=(0.0, 0.0, 1.0, 1.0), thickness=2.0)
ctx.output("graphs")
log.info("--> done") # around 300ms
if __name__ == "__main__":
if len(sys.argv) < 2:
print("[SESSION_ID]")
else:
main(sys.argv[1])