[picotts] Add LRU cache (#14565)

* [picotts] Add LRU cache

Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>

---------

Signed-off-by: Gwendal Roulleau <gwendal.roulleau@gmail.com>
This commit is contained in:
Gwendal Roulleau 2023-07-08 18:09:06 +02:00 committed by GitHub
parent 5bea9bcfdf
commit b17246f00a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 4 deletions

View File

@ -49,3 +49,7 @@ org.openhab.voice:defaultVoice=picotts:frFR
## Supported Audio Formats ## Supported Audio Formats
The Pico service produces audio streams using WAV containers and PCM (signed) codec with 16bit depth. 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.

View File

@ -24,6 +24,7 @@ import org.openhab.core.audio.AudioException;
import org.openhab.core.audio.AudioFormat; import org.openhab.core.audio.AudioFormat;
import org.openhab.core.audio.AudioStream; import org.openhab.core.audio.AudioStream;
import org.openhab.core.audio.FixedLengthAudioStream; import org.openhab.core.audio.FixedLengthAudioStream;
import org.openhab.core.common.Disposable;
import org.openhab.core.voice.Voice; import org.openhab.core.voice.Voice;
/** /**
@ -32,7 +33,8 @@ import org.openhab.core.voice.Voice;
* @author Florian Schmidt - Initial Contribution * @author Florian Schmidt - Initial Contribution
*/ */
@NonNullByDefault @NonNullByDefault
class PicoTTSAudioStream extends FixedLengthAudioStream { class PicoTTSAudioStream extends FixedLengthAudioStream implements Disposable {
private final Voice voice; private final Voice voice;
private final String text; private final String text;
private final AudioFormat audioFormat; private final AudioFormat audioFormat;
@ -127,4 +129,18 @@ class PicoTTSAudioStream extends FixedLengthAudioStream {
throw new AudioException("No temporary audio file available."); 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);
}
}
}
} }

View File

@ -23,17 +23,27 @@ import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.audio.AudioException; import org.openhab.core.audio.AudioException;
import org.openhab.core.audio.AudioFormat; import org.openhab.core.audio.AudioFormat;
import org.openhab.core.audio.AudioStream; 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.TTSException;
import org.openhab.core.voice.TTSService; import org.openhab.core.voice.TTSService;
import org.openhab.core.voice.Voice; 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.Component;
import org.osgi.service.component.annotations.Reference;
/** /**
* @author Florian Schmidt - Initial Contribution * @author Florian Schmidt - Initial Contribution
*/ */
@Component @Component(service = TTSService.class)
@NonNullByDefault @NonNullByDefault
public class PicoTTSService implements TTSService { public class PicoTTSService extends AbstractCachedTTSService {
@Activate
public PicoTTSService(@Reference TTSCache ttsCache) {
super(ttsCache);
}
private final Set<Voice> voices = Stream private final Set<Voice> voices = Stream
.of(new PicoTTSVoice("de-DE"), new PicoTTSVoice("en-US"), new PicoTTSVoice("en-GB"), .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")) new PicoTTSVoice("es-ES"), new PicoTTSVoice("fr-FR"), new PicoTTSVoice("it-IT"))
@ -53,7 +63,7 @@ public class PicoTTSService implements TTSService {
} }
@Override @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()) { if (text.isEmpty()) {
throw new TTSException("The passed text can not be empty"); throw new TTSException("The passed text can not be empty");
} }