[voice] Allow stopping single dialogs and start dialog on an existing processor (#3100)

* [voice] Allow stop single dialogs and start processing on an existing one

Signed-off-by: Miguel Álvarez <miguelwork92@gmail.com>
This commit is contained in:
GiviMAD 2022-11-05 13:16:53 +01:00 committed by GitHub
parent 18d063e272
commit 9cdaa48fa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 4 deletions

View File

@ -150,6 +150,10 @@ public class DialogProcessor implements KSListener, STTListener {
this.ttsFormat = VoiceManagerImpl.getBestMatch(tts.getSupportedFormats(), sink.getSupportedFormats());
}
public void startSingleDialog() {
executeSimpleDialog();
}
public void start() {
KSService ksService = ks;
if (ksService != null) {
@ -211,6 +215,10 @@ public class DialogProcessor implements KSListener, STTListener {
toggleProcessing(false);
}
public boolean isProcessing() {
return processing;
}
private void abortKS() {
KSServiceHandle handle = ksServiceHandle;
if (handle != null) {
@ -376,4 +384,18 @@ public class DialogProcessor implements KSListener, STTListener {
}
}
}
/**
* Check if other DialogProcessor instance have same configuration ignoring the keyword spotting configuration
*
* @param dialogProcessor Other DialogProcessor instance
*/
public boolean isCompatible(DialogProcessor dialogProcessor) {
return this.sink.equals(dialogProcessor.sink) && this.source.equals(dialogProcessor.source)
&& this.stt.equals(dialogProcessor.stt) && this.tts.equals(dialogProcessor.tts)
&& Objects.equals(this.prefVoice, dialogProcessor.prefVoice)
&& this.hlis.size() == dialogProcessor.hlis.size() && this.hlis.containsAll(dialogProcessor.hlis)
&& this.locale.equals(dialogProcessor.locale)
&& Objects.equals(this.listeningItem, dialogProcessor.listeningItem);
}
}

View File

@ -27,6 +27,7 @@ import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import org.eclipse.jdt.annotation.NonNullByDefault;
@ -126,6 +127,7 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
private final Map<String, String> defaultVoices = new HashMap<>();
private Map<String, DialogProcessor> dialogProcessors = new HashMap<>();
private Map<String, DialogProcessor> singleDialogProcessors = new ConcurrentHashMap<>();
@Activate
public VoiceManagerImpl(final @Reference LocaleProvider localeProvider, final @Reference AudioManager audioManager,
@ -544,6 +546,10 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
AudioSource audioSource = (source == null) ? audioManager.getSource() : source;
if (audioSource != null) {
DialogProcessor processor = dialogProcessors.remove(audioSource.getId());
singleDialogProcessors.values().removeIf(e -> !e.isProcessing());
if (processor == null) {
processor = singleDialogProcessors.get(audioSource.getId());
}
if (processor != null) {
processor.stop();
logger.debug("Dialog stopped for source {} ({})", audioSource.getLabel(null), audioSource.getId());
@ -598,13 +604,24 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
throw new IllegalStateException(
"Cannot execute a simple dialog as provided locale is not supported by all services.");
} else {
DialogProcessor processor = dialogProcessors.get(audioSource.getId());
if (processor == null) {
boolean isSingleDialog = false;
DialogProcessor activeProcessor = dialogProcessors.get(audioSource.getId());
singleDialogProcessors.values().removeIf(e -> !e.isProcessing());
if (activeProcessor == null) {
isSingleDialog = true;
activeProcessor = singleDialogProcessors.get(audioSource.getId());
}
var processor = new DialogProcessor(sttService, ttsService, prefVoice, interpreters, audioSource, audioSink,
loc, item, this.eventPublisher, this.i18nProvider, b);
if (activeProcessor == null) {
logger.debug("Executing a simple dialog for source {} ({})", audioSource.getLabel(null),
audioSource.getId());
processor = new DialogProcessor(sttService, ttsService, prefVoice, interpreters, audioSource, audioSink,
loc, item, this.eventPublisher, this.i18nProvider, b);
processor.start();
singleDialogProcessors.put(audioSource.getId(), processor);
} else if (!isSingleDialog && activeProcessor.isCompatible(processor)) {
logger.debug("Executing a simple dialog for active source {} ({})", audioSource.getLabel(null),
audioSource.getId());
activeProcessor.startSingleDialog();
} else {
throw new IllegalStateException(String.format(
"Cannot execute a simple dialog as a dialog is already started for audio source '%s'.",