-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathframe_app.lua
More file actions
113 lines (92 loc) · 3.05 KB
/
Copy pathframe_app.lua
File metadata and controls
113 lines (92 loc) · 3.05 KB
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
local data = require('data.min')
local battery = require('battery.min')
local code = require('code.min')
local plain_text = require('plain_text.min')
-- Phone to Frame flags
TEXT_MSG = 0x12
CLEAR_MSG = 0x10
START_AUDIO_MSG = 0x30
STOP_AUDIO_MSG = 0x31
-- Frame to Phone flags
AUDIO_DATA_NON_FINAL_MSG = 0x05
AUDIO_DATA_FINAL_MSG = 0x06
-- register the message parsers so they are automatically called when matching data comes in
data.parsers[TEXT_MSG] = plain_text.parse_plain_text
data.parsers[CLEAR_MSG] = code.parse_code
data.parsers[START_AUDIO_MSG] = code.parse_code
data.parsers[STOP_AUDIO_MSG] = code.parse_code
-- Main app loop
function app_loop()
-- clear the display
frame.display.text(" ", 1, 1)
frame.display.show()
local last_batt_update = 0
local streaming = false
local audio_data = ''
local mtu = frame.bluetooth.max_length()
-- data buffer needs to be even for reading from microphone
if mtu % 2 == 1 then mtu = mtu - 1 end
while true do
-- process any raw data items, if ready
local items_ready = data.process_raw_items()
-- one or more full messages received
if items_ready > 0 then
if (data.app_data[TEXT_MSG] ~= nil and data.app_data[TEXT_MSG].string ~= nil) then
local i = 0
for line in data.app_data[TEXT_MSG].string:gmatch("([^\n]*)\n?") do
if line ~= "" then
frame.display.text(line, 1, i * 60 + 1)
i = i + 1
end
end
frame.display.show()
end
if (data.app_data[CLEAR_MSG] ~= nil) then
-- clear the display
frame.display.text(" ", 1, 1)
frame.display.show()
data.app_data[CLEAR_MSG] = nil
end
if (data.app_data[START_AUDIO_MSG] ~= nil) then
audio_data = ''
pcall(frame.microphone.start, {sample_rate=8000, bit_depth=16})
streaming = true
frame.display.text("Streaming Audio", 1, 1)
frame.display.show()
data.app_data[START_AUDIO_MSG] = nil
end
if (data.app_data[STOP_AUDIO_MSG] ~= nil) then
pcall(frame.microphone.stop)
-- clear the display
frame.display.text(" ", 1, 1)
frame.display.show()
data.app_data[STOP_AUDIO_MSG] = nil
end
end
-- send any pending audio data back
-- Streams until STOP_AUDIO_MSG is sent from phone
-- (prioritize the reading and sending about 20x compared to checking for other events e.g. STOP_AUDIO_MSG)
for i=1,20 do
if streaming then
audio_data = frame.microphone.read(mtu)
-- Calling frame.microphone.stop() will allow this to break the loop
if audio_data == nil then
-- send an end-of-stream message back to the phone
pcall(frame.bluetooth.send, string.char(AUDIO_DATA_FINAL_MSG))
frame.sleep(0.0025)
streaming = false
break
-- send the data that was read
elseif audio_data ~= '' then
pcall(frame.bluetooth.send, string.char(AUDIO_DATA_NON_FINAL_MSG) .. audio_data)
frame.sleep(0.0025)
end
end
end
-- periodic battery level updates, 120s for a camera app
last_batt_update = battery.send_batt_if_elapsed(last_batt_update, 120)
if not streaming then frame.sleep(0.1) end
end
end
-- run the main app loop
app_loop()