private static final Map<Long, String> FREQUENCY_MAP = Map.of(8_000L, "8khz", 11_025L, "11khz", 12_000L, "12khz",
16_000L, "16khz", 22_050L, "22khz", 24_000L, "24khz", 32_000L, "32khz", 44_100L, "44khz", 48_000L, "48khz");
- private String apiKey;
-
private final Logger logger = LoggerFactory.getLogger(VoiceRSSTTSService.class);
+ private String apiKey;
+
/**
* We need the cached implementation to allow for FixedLengthAudioStream.
*/
logger.debug("Using VoiceRSS cache folder {}", getCacheFolderName());
} catch (IllegalStateException e) {
- logger.error("Failed to activate VoiceRSS: {}", e.getMessage(), e);
+ logger.warn("Failed to activate VoiceRSS: {}", e.getMessage(), e);
}
}
File cacheAudioFile = voiceRssImpl.getTextToSpeechAsFile(apiKey, trimmedText,
voice.getLocale().toLanguageTag(), voice.getLabel(), getApiAudioCodec(requestedFormat),
getApiAudioFormat(requestedFormat));
- if (cacheAudioFile == null) {
- throw new TTSException("Could not read from VoiceRSS service");
- }
return new VoiceRSSAudioStream(cacheAudioFile, requestedFormat);
} catch (AudioException ex) {
throw new TTSException("Could not create AudioStream: " + ex.getMessage(), ex);
}
}
- private CachedVoiceRSSCloudImpl initVoiceImplementation() {
+ private CachedVoiceRSSCloudImpl initVoiceImplementation() throws IllegalStateException {
return new CachedVoiceRSSCloudImpl(getCacheFolderName());
}
package org.openhab.voice.voicerss.internal.cloudapi;
import java.io.File;
-import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
*/
public class CachedVoiceRSSCloudImpl extends VoiceRSSCloudImpl {
- private final Logger logger = LoggerFactory.getLogger(CachedVoiceRSSCloudImpl.class);
-
- private final File cacheFolder;
-
/**
* Stream buffer size
*/
private static final int READ_BUFFER_SIZE = 4096;
- public CachedVoiceRSSCloudImpl(String cacheFolderName) {
+ private final Logger logger = LoggerFactory.getLogger(CachedVoiceRSSCloudImpl.class);
+
+ private final File cacheFolder;
+
+ public CachedVoiceRSSCloudImpl(String cacheFolderName) throws IllegalStateException {
if (cacheFolderName == null) {
throw new IllegalStateException("Folder for cache must be defined");
}
public File getTextToSpeechAsFile(String apiKey, String text, String locale, String voice, String audioCodec,
String audioFormat) throws IOException {
String fileNameInCache = getUniqueFilenameForText(text, locale, voice, audioFormat);
+ if (fileNameInCache == null) {
+ throw new IOException("Could not infer cache file name");
+ }
// check if in cache
File audioFileInCache = new File(cacheFolder, fileNameInCache + "." + audioCodec.toLowerCase());
if (audioFileInCache.exists()) {
writeText(txtFileInCache, text);
// return from cache
return audioFileInCache;
- } catch (FileNotFoundException ex) {
- logger.warn("Could not write {} to cache", audioFileInCache, ex);
- return null;
} catch (IOException ex) {
- logger.error("Could not write {} to cache", audioFileInCache, ex);
- return null;
+ throw new IOException("Could not write to cache file: " + ex.getMessage(), ex);
}
}
Set<String> getAvailableVoices(Locale locale);
/**
- * Get the given text in specified locale and auido format as input stream.
+ * Get the given text in specified locale and audio format as input stream.
*
* @param apiKey
* the API key to use for the cloud service
public static final String API_URL = "https://api.voicerss.org/?key=%s&hl=%s&c=%s&f=%s&src=%s";
public static final String API_URL_WITH_VOICE = API_URL + "&v=%s";
- private final Logger logger = LoggerFactory.getLogger(VoiceRSSCloudImpl.class);
-
private static final Set<AudioFormat> SUPPORTED_AUDIO_FORMATS = Set.of(
new AudioFormat(AudioFormat.CONTAINER_NONE, AudioFormat.CODEC_MP3, null, 16, null, 44_100L),
new AudioFormat(AudioFormat.CONTAINER_OGG, AudioFormat.CODEC_VORBIS, null, 16, null, 44_100L),
SUPPORTED_VOICES.put("zh-tw", Set.of("Akemi", "Lin", "Lee"));
}
+ private final Logger logger = LoggerFactory.getLogger(VoiceRSSCloudImpl.class);
+
@Override
public Set<AudioFormat> getAvailableAudioFormats() {
return SUPPORTED_AUDIO_FORMATS;
return allvoxes;
}
- /**
+ /*
* This method will return an input stream to an audio stream for the given
* parameters.
*
public InputStream getTextToSpeech(String apiKey, String text, String locale, String voice, String audioCodec,
String audioFormat) throws IOException {
String url = createURL(apiKey, text, locale, voice, audioCodec, audioFormat);
- logger.debug("Call {}", url);
+ logger.debug("Call {}", url.replace(apiKey, "***"));
URLConnection connection = new URL(url).openConnection();
// we will check return codes. The service will ALWAYS return a HTTP
// the error message in body
int status = ((HttpURLConnection) connection).getResponseCode();
if (HttpURLConnection.HTTP_OK != status) {
- logger.error("Call {} returned HTTP {}", url, status);
+ logger.warn("Call {} returned HTTP {}", url.replace(apiKey, "***"), status);
throw new IOException("Could not read from service: HTTP code " + status);
}
if (logger.isTraceEnabled()) {
logger.debug("Failed to close inputstream", ex);
}
throw new IOException(
- "Could not read audio content, service return an error: " + new String(bytes, "UTF-8"));
+ "Could not read audio content, service returned an error: " + new String(bytes, "UTF-8"));
} else {
return is;
}