mirror of
https://github.com/lightsoutgames/godot-tts
synced 2024-11-25 03:45:57 +00:00
Major tts-rs
update.
* Initial WinRT driver, used when no Windows screen reader is detected. * Enhanced rate support, tracking min/max/normal rate per synthesizer. * `rate_percentage` properties make working with differing rate ranges easier.
This commit is contained in:
parent
91faf9197c
commit
495c5eddad
|
@ -9,4 +9,4 @@ crate-type = ["cdylib"]
|
|||
|
||||
[dependencies]
|
||||
gdnative = "0.8"
|
||||
tts = "0.2"
|
||||
tts = { git = "https://gitlab.com/ndarilek/tts-rs" }
|
||||
|
|
69
TTS.gd
69
TTS.gd
|
@ -17,13 +17,49 @@ func _ready():
|
|||
else:
|
||||
print_debug("TTS not available!")
|
||||
|
||||
func _get_min_rate():
|
||||
if OS.has_feature('JavaScript'):
|
||||
return 0.1
|
||||
elif Engine.has_singleton("AndroidTTS"):
|
||||
return 0.1
|
||||
elif tts != null:
|
||||
return tts.min_rate
|
||||
else:
|
||||
return 0
|
||||
|
||||
var min_rate setget , _get_min_rate
|
||||
|
||||
func _get_max_rate():
|
||||
if OS.has_feature('JavaScript'):
|
||||
return 10
|
||||
elif Engine.has_singleton("AndroidTTS"):
|
||||
return 10.0
|
||||
elif tts != null:
|
||||
return tts.max_rate
|
||||
else:
|
||||
return 0
|
||||
|
||||
var max_rate setget , _get_max_rate
|
||||
|
||||
func _get_normal_rate():
|
||||
if OS.has_feature('JavaScript'):
|
||||
return 1
|
||||
elif Engine.has_singleton("AndroidTTS"):
|
||||
return 1.0
|
||||
elif tts != null:
|
||||
return tts.normal_rate
|
||||
else:
|
||||
return 0
|
||||
|
||||
var normal_rate setget , _get_normal_rate
|
||||
|
||||
var javascript_rate = 50
|
||||
|
||||
func set_rate(rate):
|
||||
if rate < 0:
|
||||
rate = 0
|
||||
elif rate > 100:
|
||||
rate = 100
|
||||
if rate < self.min_rate:
|
||||
rate = self.min_rate
|
||||
elif rate > self.max_rate:
|
||||
rate = self.max_rate
|
||||
if tts != null:
|
||||
tts.rate = rate
|
||||
elif OS.has_feature('JavaScript'):
|
||||
|
@ -39,20 +75,27 @@ func get_rate():
|
|||
|
||||
var rate setget set_rate, get_rate
|
||||
|
||||
func _get_rate_percentage():
|
||||
return range_lerp(self.rate, self.min_rate, self.max_rate, 0, 100)
|
||||
|
||||
func _set_rate_percentage(v):
|
||||
self.rate = range_lerp(v, 0, 100, self.min_rate, self.max_rate)
|
||||
|
||||
var rate_percentage setget _set_rate_percentage, _get_rate_percentage
|
||||
|
||||
func _get_normal_rate_percentage():
|
||||
return range_lerp(self.normal_rate, self.min_rate, self.max_rate, 0, 100)
|
||||
|
||||
var normal_rate_percentage setget , _get_rate_percentage
|
||||
|
||||
func speak(text, interrupt := true):
|
||||
if tts != null:
|
||||
tts.speak(text, interrupt)
|
||||
elif OS.has_feature('JavaScript'):
|
||||
var scaled_rate: float
|
||||
if javascript_rate <= 50:
|
||||
scaled_rate = javascript_rate / 50.0
|
||||
else:
|
||||
scaled_rate = javascript_rate - 50
|
||||
scaled_rate = 1 + (scaled_rate / 5.0)
|
||||
var code = """
|
||||
let utterance = new SpeechSynthesisUtterance("%s")
|
||||
utterance.rate = %s
|
||||
""" % [text.replace("\n", " "), scaled_rate]
|
||||
""" % [text.replace("\n", " "), javascript_rate]
|
||||
if interrupt:
|
||||
code += """
|
||||
window.speechSynthesis.cancel()
|
||||
|
@ -69,8 +112,8 @@ func stop():
|
|||
JavaScript.eval("window.speechSynthesis.cancel()")
|
||||
|
||||
func get_is_rate_supported():
|
||||
if Engine.get_singleton("AndroidTTS"):
|
||||
return false
|
||||
if Engine.has_singleton("AndroidTTS"):
|
||||
return true
|
||||
elif OS.has_feature('JavaScript'):
|
||||
return true
|
||||
elif tts != null:
|
||||
|
|
68
src/lib.rs
68
src/lib.rs
|
@ -1,5 +1,3 @@
|
|||
use std::u8;
|
||||
|
||||
use gdnative::init::*;
|
||||
use gdnative::*;
|
||||
use tts::{Features, TTS as Tts};
|
||||
|
@ -18,27 +16,69 @@ impl TTS {
|
|||
|
||||
fn register_properties(builder: &ClassBuilder<Self>) {
|
||||
builder
|
||||
.add_property::<u8>("rate")
|
||||
.with_default(50)
|
||||
.add_property("rate")
|
||||
.with_getter(|this: &TTS, _| match this.0.get_rate() {
|
||||
Ok(rate) => rate / u8::MAX * 100,
|
||||
_ => 0,
|
||||
Ok(rate) => rate,
|
||||
_ => 0.,
|
||||
})
|
||||
.with_setter(|this: &mut TTS, _, mut v: u8| {
|
||||
if v > 100 {
|
||||
v = 100;
|
||||
}
|
||||
let mut v = v as f32;
|
||||
v = v * u8::MAX as f32 / 100.;
|
||||
.with_setter(|this: &mut TTS, _, v: f32| {
|
||||
let Features {
|
||||
rate: rate_supported,
|
||||
..
|
||||
} = this.0.supported_features();
|
||||
if rate_supported {
|
||||
this.0.set_rate(v as u8).unwrap();
|
||||
let mut v = v;
|
||||
if v < this.0.min_rate() {
|
||||
v = this.0.min_rate();
|
||||
} else if v > this.0.max_rate() {
|
||||
v = this.0.max_rate();
|
||||
}
|
||||
this.0.set_rate(v).unwrap();
|
||||
}
|
||||
})
|
||||
.done()
|
||||
.done();
|
||||
builder
|
||||
.add_property("min_rate")
|
||||
.with_getter(|this: &TTS, _| {
|
||||
let Features {
|
||||
rate: rate_supported,
|
||||
..
|
||||
} = this.0.supported_features();
|
||||
if rate_supported {
|
||||
this.0.min_rate()
|
||||
} else {
|
||||
0.
|
||||
}
|
||||
})
|
||||
.done();
|
||||
builder
|
||||
.add_property("max_rate")
|
||||
.with_getter(|this: &TTS, _| {
|
||||
let Features {
|
||||
rate: rate_supported,
|
||||
..
|
||||
} = this.0.supported_features();
|
||||
if rate_supported {
|
||||
this.0.max_rate()
|
||||
} else {
|
||||
0.
|
||||
}
|
||||
})
|
||||
.done();
|
||||
builder
|
||||
.add_property("normal_rate")
|
||||
.with_getter(|this: &TTS, _| {
|
||||
let Features {
|
||||
rate: rate_supported,
|
||||
..
|
||||
} = this.0.supported_features();
|
||||
if rate_supported {
|
||||
this.0.normal_rate()
|
||||
} else {
|
||||
0.
|
||||
}
|
||||
})
|
||||
.done();
|
||||
}
|
||||
|
||||
#[export]
|
||||
|
|
Loading…
Reference in New Issue
Block a user