godot-tts/TTS.gd

327 lines
6.5 KiB
GDScript3
Raw Normal View History

tool
2019-09-24 19:21:05 +00:00
extends Node
signal utterance_begin(utterance)
2020-09-29 16:41:00 +00:00
signal utterance_end(utterance)
2020-09-29 16:41:00 +00:00
2020-10-08 13:56:56 +00:00
signal utterance_stop(utterance)
var TTS
2020-01-15 01:54:40 +00:00
var tts
func _init():
2020-05-28 18:29:39 +00:00
if OS.get_name() == "Server" or OS.has_feature("JavaScript"):
return
elif Engine.has_singleton("GodotTTS"):
tts = Engine.get_singleton("GodotTTS")
2020-05-28 18:29:39 +00:00
else:
TTS = preload("godot-tts.gdns")
if TTS and (TTS.can_instance() or Engine.editor_hint):
tts = TTS.new()
2020-10-14 18:15:03 +00:00
if tts:
if not tts is JNISingleton:
self.add_child(tts)
2020-09-29 16:41:00 +00:00
if self.are_utterance_callbacks_supported:
tts.connect("utterance_begin", self, "_on_utterance_begin")
tts.connect("utterance_end", self, "_on_utterance_end")
2020-10-08 13:56:56 +00:00
tts.connect("utterance_stop", self, "_on_utterance_stop")
2020-05-28 18:29:39 +00:00
else:
print_debug("TTS not available!")
func _ready():
pause_mode = Node.PAUSE_MODE_PROCESS
func _get_min_volume():
if OS.has_feature('JavaScript'):
return 0
else:
return 0
var min_volume setget , _get_min_volume
func _get_max_volume():
if OS.has_feature('JavaScript'):
return 1.0
else:
return 0
var max_volume setget , _get_max_volume
func _get_normal_volume():
if OS.has_feature('JavaScript'):
return 1.0
else:
return 0
var normal_volume setget , _get_normal_volume
var javascript_volume = self.normal_volume
func _set_volume(volume):
if volume < self.min_volume:
volume = self.min_volume
elif volume > self.max_volume:
volume = self.max_volume
if OS.has_feature('JavaScript'):
javascript_volume = volume
func _get_volume():
if OS.has_feature('JavaScript'):
return javascript_volume
else:
return 0
var volume setget _set_volume, _get_volume
func _get_volume_percentage():
return range_lerp(self.volume, self.min_volume, self.max_volume, 0, 100)
func _set_volume_percentage(v):
self.rate = range_lerp(v, 0, 100, self.min_volume, self.max_volume)
var volume_percentage setget _set_volume_percentage, _get_volume_percentage
func _get_normal_volume_percentage():
return range_lerp(self.normal_volume, self.min_volume, self.max_volume, 0, 100)
var normal_volume_percentage setget , _get_normal_volume_percentage
func _get_min_rate():
2020-05-28 18:29:39 +00:00
if OS.has_feature('JavaScript'):
return 0.1
2020-08-21 15:31:59 +00:00
elif Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return 0.1
elif tts != null:
return tts.min_rate
else:
return 0
var min_rate setget , _get_min_rate
2020-05-28 18:29:39 +00:00
func _get_max_rate():
2020-05-28 18:29:39 +00:00
if OS.has_feature('JavaScript'):
return 10.0
2020-08-21 15:31:59 +00:00
elif Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return 10.0
elif tts != null:
return tts.max_rate
else:
return 0
var max_rate setget , _get_max_rate
2020-05-28 18:29:39 +00:00
func _get_normal_rate():
2020-05-28 18:29:39 +00:00
if OS.has_feature('JavaScript'):
return 1.0
2020-08-21 15:31:59 +00:00
elif Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return 1.0
elif tts != null:
return tts.normal_rate
else:
return 0
var normal_rate setget , _get_normal_rate
var javascript_rate = self.normal_rate
2020-05-28 18:29:39 +00:00
func _set_rate(rate):
2020-05-28 18:29:39 +00:00
if rate < self.min_rate:
rate = self.min_rate
elif rate > self.max_rate:
rate = self.max_rate
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return tts.set_rate(rate)
elif tts != null:
tts.rate = rate
elif OS.has_feature('JavaScript'):
javascript_rate = rate
2019-09-27 18:07:35 +00:00
func _get_rate():
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return tts.get_rate()
elif tts != null:
return tts.rate
elif OS.has_feature('JavaScript'):
return javascript_rate
else:
return 0
2019-09-27 18:07:35 +00:00
var rate setget _set_rate, _get_rate
2020-05-28 18:29:39 +00:00
func _get_rate_percentage():
2020-05-28 18:29:39 +00:00
return range_lerp(self.rate, self.min_rate, self.max_rate, 0, 100)
func _set_rate_percentage(v):
2020-05-28 18:29:39 +00:00
self.rate = range_lerp(v, 0, 100, self.min_rate, self.max_rate)
var rate_percentage setget _set_rate_percentage, _get_rate_percentage
2020-05-28 18:29:39 +00:00
func _get_normal_rate_percentage():
2020-05-28 18:29:39 +00:00
return range_lerp(self.normal_rate, self.min_rate, self.max_rate, 0, 100)
var normal_rate_percentage setget , _get_rate_percentage
2020-05-28 18:29:39 +00:00
func speak(text, interrupt := true):
var utterance
2020-05-28 18:29:39 +00:00
if tts != null:
utterance = tts.speak(text, interrupt)
2020-05-28 18:29:39 +00:00
elif OS.has_feature('JavaScript'):
var code = (
"""
let utterance = new SpeechSynthesisUtterance("%s")
utterance.rate = %s
utterance.volume = %s
"""
% [text.replace("\n", " "), javascript_rate, javascript_volume]
2020-05-28 18:29:39 +00:00
)
if interrupt:
code += """
window.speechSynthesis.cancel()
"""
2020-05-28 18:29:39 +00:00
code += "window.speechSynthesis.speak(utterance)"
JavaScript.eval(code)
else:
print_debug("%s: %s" % [text, interrupt])
return utterance
2020-05-28 18:29:39 +00:00
func stop():
2020-05-28 18:29:39 +00:00
if tts != null:
tts.stop()
elif OS.has_feature('JavaScript'):
JavaScript.eval("window.speechSynthesis.cancel()")
2020-09-29 15:56:32 +00:00
func _get_is_rate_supported():
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return true
elif OS.has_feature('JavaScript'):
return true
elif tts != null:
return tts.is_rate_supported()
else:
return false
2020-09-29 15:56:32 +00:00
var is_rate_supported setget , _get_is_rate_supported
2020-05-28 18:29:39 +00:00
func _get_are_utterance_callbacks_supported():
if Engine.has_singleton("GodotTTS"):
2020-09-30 20:13:17 +00:00
return true
elif OS.has_feature('JavaScript'):
return false
elif tts != null:
return tts.are_utterance_callbacks_supported()
else:
return false
var are_utterance_callbacks_supported setget , _get_are_utterance_callbacks_supported
func _get_can_detect_is_speaking():
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
return true
elif OS.has_feature('JavaScript'):
return true
elif tts != null:
return tts.can_detect_is_speaking
return false
var can_detect_is_speaking setget , _get_can_detect_is_speaking
func _get_is_speaking():
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
return tts.is_speaking()
elif OS.has_feature('JavaScript'):
return JavaScript.eval("window.speechSynthesis.speaking")
elif tts != null:
return tts.is_speaking
return false
var is_speaking setget , _get_is_speaking
func _get_can_detect_screen_reader():
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return true
elif OS.has_feature('JavaScript'):
return false
elif tts != null:
return tts.can_detect_screen_reader
return false
var can_detect_screen_reader setget , _get_can_detect_screen_reader
2020-05-28 18:29:39 +00:00
func _get_has_screen_reader():
2020-08-21 15:31:59 +00:00
if Engine.has_singleton("GodotTTS"):
2020-05-28 18:29:39 +00:00
return tts.has_screen_reader()
elif OS.has_feature('JavaScript'):
return false
elif tts != null:
return tts.has_screen_reader
return false
var has_screen_reader setget , _get_has_screen_reader
2020-05-28 18:29:39 +00:00
func singular_or_plural(count, singular, plural):
2020-05-28 18:29:39 +00:00
if count == 1:
return singular
else:
return plural
2019-12-23 00:09:40 +00:00
func _on_utterance_begin(utterance):
emit_signal("utterance_begin", utterance)
func _on_utterance_end(utterance):
emit_signal("utterance_end", utterance)
2020-10-08 13:56:56 +00:00
func _on_utterance_stop(utterance):
emit_signal("utterance_stop", utterance)
2019-12-23 00:09:40 +00:00
func _exit_tree():
2020-05-28 18:29:39 +00:00
if not tts or not TTS:
return
tts.free()