Skip to content

Commit b4a5cd3

Browse files
authored
[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>
1 parent 738149d commit b4a5cd3

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/DialogProcessor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public DialogProcessor(KSService ks, STTService stt, TTSService tts, HumanLangua
121121
this.bundle = bundle;
122122
this.ksFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), ks.getSupportedFormats());
123123
this.sttFormat = VoiceManagerImpl.getBestMatch(source.getSupportedFormats(), stt.getSupportedFormats());
124-
this.ttsFormat = VoiceManagerImpl.getBestMatch(sink.getSupportedFormats(), tts.getSupportedFormats());
124+
this.ttsFormat = VoiceManagerImpl.getBestMatch(tts.getSupportedFormats(), sink.getSupportedFormats());
125125
}
126126

127127
public void start() {

bundles/org.openhab.core.voice/src/main/java/org/openhab/core/voice/internal/VoiceManagerImpl.java

+19-6
Original file line numberDiff line numberDiff line change
@@ -225,19 +225,19 @@ public void say(String text, @Nullable String voiceId, @Nullable String sinkId,
225225
throw new TTSException(
226226
"Unable to find a voice for language " + localeProvider.getLocale().getLanguage());
227227
}
228-
Set<AudioFormat> sttAudioFormats = tts.getSupportedFormats();
228+
Set<AudioFormat> ttsSupportedFormats = tts.getSupportedFormats();
229229
AudioSink sink = audioManager.getSink(sinkId);
230230
if (sink == null) {
231231
throw new TTSException("Unable to find the audio sink " + sinkId);
232232
}
233233

234-
AudioFormat sttAudioFormat = getBestMatch(sink.getSupportedFormats(), sttAudioFormats);
235-
if (sttAudioFormat == null) {
234+
AudioFormat ttsAudioFormat = getBestMatch(ttsSupportedFormats, sink.getSupportedFormats());
235+
if (ttsAudioFormat == null) {
236236
throw new TTSException("No compatible audio format found for TTS '" + tts.getId() + "' and sink '"
237237
+ sink.getId() + "'");
238238
}
239239

240-
AudioStream audioStream = tts.synthesize(text, voice, sttAudioFormat);
240+
AudioStream audioStream = tts.synthesize(text, voice, ttsAudioFormat);
241241
if (!sink.getSupportedStreams().stream().anyMatch(clazz -> clazz.isInstance(audioStream))) {
242242
throw new TTSException(
243243
"Failed playing audio stream '" + audioStream + "' as audio sink doesn't support it");
@@ -503,8 +503,9 @@ public void startDialog(@Nullable KSService ks, @Nullable STTService stt, @Nulla
503503
if (ksService == null || sttService == null || ttsService == null || interpreter == null || audioSource == null
504504
|| audioSink == null || b == null) {
505505
throw new IllegalStateException("Cannot start dialog as services are missing.");
506-
} else if (!ksService.getSupportedLocales().contains(loc) || !sttService.getSupportedLocales().contains(loc)
507-
|| !interpreter.getSupportedLocales().contains(loc)) {
506+
} else if (!checkLocales(ksService.getSupportedLocales(), loc)
507+
|| !checkLocales(sttService.getSupportedLocales(), loc)
508+
|| !checkLocales(interpreter.getSupportedLocales(), loc)) {
508509
throw new IllegalStateException("Cannot start dialog as provided locale is not supported by all services.");
509510
} else {
510511
DialogProcessor processor = dialogProcessors.get(audioSource.getId());
@@ -548,6 +549,18 @@ private void stopAllDialogs() {
548549
dialogProcessors.clear();
549550
}
550551

552+
private boolean checkLocales(@Nullable Set<Locale> supportedLocales, Locale locale) {
553+
if (supportedLocales == null) {
554+
// rule interpreter returns null so allowing it
555+
return true;
556+
}
557+
return supportedLocales.stream().anyMatch(sLocale -> {
558+
var country = sLocale.getCountry();
559+
return Objects.equals(sLocale.getLanguage(), locale.getLanguage())
560+
&& (country == null || country.isBlank() || country.equals(locale.getCountry()));
561+
});
562+
}
563+
551564
@Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
552565
protected void addKSService(KSService ksService) {
553566
this.ksServices.put(ksService.getId(), ksService);

0 commit comments

Comments
 (0)