4
logger = logging.getLogger('tts')
6
class TTS(gobject.GObject):
9
MAX_INTERVAL_DISTANCE = 1000
15
'error' : (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, (gobject.TYPE_PYOBJECT,)),
18
def __init__(self, core):
19
gobject.GObject.__init__(self)
21
self.gps_target_bearing_abs = None
22
self.gps_target_distance = None
26
self.timeout_event_id = None
27
self.automatic_interval = False
28
core.connect('good-fix', self.__on_good_fix)
29
core.connect('no-fix', self.__on_no_fix)
30
core.connect('settings-changed', self.__on_settings_changed)
32
def __on_settings_changed(self, caller, settings, source):
33
if 'tts_interval' in settings:
34
self.__set_enabled(settings['tts_interval'])
36
def __set_enabled(self, interval):
38
interval = self.__calculate_automatic_interval(self.gps_target_distance)
39
self.automatic_interval = True
40
logger.info("Setting interval to %d" % interval)
42
self.automatic_interval = False
44
if self.timeout_event_id != None:
45
gobject.source_remove(self.timeout_event_id)
46
self.timeout_event_id = None
49
self.timeout_event_id = gobject.timeout_add_seconds(interval, self.__tell)
55
def __calculate_automatic_interval(d):
57
return TTS.DEFAULT_INTERVAL
58
if d > TTS.MAX_INTERVAL_DISTANCE:
59
return TTS.MAX_INTERVAL
60
if d <= TTS.MIN_DISTANCE:
61
return TTS.MIN_INTERVAL
63
return int(round(TTS.MAX_INTERVAL + (TTS.MAX_INTERVAL_DISTANCE - d) * (float(TTS.MIN_INTERVAL - TTS.MAX_INTERVAL) / float(TTS.MAX_INTERVAL_DISTANCE - TTS.MIN_DISTANCE))))
68
logger.info("Starting espeak...")
70
self.proc = subprocess.Popen("espeak", stdin=subprocess.PIPE)
71
self.proc.stdin.write("Espeak ready.\n")
74
self.emit('error', Exception("Please install the 'espeak' package from the package manager to get text-to-speech functionality."))
76
def __disconnect(self):
77
logger.info("Stopping espeak...")
79
self.proc.stdin.write("Stopping espeak.\n")
80
#self.proc.terminate()
83
def __on_good_fix(self, caller, gps_data, distance, bearing):
84
self.gps_target_distance = distance
85
self.gps_target_bearing_abs = bearing - gps_data.bearing
86
self.gps_data = gps_data
89
output = "%s\n%s\n" % (self.__format_distance(), self.__format_bearing())
90
logger.info("Espeak: %s" % repr(output.strip()))
91
self.proc.stdin.write(output)
92
if self.automatic_interval:
93
self.__set_enabled(-1)
97
def __format_distance(self):
98
distance = self.gps_target_distance
102
return '%d kilometers. ' % round(distance / 1000.0)
104
return '%d meters. ' % round(distance)
106
return '%.1f meters. ' % round(distance, 1)
108
def __format_bearing(self):
109
if self.gps_target_bearing_abs == None:
111
if self.gps_data == None or self.gps_data.error_bearing > 179:
113
return "%d o'clock." % self.__degree_to_hour(self.gps_target_bearing_abs)
116
def __on_no_fix(self, caller, fix, msg):
117
self.gps_target_distance = None
118
self.gps_target_bearing_abs = None
122
def __degree_to_hour(degree):
123
ret = round((degree % 360) / 30.0)
124
return ret if ret != 0 else 12
128
print "Testing of coordinate-to-hour conversion:"
129
for i in xrange(360):
130
print "%3d -> %d" % (i, TTS.__degree_to_hour(i))
132
print "Testing of interval calculation:"
133
for z in xrange(1050, 0, -3):
134
print "%4d m -> %d seconds" % (z, TTS.__calculate_automatic_interval(z))
137
if __name__ == '__main__':