added migrated 2.x add-ons
Signed-off-by: Kai Kreuzer <kai@openhab.org>
This commit is contained in:
32
bundles/org.openhab.voice.marytts/.classpath
Normal file
32
bundles/org.openhab.voice.marytts/.classpath
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="test" value="true"/>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
23
bundles/org.openhab.voice.marytts/.project
Normal file
23
bundles/org.openhab.voice.marytts/.project
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>org.openhab.voice.marytts</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
20
bundles/org.openhab.voice.marytts/NOTICE
Normal file
20
bundles/org.openhab.voice.marytts/NOTICE
Normal file
@@ -0,0 +1,20 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
|
||||
== Third-party Content
|
||||
|
||||
marytts
|
||||
* License: LGPL v3.0 License
|
||||
* Project: http://mary.dfki.de
|
||||
* Source: https://github.com/marytts/marytts
|
||||
31
bundles/org.openhab.voice.marytts/README.md
Normal file
31
bundles/org.openhab.voice.marytts/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Mary Text-to-Speech
|
||||
|
||||
## Overview
|
||||
|
||||
The Mary Text-to-Speech (TTS) service is a pure Java implementation of a TTS service, which uses the [MaryTTS](http://mary.dfki.de/) project of DFKI.
|
||||
|
||||
While it provides good quality results, it must be noted that it is too heavy-weight for most embedded hardware like a Raspberry Pi. When using this service, you should be running openHAB on some real server instead.
|
||||
|
||||
## Configuration
|
||||
|
||||
There is no need to configure anything for this service.
|
||||
|
||||
## Voices
|
||||
|
||||
MaryTTS comes with three packages voices, one for American English, two for German:
|
||||
|
||||
```
|
||||
> voice voices
|
||||
marytts:cmuslthsmm cmu-slt-hsmm (en_US)
|
||||
marytts:bits3hsmm bits3-hsmm (de)
|
||||
marytts:bits1hsmm bits1-hsmm (de)
|
||||
```
|
||||
|
||||
## Supported Audio Formats
|
||||
|
||||
The MaryTTS service produces audio streams using WAV containers and PCM (signed) codec with 16bit depth.
|
||||
The sample frequency depends on the chosen voice and ranges from 16kHz to 48kHz.
|
||||
|
||||
## Log files
|
||||
|
||||
The log messages of Mary TTS are not bundled with the openHAB log messages in the `openhab.log` file of your log directory but are stored in their own log file at `server.log` of your log directory.
|
||||
120
bundles/org.openhab.voice.marytts/pom.xml
Normal file
120
bundles/org.openhab.voice.marytts/pom.xml
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.bundles</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.voice.marytts</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Bundles :: Voice :: Mary Text-to-Speech</name>
|
||||
|
||||
<properties>
|
||||
<bnd.importpackage>com.twmacinta.util;resolution:=optional,gnu.trove;resolution:=optional,Jampack;resolution:=optional,net.didion.jwnl*;resolution:=optional,org.apache.http*;resolution:=optional,org.apache.xerces.impl*;resolution:=optional,org.hsqldb;resolution:=optional,org.jdesktop.layout*;resolution:=optional</bnd.importpackage>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
<artifactId>icu4j</artifactId>
|
||||
<version>54.1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-collections</groupId>
|
||||
<artifactId>commons-collections</artifactId>
|
||||
<version>3.2.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.lt.jtok</groupId>
|
||||
<artifactId>jtok-core</artifactId>
|
||||
<version>1.9.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>emotionml-checker-java</artifactId>
|
||||
<version>1.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>marytts-common</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>marytts-lang-de</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>marytts-lang-en</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>marytts-runtime</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>marytts-signalproc</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>voice-bits1-hsmm</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>voice-bits3-hsmm</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>de.dfki.mary</groupId>
|
||||
<artifactId>voice-cmu-slt-hsmm</artifactId>
|
||||
<version>5.2</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>gov.nist.math</groupId>
|
||||
<artifactId>jama</artifactId>
|
||||
<version>1.0.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.opennlp</groupId>
|
||||
<artifactId>opennlp-maxent</artifactId>
|
||||
<version>3.0.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.opennlp</groupId>
|
||||
<artifactId>opennlp-tools</artifactId>
|
||||
<version>1.5.3</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<features name="org.openhab.voice.marytts-${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-marytts" description="Mary Text-to-Speech" version="${project.version}">
|
||||
<feature>openhab-runtime-base</feature>
|
||||
<bundle dependency="true">mvn:commons-collections/commons-collections/3.2.2</bundle>
|
||||
<bundle start-level="80">mvn:org.openhab.addons.bundles/org.openhab.voice.marytts/${project.version}</bundle>
|
||||
</feature>
|
||||
</features>
|
||||
@@ -0,0 +1,161 @@
|
||||
/**
|
||||
* 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.marytts.internal;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.SequenceInputStream;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.openhab.core.audio.AudioException;
|
||||
import org.openhab.core.audio.AudioFormat;
|
||||
import org.openhab.core.audio.AudioSource;
|
||||
import org.openhab.core.audio.FixedLengthAudioStream;
|
||||
|
||||
/**
|
||||
* Implementation of the {@link AudioSource} interface for the {@link MaryTTSService}
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
* @author Kai Kreuzer - Refactored to updated APIs and moved to openHAB
|
||||
*/
|
||||
class MaryTTSAudioStream extends FixedLengthAudioStream {
|
||||
|
||||
/**
|
||||
* {@link AudioFormat} of this {@link AudioSource}
|
||||
*/
|
||||
private final AudioFormat audioFormat;
|
||||
|
||||
/**
|
||||
* {@link InputStream} of this {@link AudioSource}
|
||||
*/
|
||||
private InputStream inputStream;
|
||||
|
||||
private final byte[] rawAudio;
|
||||
private final int length;
|
||||
|
||||
/**
|
||||
* Constructs an instance with the passed properties
|
||||
*
|
||||
* @param inputStream The InputStream of this instance
|
||||
* @param audioFormat The AudioFormat of this instance
|
||||
* @throws IOException
|
||||
*/
|
||||
public MaryTTSAudioStream(AudioInputStream inputStream, AudioFormat audioFormat) throws IOException {
|
||||
rawAudio = IOUtils.toByteArray(inputStream);
|
||||
this.length = rawAudio.length + 36;
|
||||
this.inputStream = new SequenceInputStream(getWavHeaderInputStream(length), new ByteArrayInputStream(rawAudio));
|
||||
this.audioFormat = audioFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioFormat getFormat() {
|
||||
return this.audioFormat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b) throws IOException {
|
||||
return inputStream.read(b, 0, b.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] b, int off, int len) throws IOException {
|
||||
return inputStream.read(b, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
return inputStream.read();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long length() {
|
||||
return length;
|
||||
}
|
||||
|
||||
private InputStream getWavHeaderInputStream(int length) throws IOException {
|
||||
// WAVE header
|
||||
// see http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/WAVE.html
|
||||
byte[] header = new byte[44];
|
||||
|
||||
byte format = 0x10; // PCM
|
||||
byte bits = 16;
|
||||
byte channel = 1;
|
||||
long srate = (this.audioFormat != null) ? this.audioFormat.getFrequency() : 48000l;
|
||||
long rawLength = length - 36;
|
||||
long bitrate = srate * channel * bits;
|
||||
|
||||
header[0] = 'R';
|
||||
header[1] = 'I';
|
||||
header[2] = 'F';
|
||||
header[3] = 'F';
|
||||
header[4] = (byte) (length & 0xff);
|
||||
header[5] = (byte) ((length >> 8) & 0xff);
|
||||
header[6] = (byte) ((length >> 16) & 0xff);
|
||||
header[7] = (byte) ((length >> 24) & 0xff);
|
||||
header[8] = 'W';
|
||||
header[9] = 'A';
|
||||
header[10] = 'V';
|
||||
header[11] = 'E';
|
||||
header[12] = 'f';
|
||||
header[13] = 'm';
|
||||
header[14] = 't';
|
||||
header[15] = ' ';
|
||||
header[16] = format;
|
||||
header[17] = 0;
|
||||
header[18] = 0;
|
||||
header[19] = 0;
|
||||
header[20] = 1;
|
||||
header[21] = 0;
|
||||
header[22] = channel;
|
||||
header[23] = 0;
|
||||
header[24] = (byte) (srate & 0xff);
|
||||
header[25] = (byte) ((srate >> 8) & 0xff);
|
||||
header[26] = (byte) ((srate >> 16) & 0xff);
|
||||
header[27] = (byte) ((srate >> 24) & 0xff);
|
||||
header[28] = (byte) ((bitrate / 8) & 0xff);
|
||||
header[29] = (byte) (((bitrate / 8) >> 8) & 0xff);
|
||||
header[30] = (byte) (((bitrate / 8) >> 16) & 0xff);
|
||||
header[31] = (byte) (((bitrate / 8) >> 24) & 0xff);
|
||||
header[32] = (byte) ((channel * bits) / 8);
|
||||
header[33] = 0;
|
||||
header[34] = 16;
|
||||
header[35] = 0;
|
||||
header[36] = 'd';
|
||||
header[37] = 'a';
|
||||
header[38] = 't';
|
||||
header[39] = 'a';
|
||||
header[40] = (byte) (rawLength & 0xff);
|
||||
header[41] = (byte) ((rawLength >> 8) & 0xff);
|
||||
header[42] = (byte) ((rawLength >> 16) & 0xff);
|
||||
header[43] = (byte) ((rawLength >> 24) & 0xff);
|
||||
return new ByteArrayInputStream(header);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void reset() throws IOException {
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
this.inputStream = new SequenceInputStream(getWavHeaderInputStream(length), new ByteArrayInputStream(rawAudio));
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getClonedStream() throws AudioException {
|
||||
try {
|
||||
return new SequenceInputStream(getWavHeaderInputStream(length), new ByteArrayInputStream(rawAudio));
|
||||
} catch (IOException e) {
|
||||
throw new AudioException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
/**
|
||||
* 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.marytts.internal;
|
||||
|
||||
import static javax.sound.sampled.AudioSystem.NOT_SPECIFIED;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
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.osgi.service.component.annotations.Component;
|
||||
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;
|
||||
|
||||
/**
|
||||
* This is a TTS service implementation for using MaryTTS.
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
* @author Kai Kreuzer - Refactored to updated APIs and moved to openHAB
|
||||
*/
|
||||
@Component
|
||||
public class MaryTTSService implements TTSService {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MaryTTSService.class);
|
||||
|
||||
private MaryInterface marytts;
|
||||
|
||||
/**
|
||||
* Set of supported voices
|
||||
*/
|
||||
private Set<org.openhab.core.voice.Voice> voices;
|
||||
|
||||
/**
|
||||
* Set of supported audio formats
|
||||
*/
|
||||
private Set<AudioFormat> audioFormats;
|
||||
|
||||
protected void activate() {
|
||||
try {
|
||||
marytts = new LocalMaryInterface();
|
||||
voices = initVoices();
|
||||
audioFormats = initAudioFormats();
|
||||
} catch (MaryConfigurationException e) {
|
||||
logger.error("Failed to initialize MaryTTS: {}", e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<org.openhab.core.voice.Voice> getAvailableVoices() {
|
||||
return voices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<AudioFormat> getSupportedFormats() {
|
||||
return audioFormats;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AudioStream synthesize(String text, org.openhab.core.voice.Voice voice, AudioFormat requestedFormat)
|
||||
throws TTSException {
|
||||
// Validate arguments
|
||||
if (text == null || text.isEmpty()) {
|
||||
throw new TTSException("The passed text is null or empty");
|
||||
}
|
||||
if (!voices.contains(voice)) {
|
||||
throw new TTSException("The passed voice is unsupported");
|
||||
}
|
||||
if (audioFormats.stream().noneMatch(f -> f.isCompatible(requestedFormat))) {
|
||||
throw new TTSException("The passed AudioFormat is unsupported");
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: For each MaryTTS voice only a single AudioFormat is supported
|
||||
* However, the TTSService interface allows the AudioFormat and
|
||||
* the Voice to vary independently. Thus, an external user does
|
||||
* not know about the requirement that a given voice is paired
|
||||
* with a given AudioFormat. The test below enforces this.
|
||||
*
|
||||
* However, this leads to a problem. The user has no way to
|
||||
* know which AudioFormat is apropos for a give Voice. Thus,
|
||||
* throwing a TTSException for the wrong AudioFormat makes
|
||||
* the user guess the right AudioFormat, a painful process.
|
||||
* Alternatively, we can get the right AudioFormat for the
|
||||
* Voice and ignore what the user requests, also wrong.
|
||||
*
|
||||
* TODO: Decide what to do
|
||||
* Voice maryTTSVoice = Voice.getVoice(voice.getLabel());
|
||||
* AudioFormat maryTTSVoiceAudioFormat = getAudioFormat(maryTTSVoice.dbAudioFormat());
|
||||
* if (!maryTTSVoiceAudioFormat.isCompatible(requestedFormat)) {
|
||||
* throw new TTSException("The passed AudioFormat is incompatable with the voice");
|
||||
* }
|
||||
*/
|
||||
Voice maryTTSVoice = Voice.getVoice(voice.getLabel());
|
||||
AudioFormat maryTTSVoiceAudioFormat = getAudioFormat(maryTTSVoice.dbAudioFormat());
|
||||
|
||||
// Synchronize on marytts
|
||||
synchronized (marytts) {
|
||||
// Set voice (Each voice supports only a single AudioFormat)
|
||||
marytts.setLocale(voice.getLocale());
|
||||
marytts.setVoice(voice.getLabel());
|
||||
|
||||
try {
|
||||
return new MaryTTSAudioStream(marytts.generateAudio(text), maryTTSVoiceAudioFormat);
|
||||
} catch (SynthesisException | IOException e) {
|
||||
throw new TTSException("Error generating an AudioStream", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes voices
|
||||
*
|
||||
* @return The voices of this instance
|
||||
*/
|
||||
private Set<org.openhab.core.voice.Voice> initVoices() {
|
||||
Set<org.openhab.core.voice.Voice> voices = new HashSet<>();
|
||||
for (Locale locale : marytts.getAvailableLocales()) {
|
||||
for (String voiceLabel : marytts.getAvailableVoices(locale)) {
|
||||
voices.add(new MaryTTSVoice(locale, voiceLabel));
|
||||
}
|
||||
}
|
||||
return voices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes audioFormats
|
||||
*
|
||||
* @return The audio formats of this instance
|
||||
*/
|
||||
private Set<AudioFormat> initAudioFormats() {
|
||||
Set<AudioFormat> audioFormats = new HashSet<>();
|
||||
for (String voiceLabel : marytts.getAvailableVoices()) {
|
||||
audioFormats.add(getAudioFormat(Voice.getVoice(voiceLabel).dbAudioFormat()));
|
||||
}
|
||||
return audioFormats;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains an AudioFormat from a javax.sound.sampled.AudioFormat
|
||||
*
|
||||
* @param audioFormat The javax.sound.sampled.AudioFormat
|
||||
* @return The corresponding AudioFormat
|
||||
*/
|
||||
private AudioFormat getAudioFormat(javax.sound.sampled.AudioFormat audioFormat) {
|
||||
String container = AudioFormat.CONTAINER_WAVE;
|
||||
String codec = audioFormat.getEncoding().toString();
|
||||
Boolean bigEndian = audioFormat.isBigEndian();
|
||||
|
||||
int frameSize = audioFormat.getFrameSize(); // In bytes
|
||||
int bitsPerFrame = frameSize * 8;
|
||||
Integer bitDepth = NOT_SPECIFIED == frameSize ? null : bitsPerFrame;
|
||||
|
||||
float frameRate = audioFormat.getFrameRate();
|
||||
Integer bitRate = NOT_SPECIFIED == frameRate ? null : (int) frameRate * bitsPerFrame;
|
||||
|
||||
float sampleRate = audioFormat.getSampleRate();
|
||||
Long frequency = NOT_SPECIFIED == sampleRate ? null : (long) sampleRate;
|
||||
|
||||
return new AudioFormat(container, codec, bigEndian, bitDepth, bitRate, frequency);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "marytts";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel(Locale locale) {
|
||||
return "MaryTTS";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* 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.marytts.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.openhab.core.voice.Voice;
|
||||
|
||||
/**
|
||||
* Implementation of the Voice interface for MaryTTS
|
||||
*
|
||||
* @author Kelly Davis - Initial contribution and API
|
||||
* @author Kai Kreuzer - Refactored to updated APIs and moved to openHAB
|
||||
*/
|
||||
public class MaryTTSVoice implements Voice {
|
||||
|
||||
/**
|
||||
* Voice locale
|
||||
*/
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Voice label
|
||||
*/
|
||||
private final String label;
|
||||
|
||||
/**
|
||||
* Constructs a MaryTTS Voice for the passed data
|
||||
*
|
||||
* @param locale The Locale of the voice
|
||||
* @param label The label of the voice
|
||||
*/
|
||||
public MaryTTSVoice(Locale locale, String label) {
|
||||
this.locale = locale;
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
/**
|
||||
* Globally unique identifier of the voice.
|
||||
*
|
||||
* @return A String uniquely identifying the voice globally
|
||||
*/
|
||||
@Override
|
||||
public String getUID() {
|
||||
return "marytts:" + label.replaceAll("[^a-zA-Z0-9_]", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* The voice label, used for GUI's or VUI's
|
||||
*
|
||||
* @return The voice label, may not be globally unique
|
||||
*/
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return label;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
@Override
|
||||
public Locale getLocale() {
|
||||
return locale;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
marytts.config.MainConfig
|
||||
marytts.language.de.GermanConfig
|
||||
marytts.language.en.EnglishConfig
|
||||
marytts.voice.Bits1Hsmm.Config
|
||||
marytts.voice.Bits3Hsmm.Config
|
||||
marytts.voice.CmuSltHsmm.Config
|
||||
Reference in New Issue
Block a user