[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>pull/3152/head
parent
18d063e272
commit
9cdaa48fa5
|
@ -150,6 +150,10 @@ public class DialogProcessor implements KSListener, STTListener {
|
||||||
this.ttsFormat = VoiceManagerImpl.getBestMatch(tts.getSupportedFormats(), sink.getSupportedFormats());
|
this.ttsFormat = VoiceManagerImpl.getBestMatch(tts.getSupportedFormats(), sink.getSupportedFormats());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void startSingleDialog() {
|
||||||
|
executeSimpleDialog();
|
||||||
|
}
|
||||||
|
|
||||||
public void start() {
|
public void start() {
|
||||||
KSService ksService = ks;
|
KSService ksService = ks;
|
||||||
if (ksService != null) {
|
if (ksService != null) {
|
||||||
|
@ -211,6 +215,10 @@ public class DialogProcessor implements KSListener, STTListener {
|
||||||
toggleProcessing(false);
|
toggleProcessing(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isProcessing() {
|
||||||
|
return processing;
|
||||||
|
}
|
||||||
|
|
||||||
private void abortKS() {
|
private void abortKS() {
|
||||||
KSServiceHandle handle = ksServiceHandle;
|
KSServiceHandle handle = ksServiceHandle;
|
||||||
if (handle != null) {
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
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 final Map<String, String> defaultVoices = new HashMap<>();
|
||||||
|
|
||||||
private Map<String, DialogProcessor> dialogProcessors = new HashMap<>();
|
private Map<String, DialogProcessor> dialogProcessors = new HashMap<>();
|
||||||
|
private Map<String, DialogProcessor> singleDialogProcessors = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Activate
|
@Activate
|
||||||
public VoiceManagerImpl(final @Reference LocaleProvider localeProvider, final @Reference AudioManager audioManager,
|
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;
|
AudioSource audioSource = (source == null) ? audioManager.getSource() : source;
|
||||||
if (audioSource != null) {
|
if (audioSource != null) {
|
||||||
DialogProcessor processor = dialogProcessors.remove(audioSource.getId());
|
DialogProcessor processor = dialogProcessors.remove(audioSource.getId());
|
||||||
|
singleDialogProcessors.values().removeIf(e -> !e.isProcessing());
|
||||||
|
if (processor == null) {
|
||||||
|
processor = singleDialogProcessors.get(audioSource.getId());
|
||||||
|
}
|
||||||
if (processor != null) {
|
if (processor != null) {
|
||||||
processor.stop();
|
processor.stop();
|
||||||
logger.debug("Dialog stopped for source {} ({})", audioSource.getLabel(null), audioSource.getId());
|
logger.debug("Dialog stopped for source {} ({})", audioSource.getLabel(null), audioSource.getId());
|
||||||
|
@ -598,13 +604,24 @@ public class VoiceManagerImpl implements VoiceManager, ConfigOptionProvider {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"Cannot execute a simple dialog as provided locale is not supported by all services.");
|
"Cannot execute a simple dialog as provided locale is not supported by all services.");
|
||||||
} else {
|
} else {
|
||||||
DialogProcessor processor = dialogProcessors.get(audioSource.getId());
|
boolean isSingleDialog = false;
|
||||||
if (processor == null) {
|
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),
|
logger.debug("Executing a simple dialog for source {} ({})", audioSource.getLabel(null),
|
||||||
audioSource.getId());
|
audioSource.getId());
|
||||||
processor = new DialogProcessor(sttService, ttsService, prefVoice, interpreters, audioSource, audioSink,
|
|
||||||
loc, item, this.eventPublisher, this.i18nProvider, b);
|
|
||||||
processor.start();
|
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 {
|
} else {
|
||||||
throw new IllegalStateException(String.format(
|
throw new IllegalStateException(String.format(
|
||||||
"Cannot execute a simple dialog as a dialog is already started for audio source '%s'.",
|
"Cannot execute a simple dialog as a dialog is already started for audio source '%s'.",
|
||||||
|
|
Loading…
Reference in New Issue