/
RIVA_Main.py
274 lines (248 loc) · 12.7 KB
/
RIVA_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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
__author__ = 'Nathan'
### Nathanial Benjamin, UCI, Calit2, CalPlug, 2014-Feb
# Written in Python 3.3.3 (added statistics and pydub modules)
### - Change return types for response sentances to file names for SmartBody script.
### - Hard-coded end of song summary to overall_summary #3. for the demo, as .wav concatenation is not finished yet.
### - Took name out of intro sentances for demo. for the demo, as TTS on-the-fly is not finished yet.
######################################################
# #
# MAIN #
# #
######################################################
import CSV_functions
import Mglove_str_gen
from CSV_functions import read_csv, make_csv
from Interface import gather_info, parse_csv, evaluate_worst_grip, evaluate_best_grip, what_song, \
grip_times, abs_val_list
from Mglove_str_gen import grip_avg_summary_str, summary_generator, emo_less_feedback
from Send_to_voice_server import reset_RIVA_log, text_to_RIVA, text_to_ispeech, ispeech_formatter, to_no_voice_log
from time import sleep, strftime
from user_stats import User_Stats
'''
-Fix selector to prioritize training prompts
'''
SONG_OVER_CHECK_TIME = 10
TIME_BETWEEN_FEEDBACK = 30 # Must be a multiple of SONG_OVER_CHECK_TIME
# ACCEPTABLE_ERROR_MULTIPLIER = 0.2 Replaced by get_Scale_Points
class MusicGloveSong:
def __init__(self, user, restart=False):
self. _feedback_plat = 'RIVA' # possible choices: RIVA, iSpeech, and Text
self. _grip_count = 0
self. _last_line = self._read_lastline()
self. _last_30_sec = []
self. _csv_result = []
self. _song_over = True
self. _last_worst_grip = 1
self. _RIVA_message_num = 0
self. _last_response = ''
self. _all_grips = []
self.user_stats = 'null'
# tells RIVA which side of it's screen the Musicglove screen is on
self._RIVA_focus_direction = 'right'
self.user_name = user # input("Please enter user name: ")
if restart == True:
self.user_stats = User_Stats(neg_quart=25, pos_quart=25, new_song=False)
else:
self.user_stats = User_Stats()
pass
def _check_completion(self) -> None:
""" waits 5 seconds then check if lastline matches past iteration's lastline
"""
sleep(SONG_OVER_CHECK_TIME) ###Wait 10 seconds
#print("entering 5sec")
csv_lastline = self._read_lastline()
#print("csv_lastline = ", csv_lastline)
#print("self._last_line = ", self._last_line)
if csv_lastline == self._last_line or csv_lastline == "Empty File":
self._song_over = True
print("Song Over")
else:
self._last_line = csv_lastline
self._song_over = False
return
def _summarize_period(self) -> None:
""" Call time_5_sec() 6 times, if the song ends return immediately,
otherwise return once iterations are complete.
"""
#print("entering 30sec")
for i in range(TIME_BETWEEN_FEEDBACK // SONG_OVER_CHECK_TIME): ### Wait 30 seconds
self._check_completion()
if self._song_over is True:
break
self._set_last_30_sec()
return
def _set_last_30_sec(self) -> None:
""" sets the grip list for the past 30 seconds of the song
"""
#print("entering set_last_30")
grip_list = read_csv(CSV_functions.MUSICGLOVE, test=True)
self._all_grips = parse_csv(grip_list)
#print("grip_list = ", grip_list)
if self._grip_count == 0:
self._grip_count = len(grip_list)
else:
for j in range(self._grip_count):
#print("j = {} and grip_list = {}".format(j, len(grip_list)))
grip_list.remove(grip_list[0])
self._grip_count += len(grip_list)
#self._all_grips += parse_csv(read_csv(CSV_functions.MUSICGLOVE))
self._last_30_sec = grip_list
return
def _read_lastline(self)-> str:
""" Reads the last line of the csv containing the user's grip information
"""
#print("entering _read_lastline()")
#print(read_csv(CSV_functions.MUSICGLOVE))
try:
last_line = parse_csv(read_csv(CSV_functions.MUSICGLOVE))[-1]
except IndexError:
return "Empty File"
return last_line
def _compile_result(self, summary: str) -> None:
""" Extends the result that will be added to the log.csv
"""
#print("entering _compile_result()")
self._csv_result.append(summary)
return
def select_response(self) -> (str, str):
""" Chooses an appropriate response based upon user's performance. Returns that response string"""
print("RIVA msg number: ", self._RIVA_message_num)
overall_avg = self.user_stats.new_overall_avg()
scale_points = self.user_stats.get_scale_points(abs_val_list(grip_times(self._all_grips)))
#print("overall avg: {}\n scale point 1: {} scale point 2: {}".format(overall_avg,scale_points[1],scale_points[2]))
# if self._RIVA_message_num == 1:
# return self.response_welcome()
if self._last_response == "training_prompt":
return self.response_training_response()
'''elif self.user_stats.get_grip_avg(grip_number=self._last_worst_grip) > \
self.user_stats.get_scale_points(abs_val_list(grip_times(self._all_grips)))[2]:
return self.response_training_prompt()
'''
elif overall_avg > scale_points[2]:
#print("Q2", scale_points[2])
return self.response_negative()
elif overall_avg < scale_points[1]:
#print("Q1", scale_points[1])
return self.response_positive()
return self.response_training_prompt()
def response_welcome(self) -> str:
""" Returns a welcome for the user, including their name, giving the system a chance to analyze their skill"""
self._last_response = "Welcome"
self._last_worst_grip = 0
### return "Alright " + self.user_name + ", are you ready to really get started!?"
return "Welcome_str"
def response_training_response(self) -> str:
""" Analyzes the user's performance on a given grip, returns a string appropriate to their success/failure"""
training_response = Mglove_str_gen.training_response(
self.user_stats.get_followup(),
self.user_stats.get_grip_avg(grip_number=self.user_stats.get_followup(), old=True),
self.user_stats.get_grip_avg(grip_number=self.user_stats.get_followup()))
self._last_response = training_response[0]
return training_response[1]
def response_training_prompt(self) -> str:
""" Analyzes user's last 30 seconds, returns prompt suggesting a grip to work on (the worst grip)"""
self._last_response = "training_prompt"
print("Training Prompt")
self.user_stats.set_followup(self._last_worst_grip)
return Mglove_str_gen.training_prompt(self.user_stats.get_followup())
def response_negative(self) -> str:
""" Returns a scaled string telling the user they need to improve their overall reaction time"""
print("Negative Response")
self._last_response = "negative_response"
#print("scale = ", self.user_stats.find_worst_grip_scale(grip_times(self._all_grips)))
return Mglove_str_gen.negative_response(self.user_stats.find_worst_grip_scale(grip_times(self._all_grips)))
def response_positive(self) -> str:
""" Returns a scaled string telling the user that their overall reaction time is good/great"""
self._last_response = "positive_response"
print("Positive Response")
#print("scale =", self.user_stats.find_best_grip_scale(grip_times(self._all_grips)))
return Mglove_str_gen.positive_response(self.user_stats.find_best_grip_scale(grip_times(self._all_grips)))
def test_for_restart(self) -> None:
""" Tests whether the a new song has been started
"""
#print("entering test_for_restart()")
self._compile_result("UserName: " + self.user_name)
msg = "Welcome_str"
if self._feedback_plat == "RIVA":
self._RIVA_message_num += 1
text_to_RIVA(self._RIVA_message_num, 0, 0, self._RIVA_focus_direction, msg = msg)
elif self._feedback_plat == "Text":
self._RIVA_message_num += 1
to_no_voice_log("NewData:{};TTS:{}".format(self._RIVA_message_num, msg))
else:
text_to_ispeech(ispeech_formatter(msg))
while True:
self._check_completion()
if self._song_over is False:
print("Song Started")
if self._feedback_plat == "RIVA":
reset_RIVA_log()
self._RIVA_message_num += 1
text_to_RIVA(self._RIVA_message_num, 0,0, self._RIVA_focus_direction, msg=self.response_welcome())
elif self._feedback_plat == "Text":
to_no_voice_log((emo_less_feedback(0, 0, 0)))
self.execute_song()
#print("Re-entered Test_for_restart()")
if self._song_over is True:
interface_info = gather_info(
parse_csv(read_csv(CSV_functions.MUSICGLOVE)))
#print(interface_info)
#print("Song_over min/max = ", min_max)
self.user_stats.set_grips(interface_info)
self._compile_result(grip_avg_summary_str(interface_info))
evaluated_info = [evaluate_worst_grip(interface_info, self._last_worst_grip),
evaluate_best_grip(interface_info)]
summary = summary_generator(evaluated_info[0], evaluated_info[1])
if self._feedback_plat == "RIVA":
self._RIVA_message_num += 1
#print("message_num={} summary={}".format(self._message_num, summary))
text_to_RIVA(self._RIVA_message_num, evaluated_info[0], evaluated_info[1],
self._RIVA_focus_direction, msg=summary)
elif self._feedback_plat == "Text":
to_no_voice_log(emo_less_feedback(self._RIVA_message_num, evaluated_info[0], evaluated_info[1]))
else:
text_to_ispeech(ispeech_formatter(summary))
self._last_30_sec = []
self._compile_result(summary)
self._csv_result.extend(read_csv(CSV_functions.MUSICGLOVE))
make_csv(self._csv_result, CSV_functions.M_GLOVE_SUMMARIES, what_song(self._grip_count))
self.__init__(self.user_name, restart=True)
self._RIVA_message_num = 1
else:
#print("no restart yet")
pass
return
def execute_song(self) -> None:
""" organizes methods, and runs a song
"""
#print("entering execute_song()")
while self._song_over is False:
self._summarize_period()
grip_info = gather_info(parse_csv(self._last_30_sec))
#print("min_max = ", min_max)
self.user_stats.set_grips(grip_info)
best_grip = evaluate_best_grip(grip_info)
self._compile_result(grip_avg_summary_str(grip_info))
self._last_worst_grip = evaluate_worst_grip(grip_info, self._last_worst_grip)
summary = self.select_response()
#summary = summary_generator(evaluate_worst_grip(grip_info, self._last_worst_grip),best_grip)
self._compile_result(summary)
self._compile_result('system time = {}'.format(strftime("%H:%M:%S")))
self._compile_result(' ')
if self._song_over is True:
#print('Number of grips this song = ', self._grip_count)
return
if self._feedback_plat == "RIVA":
self._RIVA_message_num += 1
text_to_RIVA(self._RIVA_message_num, 0, 0, self._RIVA_focus_direction, msg= summary)
elif self._feedback_plat == "Text":
self._RIVA_message_num += 1
to_no_voice_log(emo_less_feedback(self._RIVA_message_num, self._last_worst_grip, best_grip))
else:
self._RIVA_message_num += 1
text_to_ispeech(ispeech_formatter(summary))
#print("leaving execute_song()")
return
if __name__ == "__main__":
reset_RIVA_log()
MusicGloveSong(user=input("Please enter user name: ")).test_for_restart()