-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
executable file
·93 lines (78 loc) · 2.53 KB
/
main.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
90
91
92
93
import pyaudio
import scipy.fftpack as sf
import numpy as np
import sys
import time
import subprocess
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 48000
CHUNK =2**10
AS_NEXT = b'''
tell application "Keynote"
activate
show next
end tell
'''
class SnappingDetector(object):
def __init__(self):
self.x = sf.fftfreq(CHUNK, 1.0/RATE)[:int(CHUNK/2)]
self.audio = pyaudio.PyAudio()
self.preDetect = -1
self.lastMeans = [0]
self.keynote = KeynoteControl()
def start(self, device):
self.stream = self.audio.open(
input=True,
format=FORMAT,
channels=CHANNELS,
rate=RATE,
input_device_index=device,
frames_per_buffer=CHUNK,
stream_callback=self.callback)
print ("Starting detection...")
self.stream.start_stream()
def getDevices(self):
count = self.audio.get_device_count()
devices = []
for i in range(self.audio.get_device_count()):
devices.append(self.audio.get_device_info_by_index(i))
return devices
def update(self):
self.g.curve.setData(self.x, self.y)
def callback(self, in_data, frame_count, time_info, status):
result = sf.fft(np.fromstring(in_data, dtype=np.int16))
self.y = np.abs(result)[:int(CHUNK/2)]
mean = np.mean(self.y)
var = np.var(self.y)
meansMean = np.mean(self.lastMeans)
freqMean = np.mean(self.x * self.y) / mean
if self.preDetect == -1:
if 8000 < freqMean and freqMean < 12000 and 10.0*meansMean < mean and 10000 < mean and 200000000 < var:
self.preDetect = mean
self.preDetectTime = time.time()
elif self.preDetectTime + 0.2 < time.time():
if mean < self.preDetect:
print('Patchin!')
self.keynote.next()
self.preDetect = -1
if 10 <= len(self.lastMeans):
self.lastMeans.pop(0)
self.lastMeans.append(mean)
return (None, pyaudio.paContinue)
class KeynoteControl(object):
def __init__(self):
return
def next(self):
osa = subprocess.Popen('osascript', stdin = subprocess.PIPE)
osa.stdin.write(AS_NEXT)
osa.stdin.close()
if __name__ == '__main__':
a = SnappingDetector()
for i, device in enumerate(a.getDevices()):
print(i, device['name'])
device = input('input device ID > ')
a.start(int(device))
inputStr = ""
while inputStr == "":
inputStr = input()