added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.voice.mactts-${project.version}" xmlns="http://karaf.apache.org/xmlns/features/v1.4.0">
|
||||
<repository>mvn:org.openhab.core.features.karaf/org.openhab.core.features.karaf.openhab-core/${ohc.version}/xml/features</repository>
|
||||
|
||||
<feature name="openhab-voice-mactts" description="macOS Text-to-Speech" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.voice.mactts/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,167 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.voice.mactts.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
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.voice.Voice;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link AudioStream} interface for the {@link MacTTSService}
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
* @author Kai Kreuzer - Refactored to use AudioStream and fixed audio format to produce
|
||||
*/
|
||||
class MacTTSAudioStream extends FixedLengthAudioStream {
|
||||
|
||||
/**
|
||||
* {@link Voice} this {@link AudioStream} speaks in
|
||||
*/
|
||||
private final Voice voice;
|
||||
|
||||
/**
|
||||
* Text spoken in this {@link AudioStream}
|
||||
*/
|
||||
private final String text;
|
||||
|
||||
/**
|
||||
* {@link AudioFormat} of this {@link AudioStream}
|
||||
*/
|
||||
private final AudioFormat audioFormat;
|
||||
|
||||
/**
|
||||
* The raw input stream
|
||||
*/
|
||||
private InputStream inputStream;
|
||||
|
||||
private long length;
|
||||
private File file;
|
||||
|
||||
/**
|
||||
* Constructs an instance with the passed properties.
|
||||
*
|
||||
* It is assumed that the passed properties have been validated.
|
||||
*
|
||||
* @param text The text spoken in this {@link AudioStream}
|
||||
* @param voice The {@link Voice} used to speak this instance's text
|
||||
* @param audioFormat The {@link AudioFormat} of this {@link AudioStream}
|
||||
* @throws AudioException if stream cannot be created
|
||||
*/
|
||||
public MacTTSAudioStream(String text, Voice voice, AudioFormat audioFormat) throws AudioException {
|
||||
this.text = text;
|
||||
this.voice = voice;
|
||||
this.audioFormat = audioFormat;
|
||||
this.inputStream = createInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioFormat getFormat() {
|
||||
return audioFormat;
|
||||
}
|
||||
|
||||
private InputStream createInputStream() throws AudioException {
|
||||
String outputFile = generateOutputFilename();
|
||||
String command = getCommand(outputFile);
|
||||
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec(command);
|
||||
process.waitFor();
|
||||
file = new File(outputFile);
|
||||
this.length = file.length();
|
||||
return getFileInputStream(file);
|
||||
} catch (IOException e) {
|
||||
throw new AudioException("Error while executing '" + command + "'", e);
|
||||
} catch (InterruptedException e) {
|
||||
throw new AudioException("The '" + command + "' has been interrupted", e);
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream getFileInputStream(File file) throws AudioException {
|
||||
if (file == null) {
|
||||
throw new IllegalArgumentException("file must not be null");
|
||||
}
|
||||
if (file.exists()) {
|
||||
try {
|
||||
return new FileInputStream(file);
|
||||
} catch (FileNotFoundException e) {
|
||||
throw new AudioException("Cannot open temporary audio file '" + file.getName() + ".");
|
||||
}
|
||||
} else {
|
||||
throw new AudioException("Temporary file '" + file.getName() + "' not found!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a unique, absolute output filename
|
||||
*
|
||||
* @return Unique, absolute output filename
|
||||
*/
|
||||
private String generateOutputFilename() throws AudioException {
|
||||
File tempFile;
|
||||
try {
|
||||
tempFile = File.createTempFile(Integer.toString(text.hashCode()), ".wav");
|
||||
tempFile.deleteOnExit();
|
||||
} catch (IOException e) {
|
||||
throw new AudioException("Unable to create temp file.", e);
|
||||
}
|
||||
return tempFile.getAbsolutePath();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the command used to generate an audio file {@code outputFile}
|
||||
*
|
||||
* @param outputFile The absolute filename of the command's output
|
||||
* @return The command used to generate the audio file {@code outputFile}
|
||||
*/
|
||||
private String getCommand(String outputFile) {
|
||||
StringBuffer stringBuffer = new StringBuffer();
|
||||
|
||||
stringBuffer.append("say");
|
||||
|
||||
stringBuffer.append(" --voice=" + this.voice.getLabel());
|
||||
stringBuffer.append(" --output-file=" + outputFile);
|
||||
stringBuffer.append(" --file-format=" + this.audioFormat.getContainer());
|
||||
stringBuffer.append(" --data-format=LEI" + audioFormat.getBitDepth() + "@" + audioFormat.getFrequency());
|
||||
stringBuffer.append(" --channels=1"); // Mono
|
||||
stringBuffer.append(" " + this.text);
|
||||
|
||||
return stringBuffer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return inputStream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getClonedStream() throws AudioException {
|
||||
if (file != null) {
|
||||
return getFileInputStream(file);
|
||||
} else {
|
||||
throw new AudioException("No temporary audio file available.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.voice.mactts.internal;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.openhab.core.audio.AudioException;
|
||||
import org.openhab.core.audio.AudioFormat;
|
||||
import org.openhab.core.audio.AudioStream;
|
||||
import org.openhab.core.voice.TTSException;
|
||||
import org.openhab.core.voice.TTSService;
|
||||
import org.openhab.core.voice.Voice;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* This is a TTS service implementation for Mac OS, which simply uses the "say" command from the OS.
|
||||
*
|
||||
* @author Kai Kreuzer - Initial contribution and API
|
||||
* @author Pauli Antilla
|
||||
* @author Kelly Davis
|
||||
*/
|
||||
@Component
|
||||
public class MacTTSService implements TTSService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MacTTSService.class);
|
||||
|
||||
/**
|
||||
* Set of supported voices
|
||||
*/
|
||||
private final Set<Voice> voices = initVoices();
|
||||
|
||||
/**
|
||||
* Set of supported audio formats
|
||||
*/
|
||||
private final Set<AudioFormat> audioFormats = initAudioFormats();
|
||||
|
||||
@Override
|
||||
public Set<Voice> getAvailableVoices() {
|
||||
return this.voices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AudioFormat> getSupportedFormats() {
|
||||
return this.audioFormats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioStream synthesize(String text, Voice voice, AudioFormat requestedFormat) throws TTSException {
|
||||
// Validate arguments
|
||||
if ((null == text) || text.isEmpty()) {
|
||||
throw new TTSException("The passed text is null or empty");
|
||||
}
|
||||
if (!this.voices.contains(voice)) {
|
||||
throw new TTSException("The passed voice is unsupported");
|
||||
}
|
||||
boolean isAudioFormatSupported = false;
|
||||
for (AudioFormat currentAudioFormat : this.audioFormats) {
|
||||
if (currentAudioFormat.isCompatible(requestedFormat)) {
|
||||
isAudioFormatSupported = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!isAudioFormatSupported) {
|
||||
throw new TTSException("The passed AudioFormat is unsupported");
|
||||
}
|
||||
|
||||
try {
|
||||
return new MacTTSAudioStream(text, voice, requestedFormat);
|
||||
} catch (AudioException e) {
|
||||
throw new TTSException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this.voices
|
||||
*
|
||||
* @return The voices of this instance
|
||||
*/
|
||||
private final Set<Voice> initVoices() {
|
||||
Set<Voice> voices = new HashSet<>();
|
||||
InputStreamReader inputStreamReader = null;
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("say -v ?");
|
||||
inputStreamReader = new InputStreamReader(process.getInputStream());
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
|
||||
String nextLine;
|
||||
while ((nextLine = bufferedReader.readLine()) != null) {
|
||||
voices.add(new MacTTSVoice(nextLine));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Error while executing the 'say -v ?' command: {}", e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(bufferedReader);
|
||||
}
|
||||
return voices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes this.audioFormats
|
||||
*
|
||||
* @return The audio formats of this instance
|
||||
*/
|
||||
private final Set<AudioFormat> initAudioFormats() {
|
||||
AudioFormat audioFormat = new AudioFormat(AudioFormat.CONTAINER_WAVE, AudioFormat.CODEC_PCM_SIGNED, false, 16,
|
||||
null, (long) 44100);
|
||||
return Collections.singleton(audioFormat);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "mactts";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel(Locale locale) {
|
||||
return "macOS TTS";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.voice.mactts.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.openhab.core.voice.Voice;
|
||||
|
||||
/**
|
||||
* Implementation of the Voice interface for macOS
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
*/
|
||||
public class MacTTSVoice implements Voice {
|
||||
|
||||
/**
|
||||
* Voice label
|
||||
*/
|
||||
private String label;
|
||||
|
||||
/**
|
||||
* Voice language (ISO 639 alpha-2)
|
||||
*/
|
||||
private String language;
|
||||
|
||||
/**
|
||||
* Voice country (ISO 3166 alpha-2)
|
||||
*/
|
||||
private String country;
|
||||
|
||||
/**
|
||||
* Voice variant
|
||||
*/
|
||||
private String variant;
|
||||
|
||||
/**
|
||||
* Constructs a MacTTSVoice instance corresponding to a single line
|
||||
* returned from a call to the command
|
||||
*
|
||||
* {@code 'say -v ?'}
|
||||
*
|
||||
* For example, a single line from the call above could have the form
|
||||
*
|
||||
* {@code Agnes en_US # Isn't it nice to have a computer that will talk to you?}
|
||||
*
|
||||
* Generically, a single line from the call above has the form
|
||||
*
|
||||
* {@code <Label> <Locale> # <Sentence>}
|
||||
*
|
||||
* where <Label> is the voice name (which may contain spaces), <Locale>
|
||||
* is the locale ISO 639 alpha-2 + "_" + ISO 3166 alpha-2 and <Sentence>
|
||||
* is an example sentence in <Locale>.
|
||||
*
|
||||
* @param line Line from a 'say -v ?' call.
|
||||
*/
|
||||
public MacTTSVoice(String line) {
|
||||
// Default to null's
|
||||
this.label = null;
|
||||
this.country = null;
|
||||
this.variant = null;
|
||||
this.language = null;
|
||||
|
||||
// Parse line into tokens
|
||||
StringTokenizer stringTokenizer = new StringTokenizer(line);
|
||||
while (stringTokenizer.hasMoreTokens()) {
|
||||
// Get next token
|
||||
String token = stringTokenizer.nextToken();
|
||||
|
||||
// Ignore <Sentence>
|
||||
if (token.startsWith("#")) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Check that we are parsing <Label> or <Locale> for Scotland
|
||||
int underscore = token.indexOf('_');
|
||||
if (-1 == underscore) {
|
||||
// Check we're dealing with <Label>
|
||||
if (!token.equals("en-scotland")) {
|
||||
if (null == this.label) {
|
||||
this.label = token;
|
||||
} else {
|
||||
this.label = this.label + " " + token;
|
||||
}
|
||||
} else { // Else we're dealnig with <Locale> for Scotland
|
||||
this.language = "en";
|
||||
this.country = "GB";
|
||||
this.variant = "scotland";
|
||||
}
|
||||
} else { // Parse non-Scottish <Locale>
|
||||
this.language = token.substring(0, underscore);
|
||||
this.country = token.substring(underscore + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Globally unique identifier of the voice.
|
||||
*
|
||||
* @return A String uniquely identifying the voice globally
|
||||
*/
|
||||
@Override
|
||||
public String getUID() {
|
||||
return "mactts:" + label.replaceAll("[^a-zA-Z0-9_]", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* The voice label, used for GUIs
|
||||
*
|
||||
* @return The voice label, may not be globally unique
|
||||
*/
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
Locale locale;
|
||||
|
||||
if (variant != null) {
|
||||
locale = new Locale(language, country, variant);
|
||||
} else if (country != null) {
|
||||
locale = new Locale(language, country);
|
||||
} else {
|
||||
locale = new Locale(language);
|
||||
}
|
||||
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.voice.mactts.internal;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* Test MacTTSVoice
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
*/
|
||||
public class MacTTSVoiceTest {
|
||||
|
||||
Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
/**
|
||||
* Test MacTTSVoice(String) constructor
|
||||
*/
|
||||
@Test
|
||||
public void testConstructor() {
|
||||
Assume.assumeTrue("Mac OS X".equals(System.getProperty("os.name")));
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("say -v ?");
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
|
||||
String nextLine = bufferedReader.readLine();
|
||||
MacTTSVoice voiceMacOS = new MacTTSVoice(nextLine);
|
||||
Assert.assertNotNull("The MacTTSVoice(String) constructor failed", voiceMacOS);
|
||||
} catch (IOException e) {
|
||||
Assert.fail("testConstructor() failed with IOException: " + e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(bufferedReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test VoiceMacOS.getUID()
|
||||
*/
|
||||
@Test
|
||||
public void getUIDTest() {
|
||||
Assume.assumeTrue("Mac OS X".equals(System.getProperty("os.name")));
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("say -v ?");
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
|
||||
String nextLine = bufferedReader.readLine();
|
||||
MacTTSVoice macTTSVoice = new MacTTSVoice(nextLine);
|
||||
Assert.assertTrue("The VoiceMacOS UID has an incorrect format",
|
||||
(0 == macTTSVoice.getUID().indexOf("mactts:")));
|
||||
} catch (IOException e) {
|
||||
Assert.fail("getUIDTest() failed with IOException: " + e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(bufferedReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test MacTTSVoice.getLabel()
|
||||
*/
|
||||
@Test
|
||||
public void getLabelTest() {
|
||||
Assume.assumeTrue("Mac OS X".equals(System.getProperty("os.name")));
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("say -v ?");
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
|
||||
String nextLine = bufferedReader.readLine();
|
||||
MacTTSVoice voiceMacOS = new MacTTSVoice(nextLine);
|
||||
Assert.assertNotNull("The MacTTSVoice label has an incorrect format", voiceMacOS.getLabel());
|
||||
} catch (IOException e) {
|
||||
Assert.fail("getLabelTest() failed with IOException: " + e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(bufferedReader);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test MacTTSVoice.getLocale()
|
||||
*/
|
||||
@Test
|
||||
public void getLocaleTest() {
|
||||
Assume.assumeTrue("Mac OS X" == System.getProperty("os.name"));
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
Process process = Runtime.getRuntime().exec("say -v ?");
|
||||
InputStreamReader inputStreamReader = new InputStreamReader(process.getInputStream());
|
||||
bufferedReader = new BufferedReader(inputStreamReader);
|
||||
|
||||
String nextLine = bufferedReader.readLine();
|
||||
MacTTSVoice voiceMacOS = new MacTTSVoice(nextLine);
|
||||
Assert.assertNotNull("The MacTTSVoice locale has an incorrect format", voiceMacOS.getLocale());
|
||||
} catch (IOException e) {
|
||||
Assert.fail("getLocaleTest() failed with IOException: " + e.getMessage());
|
||||
} finally {
|
||||
IOUtils.closeQuietly(bufferedReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Copyright (c) 2010-2020 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.voice.mactts.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Assume;
|
||||
import org.junit.Test;
|
||||
import org.openhab.core.audio.AudioFormat;
|
||||
import org.openhab.core.audio.AudioStream;
|
||||
import org.openhab.core.voice.TTSException;
|
||||
import org.openhab.core.voice.Voice;
|
||||
|
||||
/**
|
||||
* Test TTSServiceMacOS
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
*/
|
||||
public class TTSServiceMacOSTest {
|
||||
|
||||
/**
|
||||
* Test TTSServiceMacOS.getAvailableVoices()
|
||||
*/
|
||||
@Test
|
||||
public void getAvailableVoicesTest() {
|
||||
Assume.assumeTrue("Mac OS X".equals(System.getProperty("os.name")));
|
||||
|
||||
MacTTSService ttsServiceMacOS = new MacTTSService();
|
||||
Assert.assertFalse("The getAvailableVoicesTest() failed", ttsServiceMacOS.getAvailableVoices().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test TTSServiceMacOS.getSupportedFormats()
|
||||
*/
|
||||
@Test
|
||||
public void getSupportedFormatsTest() {
|
||||
Assume.assumeTrue("Mac OS X".equals(System.getProperty("os.name")));
|
||||
|
||||
MacTTSService ttsServiceMacOS = new MacTTSService();
|
||||
Assert.assertFalse("The getSupportedFormatsTest() failed", ttsServiceMacOS.getSupportedFormats().isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test TTSServiceMacOS.synthesize(String,Voice,AudioFormat)
|
||||
*/
|
||||
@Test
|
||||
public void synthesizeTest() {
|
||||
Assume.assumeTrue("Mac OS X".equals(System.getProperty("os.name")));
|
||||
|
||||
MacTTSService ttsServiceMacOS = new MacTTSService();
|
||||
Set<Voice> voices = ttsServiceMacOS.getAvailableVoices();
|
||||
Set<AudioFormat> audioFormats = ttsServiceMacOS.getSupportedFormats();
|
||||
try (AudioStream audioStream = ttsServiceMacOS.synthesize("Hello", voices.iterator().next(),
|
||||
audioFormats.iterator().next())) {
|
||||
Assert.assertNotNull("The test synthesizeTest() created null AudioSource", audioStream);
|
||||
Assert.assertNotNull("The test synthesizeTest() created an AudioSource w/o AudioFormat",
|
||||
audioStream.getFormat());
|
||||
Assert.assertNotNull("The test synthesizeTest() created an AudioSource w/o InputStream", audioStream);
|
||||
Assert.assertTrue("The test synthesizeTest() returned an AudioSource with no data",
|
||||
(-1 != audioStream.read(new byte[2])));
|
||||
} catch (TTSException e) {
|
||||
Assert.fail("synthesizeTest() failed with TTSException: " + e.getMessage());
|
||||
} catch (IOException e) {
|
||||
Assert.fail("synthesizeTest() failed with IOException: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user