diff --git a/docs/plugins/gst_plugins_cache.json b/docs/plugins/gst_plugins_cache.json
index 8189ab59..12cb7f40 100644
--- a/docs/plugins/gst_plugins_cache.json
+++ b/docs/plugins/gst_plugins_cache.json
@@ -111,6 +111,18 @@
"type": "gchararray",
"writable": true
},
+ "ssml-set-max-duration": {
+ "blurb": "Wrap plain text as SSML and set the max-duration attribute",
+ "conditionally-available": false,
+ "construct": false,
+ "construct-only": false,
+ "controllable": false,
+ "default": "false",
+ "mutable": "ready",
+ "readable": true,
+ "type": "gboolean",
+ "writable": true
+ },
"voice-id": {
"blurb": "Defines what voice id to use",
"conditionally-available": false,
diff --git a/net/aws/src/polly/imp.rs b/net/aws/src/polly/imp.rs
index 396eb73e..9a53451e 100644
--- a/net/aws/src/polly/imp.rs
+++ b/net/aws/src/polly/imp.rs
@@ -34,6 +34,7 @@ const DEFAULT_LATENCY: gst::ClockTime = gst::ClockTime::from_seconds(2);
const DEFAULT_ENGINE: AwsPollyEngine = AwsPollyEngine::Neural;
const DEFAULT_LANGUAGE_CODE: AwsPollyLanguageCode = AwsPollyLanguageCode::None;
const DEFAULT_VOICE_ID: AwsPollyVoiceId = AwsPollyVoiceId::Aria;
+const DEFAULT_SSML_SET_MAX_DURATION: bool = false;
#[derive(Debug, Clone)]
pub(super) struct Settings {
@@ -45,6 +46,7 @@ pub(super) struct Settings {
language_code: AwsPollyLanguageCode,
voice_id: AwsPollyVoiceId,
lexicon_names: gst::Array,
+ ssml_set_max_duration: bool,
}
impl Default for Settings {
@@ -58,6 +60,7 @@ impl Default for Settings {
language_code: DEFAULT_LANGUAGE_CODE,
voice_id: DEFAULT_VOICE_ID,
lexicon_names: gst::Array::default(),
+ ssml_set_max_duration: DEFAULT_SSML_SET_MAX_DURATION,
}
}
}
@@ -181,13 +184,23 @@ impl Polly {
let job = {
let settings = self.settings.lock().unwrap();
-
let mut task = client
.synthesize_speech()
.engine(settings.engine.into())
.output_format(aws_sdk_polly::types::OutputFormat::Pcm)
- .text_type(in_format)
- .text(data)
+ .text_type(if settings.ssml_set_max_duration {
+ aws_sdk_polly::types::TextType::Ssml
+ } else {
+ in_format
+ })
+ .text(if settings.ssml_set_max_duration {
+ format!(
+ "{data}",
+ duration.mseconds()
+ )
+ } else {
+ data.to_owned()
+ })
.voice_id(settings.voice_id.into())
.set_lexicon_names(Some(
settings
@@ -217,6 +230,12 @@ impl Polly {
let mut buf = gst::Buffer::from_slice(blob.into_bytes());
let mut state = self.state.lock().unwrap();
+ let duration = gst::ClockTime::from_nseconds(
+ (buf.size() as u64)
+ .mul_div_round(1_000_000_000, 32_000)
+ .unwrap(),
+ );
+
let discont = state
.out_segment
.position()
@@ -496,6 +515,12 @@ impl ObjectImpl for Polly {
)
.mutable_ready()
.build(),
+ glib::ParamSpecBoolean::builder("ssml-set-max-duration")
+ .nick("SSML set max duration")
+ .blurb("Wrap plain text as SSML and set the max-duration attribute")
+ .default_value(DEFAULT_SSML_SET_MAX_DURATION)
+ .mutable_ready()
+ .build(),
]
});
@@ -552,6 +577,10 @@ impl ObjectImpl for Polly {
let mut settings = self.settings.lock().unwrap();
settings.lexicon_names = value.get::().expect("type checked upstream");
}
+ "ssml-set-max-duration" => {
+ let mut settings = self.settings.lock().unwrap();
+ settings.ssml_set_max_duration = value.get().expect("type checked upstream");
+ }
_ => unimplemented!(),
}
}
@@ -590,6 +619,10 @@ impl ObjectImpl for Polly {
let settings = self.settings.lock().unwrap();
settings.lexicon_names.to_value()
}
+ "ssml-set-max-duration" => {
+ let settings = self.settings.lock().unwrap();
+ settings.ssml_set_max_duration.to_value()
+ }
_ => unimplemented!(),
}
}