diff --git a/bundles/org.openhab.voice.picotts/README.md b/bundles/org.openhab.voice.picotts/README.md index cee6eb0ae..ad7d6a151 100644 --- a/bundles/org.openhab.voice.picotts/README.md +++ b/bundles/org.openhab.voice.picotts/README.md @@ -49,3 +49,7 @@ org.openhab.voice:defaultVoice=picotts:frFR ## Supported Audio Formats The Pico service produces audio streams using WAV containers and PCM (signed) codec with 16bit depth. + +## Caching + +The Pico TTS service uses the openHAB TTS cache to cache audio files produced from the most recent queries in order to reduce traffic, improve performance and reduce number of requests. diff --git a/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSAudioStream.java b/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSAudioStream.java index af4e24c6e..da384f443 100644 --- a/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSAudioStream.java +++ b/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSAudioStream.java @@ -24,6 +24,7 @@ import org.openhab.core.audio.AudioException; import org.openhab.core.audio.AudioFormat; import org.openhab.core.audio.AudioStream; import org.openhab.core.audio.FixedLengthAudioStream; +import org.openhab.core.common.Disposable; import org.openhab.core.voice.Voice; /** @@ -32,7 +33,8 @@ import org.openhab.core.voice.Voice; * @author Florian Schmidt - Initial Contribution */ @NonNullByDefault -class PicoTTSAudioStream extends FixedLengthAudioStream { +class PicoTTSAudioStream extends FixedLengthAudioStream implements Disposable { + private final Voice voice; private final String text; private final AudioFormat audioFormat; @@ -127,4 +129,18 @@ class PicoTTSAudioStream extends FixedLengthAudioStream { throw new AudioException("No temporary audio file available."); } } + + @Override + public void dispose() throws IOException { + File localFile = file; + if (localFile != null && localFile.exists()) { + try { + if (!localFile.delete()) { + throw new IOException("Failed to delete the file " + localFile.getAbsolutePath()); + } + } catch (SecurityException e) { + throw new IOException("Failed to delete the file " + localFile.getAbsolutePath(), e); + } + } + } } diff --git a/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSService.java b/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSService.java index 442f4acdc..ecb6a2ebb 100644 --- a/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSService.java +++ b/bundles/org.openhab.voice.picotts/src/main/java/org/openhab/voice/picotts/internal/PicoTTSService.java @@ -23,17 +23,27 @@ import org.eclipse.jdt.annotation.Nullable; import org.openhab.core.audio.AudioException; import org.openhab.core.audio.AudioFormat; import org.openhab.core.audio.AudioStream; +import org.openhab.core.voice.AbstractCachedTTSService; +import org.openhab.core.voice.TTSCache; import org.openhab.core.voice.TTSException; import org.openhab.core.voice.TTSService; import org.openhab.core.voice.Voice; +import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; /** * @author Florian Schmidt - Initial Contribution */ -@Component +@Component(service = TTSService.class) @NonNullByDefault -public class PicoTTSService implements TTSService { +public class PicoTTSService extends AbstractCachedTTSService { + + @Activate + public PicoTTSService(@Reference TTSCache ttsCache) { + super(ttsCache); + } + private final Set voices = Stream .of(new PicoTTSVoice("de-DE"), new PicoTTSVoice("en-US"), new PicoTTSVoice("en-GB"), new PicoTTSVoice("es-ES"), new PicoTTSVoice("fr-FR"), new PicoTTSVoice("it-IT")) @@ -53,7 +63,7 @@ public class PicoTTSService implements TTSService { } @Override - public AudioStream synthesize(String text, Voice voice, AudioFormat requestedFormat) throws TTSException { + public AudioStream synthesizeForCache(String text, Voice voice, AudioFormat requestedFormat) throws TTSException { if (text.isEmpty()) { throw new TTSException("The passed text can not be empty"); }