[Voice] Fix "best match" format resolution and language check for services involved in dialog (#2809)

Signed-off-by: Miguel Álvarez Díez <miguelwork92@gmail.com>
pull/2786/head
GiviMAD 2022-02-28 09:10:41 +01:00 committed by GitHub
parent 738149d44b
commit b4a5cd331a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 7 deletions

View File

@ -121,7 +121,7 @@ public class DialogProcessor implements KSListener, STTListener {
this.bundle = bundle;
this.ksFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), ks.getSupportedFormats());
this.sttFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), stt.getSupportedFormats());
this.ttsFormat = VoiceManagerImpl.getBestMatch(sink.getSupportedFormats(), tts.getSupportedFormats());
this.ttsFormat = VoiceManagerImpl.getBestMatch(tts.getSupportedFormats(), sink.getSupportedFormats());
}
public void start() {

View File

@ -225,19 +225,19 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
throw new TTSException(
"Unable to find a voice for language " + localeProvider.getLocale().getLanguage());
}
Set<AudioFormat> sttAudioFormats = tts.getSupportedFormats();
Set<AudioFormat> ttsSupportedFormats = tts.getSupportedFormats();
AudioSink sink = audioManager.getSink(sinkId);
if (sink == null) {
throw new TTSException("Unable to find the audio sink " + sinkId);
}
AudioFormat sttAudioFormat = getBestMatch(sink.getSupportedFormats(), sttAudioFormats);
if (sttAudioFormat == null) {
AudioFormat ttsAudioFormat = getBestMatch(ttsSupportedFormats, sink.getSupportedFormats());
if (ttsAudioFormat == null) {
throw new TTSException("No compatible audio format found for TTS '" + tts.getId() + "' and sink '"
+ sink.getId() + "'");
}
AudioStream audioStream = tts.synthesize(text, voice, sttAudioFormat);
AudioStream audioStream = tts.synthesize(text, voice, ttsAudioFormat);
if (!sink.getSupportedStreams().stream().anyMatch(clazz -> clazz.isInstance(audioStream))) {
throw new TTSException(
"Failed playing audio stream '" + audioStream + "' as audio sink doesn't support it");
@ -503,8 +503,9 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
if (ksService == null || sttService == null || ttsService == null || interpreter == null || audioSource == null
|| audioSink == null || b == null) {
throw new IllegalStateException("Cannot start dialog as services are missing.");
} else if (!ksService.getSupportedLocales().contains(loc) || !sttService.getSupportedLocales().contains(loc)
|| !interpreter.getSupportedLocales().contains(loc)) {
} else if (!checkLocales(ksService.getSupportedLocales(), loc)
|| !checkLocales(sttService.getSupportedLocales(), loc)
|| !checkLocales(interpreter.getSupportedLocales(), loc)) {
throw new IllegalStateException("Cannot start dialog as provided locale is not supported by all services.");
} else {
DialogProcessor processor = dialogProcessors.get(audioSource.getId());
@ -548,6 +549,18 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
dialogProcessors.clear();
}
private boolean checkLocales(@Nullable Set<Locale> supportedLocales, Locale locale) {
if (supportedLocales == null) {
// rule interpreter returns null so allowing it
return true;
}
return supportedLocales.stream().anyMatch(sLocale -> {
var country = sLocale.getCountry();
return Objects.equals(sLocale.getLanguage(), locale.getLanguage())
&& (country == null || country.isBlank() || country.equals(locale.getCountry()));
});
}
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
protected void addKSService(KSService ksService) {
this.ksServices.put(ksService.getId(), ksService);