зеркало из https://github.com/mozilla/smarthome.git
Fixed Issue #47 (say command should use Voice with the default language) and Issue #53 (say command should use a 'concrete' AudioFormat)
This commit is contained in:
Родитель
d9c3fc0849
Коммит
fee9c85f49
|
@ -7,9 +7,11 @@
|
|||
*/
|
||||
package org.eclipse.smarthome.io.voice.internal.extensions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.smarthome.core.items.Item;
|
||||
|
@ -77,8 +79,12 @@ public class SayConsoleCommandExtension extends AbstractConsoleCommandExtension
|
|||
if (ttsService != null) {
|
||||
Set<Voice> voices = ttsService.getAvailableVoices();
|
||||
Set<AudioFormat> audioFormats = ttsService.getSupportedFormats();
|
||||
|
||||
Voice voice = getPreferedVoice(voices);
|
||||
AudioFormat audioFormat = getPreferedAudioFormat(audioFormats);
|
||||
|
||||
try {
|
||||
AudioSource audioSource = ttsService.synthesize(msg.toString(), voices.iterator().next(), audioFormats.iterator().next());
|
||||
AudioSource audioSource = ttsService.synthesize(msg.toString(), voice, audioFormat);
|
||||
AudioPlayer audioPlayer = new AudioPlayer(audioSource);
|
||||
audioPlayer.start();
|
||||
audioPlayer.join();
|
||||
|
@ -93,6 +99,113 @@ public class SayConsoleCommandExtension extends AbstractConsoleCommandExtension
|
|||
}
|
||||
}
|
||||
|
||||
protected Voice getPreferedVoice(Set<Voice> voices) {
|
||||
// Express preferences with a Language Priority List
|
||||
Locale locale = Locale.getDefault();
|
||||
String ranges = locale.toLanguageTag();
|
||||
List<Locale.LanguageRange> languageRanges = Locale.LanguageRange.parse(ranges);
|
||||
|
||||
// Get collection of voice locales
|
||||
Collection<Locale> locales = new ArrayList<Locale>();
|
||||
for (Voice currentVoice : voices) {
|
||||
locales.add(currentVoice.getLocale());
|
||||
}
|
||||
|
||||
// Determine prefered locale based on RFC 4647
|
||||
Locale preferedLocale = Locale.lookup(languageRanges,locales);
|
||||
|
||||
// As a last resort choose some Locale
|
||||
if (null == preferedLocale) {
|
||||
preferedLocale = locales.iterator().next();
|
||||
}
|
||||
|
||||
// Determine prefered voice
|
||||
Voice preferedVoice = null;
|
||||
for (Voice currentVoice : voices) {
|
||||
if (preferedLocale.equals(currentVoice.getLocale())) {
|
||||
preferedVoice = currentVoice;
|
||||
}
|
||||
}
|
||||
assert (preferedVoice != null);
|
||||
|
||||
// Return prefered voice
|
||||
return preferedVoice;
|
||||
}
|
||||
|
||||
protected AudioFormat getPreferedAudioFormat(Set<AudioFormat> audioFormats) {
|
||||
// Return the first concrete AudioFormat found
|
||||
for (AudioFormat currentAudioFormat : audioFormats) {
|
||||
// Check if currentAudioFormat is abstract
|
||||
if (null == currentAudioFormat.getCodec()) { continue; }
|
||||
if (null == currentAudioFormat.getContainer()) { continue; }
|
||||
if (null == currentAudioFormat.isBigEndian()) { continue; }
|
||||
if (null == currentAudioFormat.getBitDepth()) { continue; }
|
||||
if (null == currentAudioFormat.getBitRate()) { continue; }
|
||||
if (null == currentAudioFormat.getFrequency()) { continue; }
|
||||
|
||||
// Prefer WAVE container
|
||||
if (!currentAudioFormat.getContainer().equals("WAVE")) { continue; }
|
||||
|
||||
// As currentAudioFormat is concreate, use it
|
||||
return currentAudioFormat;
|
||||
}
|
||||
|
||||
// There's no concrete AudioFormat so we must create one
|
||||
for (AudioFormat currentAudioFormat : audioFormats) {
|
||||
// Define AudioFormat to return
|
||||
AudioFormat format = currentAudioFormat;
|
||||
|
||||
// Not all Codecs and containers can be supported
|
||||
if (null == format.getCodec()) { continue; }
|
||||
if (null == format.getContainer()) { continue; }
|
||||
|
||||
// Prefer WAVE container
|
||||
if (!format.getContainer().equals("WAVE")) { continue; }
|
||||
|
||||
// If required set BigEndian, BitDepth, BitRate, and Frequency to default values
|
||||
if (null == format.isBigEndian()) {
|
||||
format = new AudioFormat(format.getContainer(), format.getCodec(), new Boolean(true), format.getBitDepth(), format.getBitRate(), format.getFrequency());
|
||||
}
|
||||
if (null == format.getBitDepth() || null == format.getBitRate() || null == format.getFrequency()) {
|
||||
// Define default values
|
||||
int defaultBitDepth = 16;
|
||||
int defaultBitRate = 262144;
|
||||
long defaultFrequency = 16384;
|
||||
|
||||
// Obtain current values
|
||||
Integer bitRate = format.getBitRate();
|
||||
Long frequency = format.getFrequency();
|
||||
Integer bitDepth = format.getBitDepth();
|
||||
|
||||
// These values must be interdependent (bitRate = bitDepth * frequency)
|
||||
if (null == bitRate) {
|
||||
if (null == bitDepth) { bitDepth = new Integer(defaultBitDepth); }
|
||||
if (null == frequency) { frequency = new Long(defaultFrequency); }
|
||||
bitRate = new Integer(bitDepth.intValue() * frequency.intValue());
|
||||
} else if (null == bitDepth) {
|
||||
if (null == frequency) { frequency = new Long(defaultFrequency); }
|
||||
if (null == bitRate) { bitRate = new Integer(defaultBitRate); }
|
||||
bitDepth = new Integer(bitRate.intValue() / frequency.intValue());
|
||||
} else if (null == frequency) {
|
||||
if (null == bitRate) { bitRate = new Integer(defaultBitRate); }
|
||||
if (null == bitDepth) { bitDepth = new Integer(defaultBitDepth); }
|
||||
frequency = new Long(bitRate.longValue() / bitDepth.longValue());
|
||||
}
|
||||
|
||||
format = new AudioFormat(format.getContainer(), format.getCodec(), format.isBigEndian(), bitDepth, bitRate, frequency);
|
||||
}
|
||||
|
||||
// Retrun prefered AudioFormat
|
||||
return format;
|
||||
}
|
||||
|
||||
// Indicates the passed audioFormats is empty or specified no codecs or containers
|
||||
assert (false);
|
||||
|
||||
// Return null indicating failue
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void setItemRegistry(ItemRegistry itemRegistry) {
|
||||
this.itemRegistry = itemRegistry;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче