[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
parent
738149d44b
commit
b4a5cd331a
|
@ -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() {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue