/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.io.multimedia.internal.tts; import java.util.Locale; import javax.sound.sampled.AudioInputStream; import org.apache.commons.lang.StringUtils; import org.openhab.io.multimedia.tts.TTSService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import marytts.LocalMaryInterface; import marytts.MaryInterface; import marytts.exceptions.MaryConfigurationException; import marytts.exceptions.SynthesisException; import marytts.modules.synthesis.Voice; import marytts.util.data.audio.AudioPlayer; /** * This is a pure Java TTS service implementation, based on MaryTTS. * * @author Tobias Bräutigam * @since 1.1.0 * */ public class TTSServiceMaryTTS implements TTSService { private static final Logger logger = LoggerFactory.getLogger(TTSServiceMaryTTS.class); private static MaryInterface marytts; private Voice defaultVoice; public void activate() { try { marytts = new LocalMaryInterface(); Locale systemLocale = Locale.getDefault(); if (marytts.getAvailableLocales().contains(systemLocale)) { defaultVoice = Voice.getDefaultVoice(systemLocale); } if (defaultVoice == null) { // Fallback defaultVoice = Voice.getVoice(marytts.getAvailableVoices().iterator().next()); } } catch (MaryConfigurationException e) { logger.error("Error connecting to Mary TTS: " + e.getLocalizedMessage(), e); } } public void deactivate() { marytts = null; } /** * {@inheritDoc} */ public void say(String text, String voiceName, String outputDevice) { if (marytts == null) { logger.error("Mary TTS is not available"); return; } if (text == null) { return; } Voice voice = null; if (StringUtils.isBlank(voiceName)) { logger.debug("Mary TTS: {} (Voice not set. Using default voice {}).", new String[] { text, defaultVoice.toString() }); voice = defaultVoice; } else { voice = Voice.getVoice(voiceName); logger.debug("Mary TTS: {} (Voice: {})", new String[] { text, voiceName }); } if (voice != null) { // Workaround: we have to set the Locale first, because only in the LocalMaryInterface.setLocale() method // the required private method // LocalMaryInterface.setAudioFileFormatForVoice() method is called. After that we can set the voice, // otherwise an NPE occurs marytts.setLocale(voice.getLocale()); marytts.setVoice(voice.getName()); try { AudioInputStream audio = marytts.generateAudio(text); AudioPlayer player = new AudioPlayer(audio); player.start(); player.join(); } catch (SynthesisException e) { logger.error("Error during tts generation: {}", e.getLocalizedMessage(), e); } catch (InterruptedException e) { logger.error("Error during tts playback: {}", e.getLocalizedMessage(), e); } } else { logger.error("Could not find voice: {}", voiceName); logger.info("Available Voices are {} ", StringUtils.join(marytts.getAvailableVoices(), ", ")); } } }