[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.bundle = bundle;
this.ksFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), ks.getSupportedFormats()); this.ksFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), ks.getSupportedFormats());
this.sttFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), stt.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() { public void start() {

View File

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