Added voice control
Former-commit-id: 6f69079bf44f0d8f9ae40de6b0f1638d103464c2
This commit is contained in:
parent
35c92407a3
commit
53da641909
863 changed files with 192681 additions and 0 deletions
367
external/marytts-5.1.2/doc/examples/client/MaryClient.py
vendored
Normal file
367
external/marytts-5.1.2/doc/examples/client/MaryClient.py
vendored
Normal file
|
|
@ -0,0 +1,367 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
import socket, sys, types, getopt
|
||||
|
||||
|
||||
languageNames = {'de':'German',
|
||||
'en':'English',
|
||||
'en_US':'US English',
|
||||
'tib':'Tibetan'}
|
||||
|
||||
class MaryClient:
|
||||
specificationVersion = "0.1"
|
||||
|
||||
"""Python implementation of a MARY TTS client"""
|
||||
def __init__( self, host="cling.dfki.uni-sb.de", port=59125, profile=False, quiet=False ):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.profile = profile
|
||||
self.quiet = quiet
|
||||
self.allVoices = None # array of Voice objects
|
||||
self.voicesByLocaleMap = {} # Map locale strings to arrays of Voice objects
|
||||
self.allDataTypes = None # array of DataType objects
|
||||
self.inputDataTypes = None # array of DataType objects
|
||||
self.outputDataTypes = None # array of DataType objects
|
||||
self.serverExampleTexts = {}
|
||||
self.voiceExampleTexts = {}
|
||||
self.serverVersionInfo = u''
|
||||
|
||||
if not self.quiet:
|
||||
sys.stderr.write( "MARY TTS Python Client %s\n" % ( self.specificationVersion ) )
|
||||
try:
|
||||
info = self.getServerVersionInfo()
|
||||
except:
|
||||
sys.stderr.write( "Problem connecting to mary server at %s:%i\n" % ( self.host, self.port ) )
|
||||
raise
|
||||
sys.stderr.write( "Connected to %s:%i, " % ( self.host, self.port ) )
|
||||
sys.stderr.write( info )
|
||||
sys.stderr.write( '\n' )
|
||||
|
||||
def __getServerInfo( self, request="", marySocket=None ):
|
||||
"""Get answer to request from mary server. Returns a list of unicode strings,
|
||||
each representing a line without the line break.
|
||||
"""
|
||||
closeSocket = False
|
||||
if marySocket is None:
|
||||
closeSocket = True
|
||||
marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
marySocket.connect( ( self.host, self.port ) )
|
||||
assert isinstance(marySocket, socket.SocketType)
|
||||
maryFile = marySocket.makefile( 'rwb', 1 ) # read-write, line-buffered
|
||||
maryFile.write( unicode( request+"\n" ).encode( 'utf-8' ) )
|
||||
result = []
|
||||
while True:
|
||||
got = unicode( maryFile.readline().strip(), 'utf-8' )
|
||||
# read until end of file or an empty line is read:
|
||||
if not got: break
|
||||
result.append(got)
|
||||
if closeSocket:
|
||||
marySocket.close()
|
||||
return result
|
||||
|
||||
def getServerVersionInfo( self ):
|
||||
"Get version info from server. Returns a unicode string"
|
||||
if self.serverVersionInfo == u'':
|
||||
# need to get it from server
|
||||
self.serverVersionInfo = u'\n'.join(self.__getServerInfo("MARY VERSION"))
|
||||
return self.serverVersionInfo
|
||||
|
||||
def getAllDataTypes(self, locale=None):
|
||||
"""Obtain a list of all data types known to the server. If the information is not
|
||||
yet available, the server is queried. This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities.
|
||||
Returns an array of DataType objects
|
||||
"""
|
||||
if self.allDataTypes is None:
|
||||
self.__fillDataTypes()
|
||||
assert self.allDataTypes is not None and len( self.allDataTypes ) > 0
|
||||
if locale is None:
|
||||
return self.allDataTypes
|
||||
else:
|
||||
assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
|
||||
return [d for d in self.allDataTypes if d.locale is None or d.locale == locale]
|
||||
|
||||
def getInputDataTypes(self,locale=None):
|
||||
"""Obtain a list of input data types known to the server. If the information is not
|
||||
yet available, the server is queried. This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities.
|
||||
Returns an arry of DataType objects
|
||||
"""
|
||||
if self.inputDataTypes is None:
|
||||
self.__fillDataTypes()
|
||||
assert self.inputDataTypes is not None and len( self.inputDataTypes ) > 0
|
||||
if locale is None:
|
||||
return self.inputDataTypes
|
||||
else:
|
||||
assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
|
||||
return [d for d in self.inputDataTypes if d.locale is None or d.locale == locale]
|
||||
|
||||
def getOutputDataTypes(self, locale=None):
|
||||
"""Obtain a list of output data types known to the server. If the information is not
|
||||
yet available, the server is queried. This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities.
|
||||
Returns an arry of DataType objects
|
||||
"""
|
||||
if self.outputDataTypes is None:
|
||||
self.__fillDataTypes()
|
||||
assert self.outputDataTypes is not None and len( self.outputDataTypes ) > 0
|
||||
if locale is None:
|
||||
return self.outputDataTypes
|
||||
else:
|
||||
assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
|
||||
return [d for d in self.outputDataTypes if d.locale is None or d.locale == locale]
|
||||
|
||||
|
||||
def __fillDataTypes( self ):
|
||||
self.allDataTypes = []
|
||||
self.inputDataTypes = []
|
||||
self.outputDataTypes = []
|
||||
marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
marySocket.connect( ( self.host, self.port ) )
|
||||
# Expect a variable number of lines of the kind
|
||||
# RAWMARYXML INPUT OUTPUT
|
||||
# TEXT_DE LOCALE=de INPUT
|
||||
# AUDIO OUTPUT
|
||||
typeStrings = self.__getServerInfo( "MARY LIST DATATYPES", marySocket )
|
||||
if not typeStrings or len(typeStrings) == 0:
|
||||
raise IOError( "Could not get list of data types from Mary server" )
|
||||
marySocket.close()
|
||||
for typeString in typeStrings:
|
||||
parts = typeString.split()
|
||||
if len( parts ) == 0:
|
||||
continue
|
||||
name = parts[0]
|
||||
isInputType = False
|
||||
isOutputType = False
|
||||
locale = None
|
||||
for part in parts[1:]:
|
||||
if part[:7] == "LOCALE=":
|
||||
locale = part[7:]
|
||||
elif part == "INPUT":
|
||||
isInputType = True
|
||||
elif part == "OUTPUT":
|
||||
isOutputType = True
|
||||
dt = DataType( name, locale, isInputType, isOutputType )
|
||||
self.allDataTypes.append( dt )
|
||||
if dt.isInputType:
|
||||
self.inputDataTypes.append( dt )
|
||||
if dt.isOutputType:
|
||||
self.outputDataTypes.append( dt )
|
||||
|
||||
def getVoices( self, locale=None ):
|
||||
"""Obtain a list of voices known to the server. If the information is not
|
||||
yet available, the server is queried. This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities.
|
||||
Returns an array of Voice objects
|
||||
"""
|
||||
if self.allVoices is None:
|
||||
self.__fillVoices()
|
||||
assert self.allVoices is not None and len( self.allVoices ) > 0
|
||||
if locale is None:
|
||||
return self.allVoices
|
||||
else:
|
||||
assert isinstance(locale, types.UnicodeType), "Unexpected type for locale: '%s'" % (type(locale))
|
||||
if self.voicesByLocaleMap.has_key(locale):
|
||||
return self.voicesByLocaleMap[locale]
|
||||
else:
|
||||
raise Exception("No voices for locale '%s'" % (locale))
|
||||
|
||||
def __fillVoices( self ):
|
||||
self.allVoices = []
|
||||
self.voicesByLocaleMap = {}
|
||||
marySocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
marySocket.connect( ( self.host, self.port ) )
|
||||
# Expect a variable number of lines of the kind
|
||||
# de7 de female
|
||||
# us2 en male
|
||||
# dfki-stadium-emo de male limited
|
||||
voiceStrings = self.__getServerInfo( "MARY LIST VOICES", marySocket )
|
||||
if not voiceStrings or len(voiceStrings) == 0:
|
||||
raise IOError( "Could not get list of voices from Mary server" )
|
||||
marySocket.close()
|
||||
for voiceString in voiceStrings:
|
||||
parts = voiceString.split()
|
||||
if len( parts ) < 3:
|
||||
continue
|
||||
name = parts[0]
|
||||
locale = parts[1]
|
||||
gender = parts[2]
|
||||
domain = None
|
||||
if len( parts ) > 3:
|
||||
domain = parts[3]
|
||||
voice = Voice( name, locale, gender, domain )
|
||||
self.allVoices.append( voice )
|
||||
localeVoices = None
|
||||
if self.voicesByLocaleMap.has_key( locale ):
|
||||
localeVoices = self.voicesByLocaleMap[locale]
|
||||
else:
|
||||
localeVoices = []
|
||||
self.voicesByLocaleMap[locale] = localeVoices
|
||||
localeVoices.append( voice )
|
||||
|
||||
def getGeneralDomainVoices( self, locale=None ):
|
||||
"""Obtain a list of general domain voices known to the server. If the information is not
|
||||
yet available, the server is queried. This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities.
|
||||
Returns an array of Voice objects
|
||||
"""
|
||||
return [v for v in self.getVoices( locale ) if not v.isLimitedDomain]
|
||||
|
||||
def getLimitedDomainVoices( self, locale=None ):
|
||||
"""Obtain a list of limited domain voices known to the server. If the information is not
|
||||
yet available, the server is queried. This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities.
|
||||
Returns an array of Voice objects
|
||||
"""
|
||||
return [v for v in self.getVoices( locale ) if v.isLimitedDomain]
|
||||
|
||||
def getAvailableLanguages(self):
|
||||
""" Check available voices and return a list of tuples (abbrev, name)
|
||||
representing the available languages -- e.g. [('en', 'English'),('de', 'German')].
|
||||
"""
|
||||
if self.allVoices is None:
|
||||
self.__fillVoices()
|
||||
assert self.allVoices is not None and len( self.allVoices ) > 0
|
||||
languages = []
|
||||
for l in self.voicesByLocaleMap.keys():
|
||||
if languageNames.has_key(l):
|
||||
languages.append((l,languageNames[l]))
|
||||
else:
|
||||
languages.append((l, l))
|
||||
return languages
|
||||
|
||||
def getServerExampleText( self, dataType ):
|
||||
"""Request an example text for a given data type from the server.
|
||||
dataType the string representation of the data type,
|
||||
e.g. "RAWMARYXML". This is optional information
|
||||
which is not required for the normal operation of the client, but
|
||||
may help to avoid incompatibilities."""
|
||||
if not self.serverExampleTexts.has_key( dataType ):
|
||||
exampleTexts = self.__getServerInfo( "MARY EXAMPLETEXT %s" % ( dataType ) )
|
||||
if not exampleTexts or len(exampleTexts) == 0:
|
||||
raise IOError( "Could not get example text for type '%s' from Mary server" % (dataType))
|
||||
exampleText = u'\n'.join(exampleTexts)
|
||||
self.serverExampleTexts[dataType] = exampleText
|
||||
return self.serverExampleTexts[dataType]
|
||||
|
||||
def process( self, input, inputType, outputType, audioType=None, defaultVoiceName=None, output=sys.stdout ):
|
||||
assert type( input ) in types.StringTypes
|
||||
assert type( inputType ) in types.StringTypes
|
||||
assert type( outputType ) in types.StringTypes
|
||||
assert audioType is None or type( audioType ) in types.StringTypes
|
||||
assert defaultVoiceName is None or type( defaultVoiceName ) in types.StringTypes
|
||||
assert callable( getattr( output, 'write' ) )
|
||||
if type( input ) != types.UnicodeType:
|
||||
input = unicode( input, 'utf-8' )
|
||||
maryInfoSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
maryInfoSocket.connect( ( self.host, self.port ) )
|
||||
assert type( maryInfoSocket ) is socket.SocketType
|
||||
maryInfo = maryInfoSocket.makefile( 'rwb', 1 ) # read-write, line-buffered
|
||||
maryInfo.write( unicode( "MARY IN=%s OUT=%s" % ( inputType, outputType ), 'utf-8' ) )
|
||||
if audioType:
|
||||
maryInfo.write( unicode( " AUDIO=%s" % ( audioType ), 'utf-8' ) )
|
||||
if defaultVoiceName:
|
||||
maryInfo.write( unicode( " VOICE=%s" % ( defaultVoiceName ), 'utf-8' ) )
|
||||
maryInfo.write( "\r\n" )
|
||||
# Receive a request ID:
|
||||
id = maryInfo.readline()
|
||||
maryDataSocket = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
|
||||
maryDataSocket.connect( ( self.host, self.port ) )
|
||||
assert type( maryDataSocket ) is socket.SocketType
|
||||
maryDataSocket.sendall( id ) # includes newline
|
||||
maryDataSocket.sendall( input.encode( 'utf-8' ) )
|
||||
maryDataSocket.shutdown( 1 ) # shutdown writing
|
||||
# Set mary info socket to non-blocking, so we only read somthing
|
||||
# if there is something to read:
|
||||
maryInfoSocket.setblocking( 0 )
|
||||
while True:
|
||||
try:
|
||||
err = maryInfoSocket.recv( 8192 )
|
||||
if err: sys.stderr.write( err )
|
||||
except:
|
||||
pass
|
||||
got = maryDataSocket.recv( 8192 )
|
||||
if not got: break
|
||||
output.write( got )
|
||||
maryInfoSocket.setblocking( 1 )
|
||||
while True:
|
||||
err = maryInfoSocket.recv( 8192 )
|
||||
if not err: break
|
||||
sys.stderr.write( err )
|
||||
|
||||
|
||||
|
||||
################ data representation classes ##################
|
||||
|
||||
class DataType:
|
||||
def __init__( self, name, locale=None, isInputType=False, isOutputType=False ):
|
||||
self.name = name
|
||||
self.locale = locale
|
||||
self.isInputType = isInputType
|
||||
self.isOutputType = isOutputType
|
||||
|
||||
def isTextType( self ):
|
||||
return self.name != "AUDIO"
|
||||
|
||||
class Voice:
|
||||
|
||||
def __init__( self, name, locale, gender, domain="general" ):
|
||||
self.name = name
|
||||
self.locale = locale
|
||||
self.gender = gender
|
||||
self.domain = domain
|
||||
if not domain or domain == "general":
|
||||
self.isLimitedDomain = False
|
||||
else:
|
||||
self.isLimitedDomain = True
|
||||
|
||||
def __str__(self):
|
||||
if languageNames.has_key(self.locale):
|
||||
langName = languageNames[self.locale]
|
||||
else:
|
||||
langName = self.locale
|
||||
if self.isLimitedDomain:
|
||||
return "%s (%s, %s %s)" % (self.name, self.domain, langName, self.gender)
|
||||
else:
|
||||
return "%s (%s %s)" % (self.name, langName, self.gender)
|
||||
|
||||
##################### Main #########################
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
serverHost = "cling.dfki.uni-sb.de"
|
||||
serverPort = 59125
|
||||
inputType = "TEXT"
|
||||
outputType = "AUDIO"
|
||||
audioType = "WAVE"
|
||||
defaultVoice = None
|
||||
inputEncoding = 'utf-8'
|
||||
( options, rest ) = getopt.getopt( sys.argv[1:], '', \
|
||||
['server.host=', 'server.port=', 'input.type=', 'output.type=', \
|
||||
'audio.type=', 'voice.default=', 'input.encoding='] )
|
||||
for ( option, value ) in options:
|
||||
if option == '--server.host': serverHost = value
|
||||
elif option == '--server.port': serverPort = int( value )
|
||||
elif option == '--input.type': inputType = value
|
||||
elif option == '--output.type': outputType = value
|
||||
elif option == '--audio.type': audioType = value
|
||||
elif option == '--voice.default': defaultVoice = value
|
||||
elif option == '--input.encoding': inputEncoding = value
|
||||
if len( rest )>0: # have input file
|
||||
inputFile = file( rest[0] )
|
||||
else:
|
||||
inputFile = sys.stdin
|
||||
input = unicode( ''.join( inputFile.readlines() ), inputEncoding )
|
||||
if len( rest )>1: # also have output file
|
||||
outputFile = file( rest[1] )
|
||||
else:
|
||||
outputFile = sys.stdout
|
||||
|
||||
maryClient = MaryClient( serverHost, serverPort )
|
||||
maryClient.process( input, inputType, outputType, audioType, defaultVoice, outputFile )
|
||||
102
external/marytts-5.1.2/doc/examples/client/MaryClientUser.java
vendored
Normal file
102
external/marytts-5.1.2/doc/examples/client/MaryClientUser.java
vendored
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/**
|
||||
* Copyright 2000-2006 DFKI GmbH.
|
||||
* All Rights Reserved. Use is subject to license terms.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to use and distribute
|
||||
* this software and its documentation without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of this work, and to
|
||||
* permit persons to whom this work is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* 2. Any modifications must be clearly marked as such.
|
||||
* 3. Original authors' names are not deleted.
|
||||
* 4. The authors' names are not used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import javax.sound.sampled.LineEvent;
|
||||
import javax.sound.sampled.LineListener;
|
||||
import javax.sound.sampled.UnsupportedAudioFileException;
|
||||
|
||||
import marytts.util.data.audio.AudioPlayer;
|
||||
import marytts.client.MaryClient;
|
||||
import marytts.util.http.Address;
|
||||
|
||||
/**
|
||||
* A demo class illustrating how to use the MaryClient class.
|
||||
* This will connect to a MARY server, version 4.x.
|
||||
* It requires maryclient.jar from MARY 4.0.
|
||||
* This works transparently with MARY servers in both http and socket server mode.
|
||||
*
|
||||
* Compile this as follows:
|
||||
* <code>javac -cp maryclient.jar MaryClientUser.java</code>
|
||||
*
|
||||
* And run as:
|
||||
* <code>java -cp .:maryclient.jar MaryClientUser</code>
|
||||
*
|
||||
* @author marc
|
||||
*
|
||||
*/
|
||||
|
||||
public class MaryClientUser {
|
||||
|
||||
public static void main(String[] args)
|
||||
throws IOException, UnknownHostException, UnsupportedAudioFileException,
|
||||
InterruptedException
|
||||
{
|
||||
String serverHost = System.getProperty("server.host", "cling.dfki.uni-sb.de");
|
||||
int serverPort = Integer.getInteger("server.port", 59125).intValue();
|
||||
MaryClient mary = MaryClient.getMaryClient(new Address(serverHost, serverPort));
|
||||
String text = "Willkommen in der Welt der Sprachsynthese!";
|
||||
// If the given locale is not supported by the server, it returns
|
||||
// an ambigous exception: "Problem processing the data."
|
||||
String locale = "de"; // or US English (en-US), Telugu (te), Turkish (tr), ...
|
||||
String inputType = "TEXT";
|
||||
String outputType = "AUDIO";
|
||||
String audioType = "WAVE";
|
||||
String defaultVoiceName = null;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
mary.process(text, inputType, outputType, locale, audioType, defaultVoiceName, baos);
|
||||
// The byte array constitutes a full wave file, including the headers.
|
||||
// And now, play the audio data:
|
||||
AudioInputStream ais = AudioSystem.getAudioInputStream(
|
||||
new ByteArrayInputStream(baos.toByteArray()));
|
||||
LineListener lineListener = new LineListener() {
|
||||
public void update(LineEvent event) {
|
||||
if (event.getType() == LineEvent.Type.START) {
|
||||
System.err.println("Audio started playing.");
|
||||
} else if (event.getType() == LineEvent.Type.STOP) {
|
||||
System.err.println("Audio stopped playing.");
|
||||
} else if (event.getType() == LineEvent.Type.OPEN) {
|
||||
System.err.println("Audio line opened.");
|
||||
} else if (event.getType() == LineEvent.Type.CLOSE) {
|
||||
System.err.println("Audio line closed.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AudioPlayer ap = new AudioPlayer(ais, lineListener);
|
||||
ap.start();
|
||||
}
|
||||
}
|
||||
45
external/marytts-5.1.2/doc/examples/client/c++/Makefile
vendored
Normal file
45
external/marytts-5.1.2/doc/examples/client/c++/Makefile
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
##########################################################################
|
||||
# Copyright (C) 2000-2006 DFKI GmbH.
|
||||
# All rights reserved. Use is subject to license terms.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to use and distribute
|
||||
# this software and its documentation without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of this work, and to
|
||||
# permit persons to whom this work is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# 1. The code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
# 2. Any modifications must be clearly marked as such.
|
||||
# 3. Original authors' names are not deleted.
|
||||
# 4. The authors' names are not used to endorse or promote products
|
||||
# derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
# THIS SOFTWARE.
|
||||
##########################################################################
|
||||
|
||||
CC=g++
|
||||
CFLAGS=-Wall -w -O3 -g
|
||||
ICUDIR=/usr/local/icu
|
||||
ICULIBS=-Wl,-R,$(ICUDIR)/lib -L$(ICUDIR)/lib -licuuc -licui18n -ldl
|
||||
|
||||
all: MaryDemo
|
||||
|
||||
MaryDemo: MaryClient.o MaryDemo.o
|
||||
$(CC) $(CFLAGS) *.o -o MaryDemo $(LIBS)
|
||||
|
||||
%.o: %.cc
|
||||
$(CC) $(CFLAGS) $(RFLAGS) -o $@ -c $<
|
||||
|
||||
clean:
|
||||
rm -rf *.o ./MaryDemo
|
||||
|
||||
277
external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc
vendored
Normal file
277
external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc
vendored
Normal file
|
|
@ -0,0 +1,277 @@
|
|||
/**
|
||||
* Copyright 2000-2006 DFKI GmbH.
|
||||
* All Rights Reserved. Use is subject to license terms.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to use and distribute
|
||||
* this software and its documentation without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of this work, and to
|
||||
* permit persons to whom this work is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* 2. Any modifications must be clearly marked as such.
|
||||
* 3. Original authors' names are not deleted.
|
||||
* 4. The authors' names are not used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
#include <netdb.h>
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "MaryClient.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* A C++ implementation of a simple client to the MARY TTS system.
|
||||
* result: an empty string serving as the container for the output.
|
||||
* It will return text or audio data; text data will be encoded as UTF-8.
|
||||
* inputText: the UTF-8 encoded text (or XML document) to send as a request
|
||||
* maryInFormat: the input type of the data in inputText, e.g. TEXT
|
||||
* maryOutFormat: the output type to produce, e.g. MBROLA, AUDIO
|
||||
* locale: the language of the input, e.g. EN-US, DE
|
||||
* audioType: for AUDIO output, the type of audio data to produce,
|
||||
* e.g. WAVE or MP3.
|
||||
* voice: the voice to be used, e.g. cmu-slt-hsmm, bits3.
|
||||
* effects: the list of effects to be generated.
|
||||
* return value: 0 on success, negative on failure.
|
||||
*/
|
||||
int
|
||||
MaryClient::maryQuery( int server_port,
|
||||
string server_host,
|
||||
string& result,
|
||||
string inputText,
|
||||
string maryInFormat,
|
||||
string maryOutFormat,
|
||||
string locale,
|
||||
string audioType,
|
||||
string voice,
|
||||
string effects ) {
|
||||
|
||||
// prepare the request
|
||||
string query = "MARY";
|
||||
query += " IN=" + maryInFormat;
|
||||
query += " OUT=" + maryOutFormat;
|
||||
query += " LOCALE=" + locale; // remove this line, if using an older version than MARY 4.0
|
||||
query += " AUDIO=" + audioType;
|
||||
query += " VOICE=" + voice;
|
||||
if (effects != "") {
|
||||
query += " EFFECTS=" + effects;
|
||||
}
|
||||
query += "\012\015";
|
||||
|
||||
//cout << "Constructed query: " << query << endl;
|
||||
|
||||
// declare connection stuff
|
||||
struct sockaddr_in maryServer;
|
||||
struct sockaddr_in maryClient;
|
||||
struct hostent* hostInfo;
|
||||
|
||||
// declare variables
|
||||
int maryInfoSocket;
|
||||
int maryDataSocket;
|
||||
|
||||
// set configuration parameters
|
||||
|
||||
// get host information
|
||||
hostInfo = gethostbyname (server_host.c_str());
|
||||
|
||||
if (hostInfo == NULL)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// create a tcp connection to the mary server
|
||||
maryInfoSocket = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
// verify that the socket could be opened successfully
|
||||
if (maryInfoSocket == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
// autoflush stdout, bind and connect
|
||||
{
|
||||
maryClient.sin_family = AF_INET;
|
||||
maryClient.sin_port = htons (0);
|
||||
maryClient.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
int status = bind (maryInfoSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
maryServer.sin_family = AF_INET;
|
||||
maryServer.sin_port = htons (server_port);
|
||||
memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
|
||||
|
||||
status = connect (maryInfoSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
// send request to the Mary server
|
||||
if (send (maryInfoSocket, query.c_str (), query.size (), 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// receive the request id
|
||||
char id [32] = "";
|
||||
|
||||
if (recv (maryInfoSocket, id, 32, 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
//cout << "Read id: " << id << endl;
|
||||
|
||||
// create a tcp connection to the mary server
|
||||
maryDataSocket = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
// verify that the socket could be opened successfully
|
||||
if (maryDataSocket == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
// autoflush stdout, bind and connect
|
||||
{
|
||||
maryClient.sin_family = AF_INET;
|
||||
maryClient.sin_port = htons (0);
|
||||
maryClient.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
int status = bind (maryDataSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
maryServer.sin_family = AF_INET;
|
||||
maryServer.sin_port = htons (server_port);
|
||||
memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
|
||||
|
||||
status = connect (maryDataSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// send the request id to the Mary server
|
||||
if (send (maryDataSocket, id, strlen (id), 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
//cout << "Sending request: " << inputText << endl;
|
||||
|
||||
// send the query to the Mary server
|
||||
if (send (maryDataSocket, inputText.c_str (), inputText.size (), 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (send (maryDataSocket, "\012\015", 2, 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// shutdown data socket
|
||||
shutdown (maryDataSocket, 1);
|
||||
|
||||
|
||||
//cout << "Reading result" << endl;
|
||||
|
||||
unsigned int total_bytes = 0;
|
||||
int recv_bytes = 0;
|
||||
char data [1024] = "";
|
||||
|
||||
result [0] = '\0';
|
||||
|
||||
// receive the request result
|
||||
do
|
||||
{
|
||||
data [0] = '\0';
|
||||
|
||||
recv_bytes = recv (maryDataSocket, data, 1024, 0);
|
||||
|
||||
if (recv_bytes == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else if (recv_bytes > 0)
|
||||
{
|
||||
//cout << "("<<recv_bytes<<")" << endl;
|
||||
total_bytes += recv_bytes;
|
||||
data [recv_bytes] = '\0';
|
||||
|
||||
if (maryOutFormat == "AUDIO")
|
||||
{
|
||||
for (unsigned int i=0; i<recv_bytes; i++)
|
||||
{
|
||||
result += data [i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result += data;
|
||||
}
|
||||
}
|
||||
} while (recv_bytes != 0);
|
||||
|
||||
if (result.size () != total_bytes)
|
||||
{
|
||||
cerr << "error: total bytes received != result bytes!" << endl;
|
||||
cerr << " total bytes received = " << total_bytes << endl;
|
||||
cerr << " result bytes = " << result.size () << endl;
|
||||
}
|
||||
|
||||
// receive the request error
|
||||
do
|
||||
{
|
||||
data [0] = '\0';
|
||||
|
||||
recv_bytes = recv (maryInfoSocket, data, 1024, 0);
|
||||
|
||||
if (recv_bytes == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else if (recv_bytes > 0)
|
||||
{
|
||||
cerr << endl << "Mary error code: " << data << endl;
|
||||
return -3;
|
||||
}
|
||||
} while (recv_bytes != 0);
|
||||
|
||||
// close all open sockets
|
||||
close (maryInfoSocket);
|
||||
close (maryDataSocket);
|
||||
|
||||
return 0;
|
||||
}
|
||||
290
external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc.win
vendored
Normal file
290
external/marytts-5.1.2/doc/examples/client/c++/MaryClient.cc.win
vendored
Normal file
|
|
@ -0,0 +1,290 @@
|
|||
/**
|
||||
* Copyright 2000-2006 DFKI GmbH.
|
||||
* All Rights Reserved. Use is subject to license terms.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to use and distribute
|
||||
* this software and its documentation without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of this work, and to
|
||||
* permit persons to whom this work is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* 2. Any modifications must be clearly marked as such.
|
||||
* 3. Original authors' names are not deleted.
|
||||
* 4. The authors' names are not used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
// use compiler option -L/<path to>/libwsock32.a
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <string.h>
|
||||
|
||||
#include "MaryClient.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* A C++ implementation of a simple client to the MARY TTS system.
|
||||
* result: an empty string serving as the container for the output.
|
||||
* It will return text or audio data; text data will be encoded as UTF-8.
|
||||
* inputText: the UTF-8 encoded text (or XML document) to send as a request
|
||||
* maryInFormat: the input type of the data in inputText, e.g. TEXT
|
||||
* maryOutFormat: the output type to produce, e.g. MBROLA, AUDIO
|
||||
* locale: the language of the input, e.g. EN-US, DE
|
||||
* audioType: for AUDIO output, the type of audio data to produce,
|
||||
* e.g. WAVE or MP3.
|
||||
* voice: the voice to be used, e.g. cmu-slt-hsmm, bits3.
|
||||
* effects: the list of effects to be generated.
|
||||
* return value: 0 on success, negative on failure.
|
||||
*/
|
||||
int
|
||||
MaryClient::maryQuery( int server_port,
|
||||
string server_host,
|
||||
string& result,
|
||||
string inputText,
|
||||
string maryInFormat,
|
||||
string maryOutFormat,
|
||||
string locale,
|
||||
string audioType,
|
||||
string voice,
|
||||
string effects ) {
|
||||
|
||||
// prepare the request
|
||||
string query = "MARY";
|
||||
query += " IN=" + maryInFormat;
|
||||
query += " OUT=" + maryOutFormat;
|
||||
query += " LOCALE=" + locale; // remove this line, if using an older version than MARY 4.0
|
||||
query += " AUDIO=" + audioType;
|
||||
query += " VOICE=" + voice;
|
||||
if (effects != "") {
|
||||
query += " EFFECTS=" + effects;
|
||||
}
|
||||
query += "\012\015";
|
||||
|
||||
//cout << "Constructed query: " << query << endl;
|
||||
|
||||
// declare connection stuff
|
||||
struct sockaddr_in maryServer;
|
||||
struct sockaddr_in maryClient;
|
||||
struct hostent* hostInfo;
|
||||
|
||||
// declare variables
|
||||
int maryInfoSocket;
|
||||
int maryDataSocket;
|
||||
|
||||
// set configuration parameters
|
||||
|
||||
// get host information
|
||||
hostInfo = gethostbyname (server_host.c_str());
|
||||
|
||||
if (hostInfo == NULL)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// create a tcp connection to the mary server
|
||||
maryInfoSocket = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
// verify that the socket could be opened successfully
|
||||
if (maryInfoSocket == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
// autoflush stdout, bind and connect
|
||||
{
|
||||
maryClient.sin_family = AF_INET;
|
||||
maryClient.sin_port = htons (0);
|
||||
maryClient.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
int status = bind (maryInfoSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
maryServer.sin_family = AF_INET;
|
||||
maryServer.sin_port = htons (server_port);
|
||||
memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
|
||||
|
||||
status = connect (maryInfoSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
// send request to the Mary server
|
||||
if (send (maryInfoSocket, query.c_str (), query.size (), 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// receive the request id
|
||||
char id [32] = "";
|
||||
|
||||
if (recv (maryInfoSocket, id, 32, 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
//cout << "Read id: " << id << endl;
|
||||
|
||||
// create a tcp connection to the mary server
|
||||
maryDataSocket = socket (AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
// verify that the socket could be opened successfully
|
||||
if (maryDataSocket == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else
|
||||
// autoflush stdout, bind and connect
|
||||
{
|
||||
maryClient.sin_family = AF_INET;
|
||||
maryClient.sin_port = htons (0);
|
||||
maryClient.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
int status = bind (maryDataSocket, (struct sockaddr*) &maryClient, sizeof (maryClient));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
maryServer.sin_family = AF_INET;
|
||||
maryServer.sin_port = htons (server_port);
|
||||
memcpy ((char*) &maryServer.sin_addr.s_addr, hostInfo->h_addr_list [0], hostInfo->h_length);
|
||||
|
||||
status = connect (maryDataSocket, (struct sockaddr*) &maryServer, sizeof (maryServer));
|
||||
|
||||
if (status != 0)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// send the request id to the Mary server
|
||||
if (send (maryDataSocket, id, strlen (id), 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
//cout << "Sending request: " << inputText << endl;
|
||||
|
||||
// send the query to the Mary server
|
||||
if (send (maryDataSocket, inputText.c_str (), inputText.size (), 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
if (send (maryDataSocket, "\012\015", 2, 0) == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
// shutdown data socket
|
||||
shutdown (maryDataSocket, 1);
|
||||
|
||||
|
||||
//cout << "Reading result" << endl;
|
||||
|
||||
unsigned int total_bytes = 0;
|
||||
int recv_bytes = 0;
|
||||
char data [1024] = "";
|
||||
|
||||
result [0] = '\0';
|
||||
|
||||
// receive the request result
|
||||
do
|
||||
{
|
||||
data [0] = '\0';
|
||||
|
||||
recv_bytes = recv (maryDataSocket, data, 1024, 0);
|
||||
|
||||
if (recv_bytes == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else if (recv_bytes > 0)
|
||||
{
|
||||
//cout << "("<<recv_bytes<<")" << endl;
|
||||
total_bytes += recv_bytes;
|
||||
data [recv_bytes] = '\0';
|
||||
|
||||
if (maryOutFormat == "AUDIO")
|
||||
{
|
||||
for (unsigned int i=0; i<recv_bytes; i++)
|
||||
{
|
||||
result += data [i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result += data;
|
||||
}
|
||||
}
|
||||
} while (recv_bytes != 0);
|
||||
|
||||
if (result.size () != total_bytes)
|
||||
{
|
||||
cerr << "error: total bytes received != result bytes!" << endl;
|
||||
cerr << " total bytes received = " << total_bytes << endl;
|
||||
cerr << " result bytes = " << result.size () << endl;
|
||||
}
|
||||
|
||||
// receive the request error
|
||||
do
|
||||
{
|
||||
data [0] = '\0';
|
||||
|
||||
recv_bytes = recv (maryInfoSocket, data, 1024, 0);
|
||||
|
||||
if (recv_bytes == -1)
|
||||
{
|
||||
return -2;
|
||||
}
|
||||
else if (recv_bytes > 0)
|
||||
{
|
||||
cerr << endl << "Mary error code: " << data << endl;
|
||||
return -3;
|
||||
}
|
||||
} while (recv_bytes != 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
// close all open sockets Windows
|
||||
closesocket (maryInfoSocket);
|
||||
closesocket (maryDataSocket);
|
||||
#else
|
||||
// close all open sockets UNIX
|
||||
close (maryInfoSocket);
|
||||
close (maryDataSocket);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
external/marytts-5.1.2/doc/examples/client/c++/MaryClient.h
vendored
Normal file
49
external/marytts-5.1.2/doc/examples/client/c++/MaryClient.h
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/**
|
||||
* Copyright 2000-2006 DFKI GmbH.
|
||||
* All Rights Reserved. Use is subject to license terms.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to use and distribute
|
||||
* this software and its documentation without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of this work, and to
|
||||
* permit persons to whom this work is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* 2. Any modifications must be clearly marked as such.
|
||||
* 3. Original authors' names are not deleted.
|
||||
* 4. The authors' names are not used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef __MARYCLIENT_H_
|
||||
#define __MARYCLIENT_H_
|
||||
|
||||
class MaryClient {
|
||||
|
||||
public:
|
||||
// send query to the MaryServer
|
||||
int maryQuery( int server_port,
|
||||
std::string server_host,
|
||||
std::string& result,
|
||||
std::string inputText,
|
||||
std::string maryInFormat,
|
||||
std::string maryOutFormat,
|
||||
std::string locale,
|
||||
std::string audioType,
|
||||
std::string voice,
|
||||
std::string effects = "" );
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
87
external/marytts-5.1.2/doc/examples/client/c++/MaryDemo.cc
vendored
Normal file
87
external/marytts-5.1.2/doc/examples/client/c++/MaryDemo.cc
vendored
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Copyright 2000-2006 DFKI GmbH.
|
||||
* All Rights Reserved. Use is subject to license terms.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to use and distribute
|
||||
* this software and its documentation without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of this work, and to
|
||||
* permit persons to whom this work is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* 2. Any modifications must be clearly marked as such.
|
||||
* 3. Original authors' names are not deleted.
|
||||
* 4. The authors' names are not used to endorse or promote products
|
||||
* derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
* REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
* THIS SOFTWARE.
|
||||
*/
|
||||
// This version, adapted to MARY 4.0, provided by Sebastian Ptock.
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "MaryClient.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Demonstration code for using the MaryClient.
|
||||
+ Call this as:
|
||||
* ./MaryDemo
|
||||
* or
|
||||
* ./MaryDemo > output.wav
|
||||
*/
|
||||
int main() {
|
||||
int server_port = 59125;
|
||||
string server_host = "localhost";
|
||||
string inputText = "Welcome to the world of speech synthesis!";
|
||||
string maryInFormat = "TEXT";
|
||||
string maryOutFormat = "AUDIO";
|
||||
//string maryOutFormat = "REALISED_DURATIONS";
|
||||
string locale = "en-US";
|
||||
string audioType = "WAV_FILE";
|
||||
string voice = "cmu-slt-hsmm";
|
||||
string effects;
|
||||
// effects += "Volume(amount:5.0;)+";
|
||||
// effects += "TractScaler(amount:1.5;)+";
|
||||
// effects += "F0Scale(f0Scale:2.0;)+";
|
||||
// effects += "F0Add(f0Add:50.0;)+";
|
||||
// effects += "Rate(durScale:1.5;)+";
|
||||
// effects += "Robot(amount:100.0;)+";
|
||||
// effects += "Whisper(amount:100.0;)+";
|
||||
// effects += "Stadium(amount:100.0)+";
|
||||
// effects += "Chorus(delay1:466;amp1:0.54;delay2:600;amp2:-0.10;delay3:250;amp3:0.30)+";
|
||||
// effects += "FIRFilter(type:3;fc1:500.0;fc2:2000.0)+";
|
||||
// effects += "JetPilot";
|
||||
string result;
|
||||
|
||||
MaryClient maryClient;
|
||||
maryClient.maryQuery( server_port, server_host, result, inputText, maryInFormat, maryOutFormat, locale, audioType, voice, effects);
|
||||
|
||||
if (maryOutFormat == "AUDIO") {
|
||||
// write result into a file
|
||||
const char *filename = "output.wav";
|
||||
ofstream file( filename );
|
||||
file << result;
|
||||
|
||||
// play output
|
||||
//system("play output.wav");
|
||||
} else {
|
||||
cout << "RESULT: " << endl << result << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
4
external/marytts-5.1.2/doc/examples/client/c++/README.txt
vendored
Normal file
4
external/marytts-5.1.2/doc/examples/client/c++/README.txt
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
Start MARY as a socket server:
|
||||
|
||||
maryserver -Dserver=socket
|
||||
(or change entry 'server' in conf/marybase.config)
|
||||
185
external/marytts-5.1.2/doc/examples/client/maryclient-http.py
vendored
Normal file
185
external/marytts-5.1.2/doc/examples/client/maryclient-http.py
vendored
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
#!/usr/bin/env python
|
||||
import httplib, urllib
|
||||
|
||||
# A basic mary client in Python,
|
||||
# kindly donated to the MARY TTS project
|
||||
# by Hugh Sasse. Thanks Hugh!
|
||||
|
||||
# A very basic Python class for accessing
|
||||
# the MARY TTS system using the modern
|
||||
# HTTP server.
|
||||
# Warning, this is probably ghastly Python,
|
||||
# most of my time of late has been with
|
||||
# other languages, so I'm not up to date
|
||||
# with all the stylistic conventions of
|
||||
# modern Python.
|
||||
# This does seem to work OK though.
|
||||
|
||||
class maryclient:
|
||||
"""A basic handler for MARY-TTS HTTP clients
|
||||
|
||||
At present, there is no checking for
|
||||
allowed voices, locales, and so on.
|
||||
Most of the useful parameters can be
|
||||
accessed by get_ and set_ methods.
|
||||
Relying on winsound, this is Windows
|
||||
specific.
|
||||
"""
|
||||
def __init__(self):
|
||||
"""Set up useful defaults (for
|
||||
people in England, anyway)"""
|
||||
self.host = "127.0.0.1"
|
||||
self.port = 59125
|
||||
self.input_type = "TEXT"
|
||||
self.output_type = "AUDIO"
|
||||
self.audio = "WAVE_FILE"
|
||||
self.locale = "en_GB"
|
||||
self.voice = "dfki-prudence-hsmm"
|
||||
|
||||
def set_host(self, a_host):
|
||||
"""Set the host for the TTS server."""
|
||||
self.host = a_host
|
||||
|
||||
def get_host(self):
|
||||
"""Get the host for the TTS server."""
|
||||
self.host
|
||||
|
||||
def set_port(self, a_port):
|
||||
"""Set the port for the TTS server."""
|
||||
self.port = a_port
|
||||
|
||||
def get_port(self):
|
||||
"""Get the port for the TTS server."""
|
||||
self.port
|
||||
|
||||
def set_input_type(self, type):
|
||||
"""Set the type of input being
|
||||
supplied to the TTS server
|
||||
(such as 'TEXT')."""
|
||||
self.input_type = type
|
||||
|
||||
def get_input_type(self):
|
||||
"""Get the type of input being
|
||||
supplied to the TTS server
|
||||
(such as 'TEXT')."""
|
||||
self.input_type
|
||||
|
||||
def set_output_type(self, type):
|
||||
"""Set the type of input being
|
||||
supplied to the TTS server
|
||||
(such as 'AUDIO')."""
|
||||
self.output_type = type
|
||||
|
||||
def get_output_type(self):
|
||||
"""Get the type of input being
|
||||
supplied to the TTS server
|
||||
(such as "AUDIO")."""
|
||||
self.output_type
|
||||
|
||||
def set_locale(self, a_locale):
|
||||
"""Set the locale
|
||||
(such as "en_GB")."""
|
||||
self.locale = a_locale
|
||||
|
||||
def get_locale(self):
|
||||
"""Get the locale
|
||||
(such as "en_GB")."""
|
||||
self.locale
|
||||
|
||||
def set_audio(self, audio_type):
|
||||
"""Set the audio type for playback
|
||||
(such as "WAVE_FILE")."""
|
||||
self.audio = audio_type
|
||||
|
||||
def get_audio(self):
|
||||
"""Get the audio type for playback
|
||||
(such as "WAVE_FILE")."""
|
||||
self.audio
|
||||
|
||||
def set_voice(self, a_voice):
|
||||
"""Set the voice to speak with
|
||||
(such as "dfki-prudence-hsmm")."""
|
||||
self.voice = a_voice
|
||||
|
||||
def get_voice(self):
|
||||
"""Get the voice to speak with
|
||||
(such as "dfki-prudence-hsmm")."""
|
||||
self.voice
|
||||
|
||||
def generate(self, message):
|
||||
"""Given a message in message,
|
||||
return a response in the appropriate
|
||||
format."""
|
||||
raw_params = {"INPUT_TEXT": message,
|
||||
"INPUT_TYPE": self.input_type,
|
||||
"OUTPUT_TYPE": self.output_type,
|
||||
"LOCALE": self.locale,
|
||||
"AUDIO": self.audio,
|
||||
"VOICE": self.voice,
|
||||
}
|
||||
params = urllib.urlencode(raw_params)
|
||||
headers = {}
|
||||
|
||||
# Open connection to self.host, self.port.
|
||||
conn = httplib.HTTPConnection(self.host, self.port)
|
||||
|
||||
# conn.set_debuglevel(5)
|
||||
|
||||
conn.request("POST", "/process", params, headers)
|
||||
response = conn.getresponse()
|
||||
if response.status != 200:
|
||||
print response.getheaders()
|
||||
raise RuntimeError("{0}: {1}".format(response.status,
|
||||
response.reason))
|
||||
return response.read()
|
||||
|
||||
# If this is invoked as a program, just give
|
||||
# a greeting to show it is working.
|
||||
# The platform specific code is moved to this
|
||||
# part so that this file may be imported without
|
||||
# bringing platform specific code in.
|
||||
if __name__ == "__main__":
|
||||
|
||||
# For handling command line arguments:
|
||||
import sys
|
||||
import platform
|
||||
|
||||
# check we are on Windows:
|
||||
system = platform.system().lower()
|
||||
if (system == "windows"):
|
||||
|
||||
import winsound
|
||||
|
||||
class Player:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def play(self, a_sound):
|
||||
winsound.PlaySound(a_sound, winsound.SND_MEMORY)
|
||||
|
||||
#if ("cygwin" in system):
|
||||
else:
|
||||
# Not sure how to do audio on cygwin,
|
||||
# portably for python. So have a sound
|
||||
# player class that doesn't play sounds.
|
||||
# A null object, if you like.
|
||||
class Player:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def play(self, a_sound):
|
||||
print("Here I would play a sound if I knew how")
|
||||
pass
|
||||
|
||||
# Probably want to parse arguments to
|
||||
# set the voice, etc., here
|
||||
|
||||
client = maryclient()
|
||||
client.set_audio("WAVE_FILE") # for example
|
||||
|
||||
player = Player()
|
||||
the_sound = client.generate("hello from Mary Text to Speech, with Python.")
|
||||
if client.output_type == "AUDIO":
|
||||
player.play(the_sound)
|
||||
|
||||
# vi:set sw=4 et:
|
||||
177
external/marytts-5.1.2/doc/examples/client/maryclient.cgi
vendored
Normal file
177
external/marytts-5.1.2/doc/examples/client/maryclient.cgi
vendored
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
#!/usr/bin/perl -T
|
||||
# -*- Mode: Perl -*-
|
||||
# MARY Text-to-Speech System
|
||||
# CGI Script implementing a simple mary client,
|
||||
# can be used for web pages.
|
||||
##########################################################################
|
||||
# Copyright (C) 2000-2006 DFKI GmbH.
|
||||
# All rights reserved. Use is subject to license terms.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to use and distribute
|
||||
# this software and its documentation without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of this work, and to
|
||||
# permit persons to whom this work is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# 1. The code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
# 2. Any modifications must be clearly marked as such.
|
||||
# 3. Original authors' names are not deleted.
|
||||
# 4. The authors' names are not used to endorse or promote products
|
||||
# derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
# THIS SOFTWARE.
|
||||
##########################################################################
|
||||
# Author: Marc Schroeder
|
||||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
use CGI;
|
||||
|
||||
# variables getting their values from form:
|
||||
my ($inputtext, $in, $out, $audiotype, $voice);
|
||||
|
||||
# little helpers:
|
||||
my ($var, $tmp);
|
||||
|
||||
# contacting the mary server:
|
||||
my ($host, $port, $maryInfoSocket, $maryDataSocket, $id);
|
||||
|
||||
# helping with audio output:
|
||||
my ($save_to_disk, $audiosubtype, $filename);
|
||||
|
||||
|
||||
my $cgi = new CGI;
|
||||
my @param = $cgi->param();
|
||||
$inputtext = $cgi->param('inputtext');
|
||||
$in = $cgi->param('in');
|
||||
$out = $cgi->param('out');
|
||||
$audiotype = $cgi->param('audiotype');
|
||||
$save_to_disk = $cgi->param('save_to_disk');
|
||||
$voice = $cgi->param('voice');
|
||||
|
||||
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
|
||||
$year += 1900;
|
||||
printf STDERR "[%04i-%02i-%02i %02i:%02i:%02i] ", $year, $mon, $mday, $hour, $min, $sec;
|
||||
print STDERR "Request from ",$cgi->remote_user(),"@",$cgi->remote_host(),": \n";
|
||||
print STDERR " in=",$in;
|
||||
print STDERR " out=",$out;
|
||||
print STDERR " audiotype=",$audiotype;
|
||||
print STDERR " voice=",$voice;
|
||||
print STDERR " save_to_disk=",$save_to_disk,"\n";
|
||||
print STDERR " inputtext: ";
|
||||
print STDERR $inputtext,"\n";
|
||||
|
||||
|
||||
# Limit inputtext length to 5000 bytes:
|
||||
if (length $inputtext > 5000) {
|
||||
$inputtext = substr $inputtext, 0, 5000;
|
||||
}
|
||||
|
||||
|
||||
# set audio subtype
|
||||
if ($out eq "AUDIO") {
|
||||
if ($audiotype eq "AU") {
|
||||
$audiosubtype = "basic";
|
||||
$filename = "mary.au";
|
||||
} elsif ($audiotype eq "AIFF") {
|
||||
$audiosubtype = "x-aiff";
|
||||
$filename = "mary.aiff";
|
||||
} elsif ($audiotype eq "WAVE") {
|
||||
$audiosubtype = "x-wav";
|
||||
$filename = "mary.wav";
|
||||
} elsif ($audiotype eq "MP3") {
|
||||
$audiosubtype = "mp3";
|
||||
$filename = "mary.mp3";
|
||||
} else {
|
||||
$audiosubtype = "x-wav";
|
||||
$filename = "mary.wav";
|
||||
}
|
||||
}
|
||||
|
||||
# announce data type on stdout
|
||||
if ($save_to_disk) {
|
||||
print "Content-Type: application/octet-stream";
|
||||
} else {
|
||||
print "Content-Type: audio/$audiosubtype";
|
||||
}
|
||||
print "\nContent-Disposition: filename=\"$filename\"\n\n";
|
||||
|
||||
# contact mary server
|
||||
$host = "cling.dfki.uni-sb.de";
|
||||
$port = 59125;
|
||||
|
||||
# create a tcp connection to the specified host and port
|
||||
$maryInfoSocket = IO::Socket::INET->new(Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port)
|
||||
or die "can't connect to port $port on $host: $!";
|
||||
|
||||
# avoid buffering when writing to server:
|
||||
$maryInfoSocket->autoflush(1); # so output gets there right away
|
||||
|
||||
########## Write input to server: ##########
|
||||
# formulate the request:
|
||||
print $maryInfoSocket "MARY IN=$in OUT=$out AUDIO=$audiotype";
|
||||
if ($voice && $voice ne 'v') { print $maryInfoSocket " VOICE=$voice"; }
|
||||
print $maryInfoSocket " LOG=\"REMOTE_HOST=$ENV{'REMOTE_HOST'}",
|
||||
", REMOTE_ADDR=$ENV{'REMOTE_ADDR'}\"";
|
||||
print $maryInfoSocket "\015\012";
|
||||
|
||||
# receive a request ID:
|
||||
$id = <$maryInfoSocket>;
|
||||
|
||||
# open second socket for the data:
|
||||
$maryDataSocket = IO::Socket::INET->new(Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port)
|
||||
or die "can't connect to port $port on $host: $!";
|
||||
# identify with request number:
|
||||
print $maryDataSocket $id; # $id contains a newline character
|
||||
|
||||
# copy $inputtext to mary data socket
|
||||
print $maryDataSocket $inputtext;
|
||||
|
||||
# mark end-of-request:
|
||||
print $maryDataSocket "\015\012"; # that is a \n, actually
|
||||
$maryDataSocket->shutdown(1); # we have stopped writing data
|
||||
|
||||
########## Read output from server: ##########
|
||||
# copy the data socket to standard output
|
||||
if ($out ne "AUDIO") { # text output
|
||||
my $line;
|
||||
while (defined ($line = <$maryDataSocket>)) {
|
||||
print STDOUT $line;
|
||||
}
|
||||
} else { # audio data output
|
||||
my $nr; # number of bytes read
|
||||
my $buf; # buffer to read into
|
||||
my $outnr; # number of bytes written
|
||||
while($nr = read($maryDataSocket, $buf, 8192)) {
|
||||
# (read returns no. of bytes read, 0 at eof)
|
||||
print STDOUT $buf
|
||||
or die "Write error on stdout";
|
||||
} # while read something from socket
|
||||
} # audio output
|
||||
|
||||
### Read complaints from server:
|
||||
my $line;
|
||||
while (defined ($line = <$maryInfoSocket>)) {
|
||||
print STDERR $line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
136
external/marytts-5.1.2/doc/examples/client/maryclient.pl
vendored
Normal file
136
external/marytts-5.1.2/doc/examples/client/maryclient.pl
vendored
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
#!/usr/bin/env perl
|
||||
#
|
||||
# MARY Text-to-Speech System
|
||||
# Minimal Socket client (for demonstration)
|
||||
##########################################################################
|
||||
# Copyright (C) 2000-2006 DFKI GmbH.
|
||||
# All rights reserved. Use is subject to license terms.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to use and distribute
|
||||
# this software and its documentation without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of this work, and to
|
||||
# permit persons to whom this work is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# 1. The code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
# 2. Any modifications must be clearly marked as such.
|
||||
# 3. Original authors' names are not deleted.
|
||||
# 4. The authors' names are not used to endorse or promote products
|
||||
# derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
# DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
# THIS SOFTWARE.
|
||||
##########################################################################
|
||||
# Author: Marc Schroeder
|
||||
# This is a minimal version of a socket client for the mary TtS system.
|
||||
# It is intended to be used as a model for writing socket clients for
|
||||
# particular applications. All input verification, command line options,
|
||||
# and other luxury have been omitted.
|
||||
#
|
||||
# Usage:
|
||||
# maryclient.pl infile.txt > outfile.wav
|
||||
#
|
||||
# Input/output formats and other options must be set in the perl code directly.
|
||||
# See also Protocol.html for a description of the Protocol.
|
||||
#
|
||||
|
||||
use strict;
|
||||
use IO::Socket;
|
||||
|
||||
############################
|
||||
# Package-global variables #
|
||||
############################
|
||||
# global settings:
|
||||
my $maryInfoSocket; # handle to socket server
|
||||
my $maryDataSocket; # handle to socket server
|
||||
my $host; # string containing host address
|
||||
my $port; # socket port on which we listen
|
||||
my ($in, $out, $audiotype); # requested input / output format
|
||||
my $voice; # default voice
|
||||
my $id; # request ID
|
||||
|
||||
######################################################################
|
||||
################################ main ################################
|
||||
######################################################################
|
||||
|
||||
STDOUT->autoflush(1);
|
||||
|
||||
$host = "cling.dfki.uni-sb.de";
|
||||
$port = 59125;
|
||||
$in = "TEXT_DE";
|
||||
$out = "AUDIO";
|
||||
$audiotype = "MP3";
|
||||
#$audiotype = "WAVE";
|
||||
#$voice = "male";
|
||||
$voice = "de3";
|
||||
|
||||
# create a tcp connection to the specified host and port
|
||||
$maryInfoSocket = IO::Socket::INET->new(Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port)
|
||||
or die "can't connect to port $port on $host: $!";
|
||||
|
||||
# avoid buffering when writing to server:
|
||||
$maryInfoSocket->autoflush(1); # so output gets there right away
|
||||
|
||||
########## Write input to server: ##########
|
||||
# formulate the request:
|
||||
print $maryInfoSocket "MARY IN=$in OUT=$out AUDIO=$audiotype";
|
||||
if ($voice) { print $maryInfoSocket " VOICE=$voice"; }
|
||||
print $maryInfoSocket "\015\012";
|
||||
|
||||
# receive a request ID:
|
||||
$id = <$maryInfoSocket>;
|
||||
chomp $id; chomp $id;
|
||||
|
||||
# open second socket for the data:
|
||||
$maryDataSocket = IO::Socket::INET->new(Proto => "tcp",
|
||||
PeerAddr => $host,
|
||||
PeerPort => $port)
|
||||
or die "can't connect to port $port on $host: $!";
|
||||
# identify with request number:
|
||||
print $maryDataSocket $id, "\015\012";
|
||||
|
||||
# copy standard input and/or files given on the command line to the socket
|
||||
while (defined (my $line = <>)) {
|
||||
print $maryDataSocket $line;
|
||||
}
|
||||
# mark end-of-request:
|
||||
print $maryDataSocket "\015\012"; # that is a \n, actually
|
||||
shutdown($maryDataSocket, 1); # we have stopped writing data
|
||||
|
||||
########## Read output from server: ##########
|
||||
# copy the data socket to standard output
|
||||
if ($out ne "AUDIO") { # text output
|
||||
my $line;
|
||||
while (defined ($line = <$maryDataSocket>)) {
|
||||
print STDOUT $line;
|
||||
}
|
||||
} else { # audio data output
|
||||
my $nr; # number of bytes read
|
||||
my $buf; # buffer to read into
|
||||
my $outnr; # number of bytes written
|
||||
while($nr = read($maryDataSocket, $buf, 100000)) {
|
||||
# (read returns no. of bytes read, 0 at eof)
|
||||
print STDOUT $buf
|
||||
or die "Write error on stdout";
|
||||
} # while read something from socket
|
||||
} # audio output
|
||||
|
||||
### Read complaints from server:
|
||||
my $line;
|
||||
while (defined ($line = <$maryInfoSocket>)) {
|
||||
print STDERR $line;
|
||||
}
|
||||
|
||||
|
||||
|
||||
261
external/marytts-5.1.2/doc/examples/client/maryclient.rb
vendored
Normal file
261
external/marytts-5.1.2/doc/examples/client/maryclient.rb
vendored
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
#!/usr/bin/env ruby
|
||||
#
|
||||
# A basic mary client in Ruby,
|
||||
# kindly donated to the MARY TTS project
|
||||
# by Hugh Sasse. Thanks Hugh!
|
||||
|
||||
|
||||
# Ruby client for the MARY TTS HTTP server.
|
||||
# This is for Windows only, and relies on
|
||||
# the Win32-Sound gem to access the audio.
|
||||
#
|
||||
#
|
||||
|
||||
require 'rubygems'
|
||||
require 'net/http'
|
||||
require 'uri'
|
||||
|
||||
# A fairly minimal client class for the
|
||||
# MARY TTS system. This uses the modern
|
||||
# HTTP interface to access the server.
|
||||
# At present, this doesn't wrap the methods
|
||||
# which provide documentation or lists of
|
||||
# voices or features.
|
||||
class MaryClient
|
||||
attr_accessor :host, :port
|
||||
attr_accessor :input_type, :output_type
|
||||
attr_accessor :locale, :audio, :voice
|
||||
|
||||
# Set up the defaults for the MARY TTS
|
||||
# server, which is assumed to be running
|
||||
# on the local host, with British voices
|
||||
# installed. These may be modified with
|
||||
# the appropriate methods.
|
||||
# host = 127.0.0.1)
|
||||
# port = 59125
|
||||
# input_type = "TEXT"
|
||||
# output_type = "AUDIO"
|
||||
# audio = "WAVE_FILE"
|
||||
# locale = "en_GB"
|
||||
# voice = "dfki-prudence-hsmm"
|
||||
def initialize
|
||||
@host = "127.0.0.1" # The local machine
|
||||
@port = 59125
|
||||
@input_type = "TEXT"
|
||||
@output_type = "AUDIO"
|
||||
@locale = "en_GB"
|
||||
@audio = "WAVE_FILE"
|
||||
@voice = "dfki-prudence-hsmm"
|
||||
end
|
||||
|
||||
# Process a text message, which with a
|
||||
# new client, will return the audio.
|
||||
# This is so that platform dependent parts
|
||||
# are kept separate.
|
||||
def generate(message)
|
||||
raw_params = {"INPUT_TEXT" => message,
|
||||
"INPUT_TYPE" => @input_type,
|
||||
"OUTPUT_TYPE" => @output_type,
|
||||
"LOCALE" => @locale,
|
||||
"AUDIO" => @audio,
|
||||
"VOICE" => @voice,
|
||||
}
|
||||
res = Net::HTTP.post_form(URI.parse("http://#{@host}:#{@port}/process"), raw_params)
|
||||
res.value # Throw an exception on failure
|
||||
#puts res.body
|
||||
return res.body
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# If this invoked as a program with no
|
||||
# argumens, just give a greeting to show
|
||||
# that it is working. If arguments are
|
||||
# supplied, process options to work out
|
||||
# what to do with the arguments.
|
||||
if __FILE__ == $0
|
||||
|
||||
# These files are only loaded when this is
|
||||
# invoked as a program.
|
||||
require 'rbconfig'
|
||||
require 'getoptlong'
|
||||
|
||||
# PLATFORM SPECIFIC CODE.
|
||||
# Needs more work [!]
|
||||
case Config::CONFIG['host_os']
|
||||
when /darwin/i
|
||||
raise NotImplementedError.new("Don't know how to play audio on a Mac")
|
||||
when /linux/i
|
||||
raise NotImplementedError.new("Far too many ways to play audio on Linux, you'll need to choose something")
|
||||
when /sunos|solaris/i
|
||||
raise NotImplementedError.new("Have not played audio on Suns for too long to implement this.")
|
||||
when /java/i
|
||||
raise NotImplementedError.new("Don't know how to play audio from Java ")
|
||||
when /win32|cygwin|mingw32/i
|
||||
# The various things that can use the Win32
|
||||
# sound gem
|
||||
require 'win32/sound'
|
||||
# Create a player class that will play the
|
||||
# sound that the Mary TTS system returns
|
||||
class Player
|
||||
|
||||
# Play the audio passed in.
|
||||
# Possibly this should receive the audio
|
||||
# type so we can check that we can play it,
|
||||
# but at the moment that is the
|
||||
# responsibility of the user.
|
||||
def self.play(sound)
|
||||
Win32::Sound.play(sound, Win32::Sound::MEMORY)
|
||||
end
|
||||
end
|
||||
else
|
||||
raise NotImplementedError.new("Haven't thought how to support this OS yet")
|
||||
end
|
||||
|
||||
|
||||
client = nil
|
||||
split = ""
|
||||
|
||||
if ARGV.size.zero?
|
||||
client = MaryClient.new()
|
||||
sound = client.generate("Hello from Mary Text to Speech with Ruby.")
|
||||
Player.play(sound)
|
||||
else
|
||||
args_mode = :words
|
||||
stdout_mode = :absorb
|
||||
opts = GetoptLong::new(
|
||||
["--audio", "-a", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--echo", "-e", GetoptLong::NO_ARGUMENT],
|
||||
["--help", "-h", GetoptLong::NO_ARGUMENT],
|
||||
["--host", "-H", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--input-type", "-i", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--locale", "-l", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--read", "-r", GetoptLong::NO_ARGUMENT],
|
||||
|
||||
["--split", "-s", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--output-type", "-o", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--port", "-P", GetoptLong::REQUIRED_ARGUMENT],
|
||||
["--tee", "-t", GetoptLong::NO_ARGUMENT],
|
||||
["--voice", "-v", GetoptLong::REQUIRED_ARGUMENT]
|
||||
)
|
||||
|
||||
opts.each do |opt, arg|
|
||||
unless ["--help", "-h"].include?(opt)
|
||||
# skip if we are only getting help
|
||||
client ||= MaryClient.new()
|
||||
end
|
||||
case opt
|
||||
when "--help", "-h"
|
||||
puts <<-EOHELP
|
||||
Usage: #{$0} [options] [arguments]
|
||||
--audio -a
|
||||
Audio format. Defualt: WAVE_FILE
|
||||
--echo -e
|
||||
Act as an echo command and send output
|
||||
arguments to the synthesizer only (not
|
||||
to standard output.
|
||||
Turns off --read|-r
|
||||
--help -h
|
||||
Print this help, then exit.
|
||||
--host -H
|
||||
The host which is the server.
|
||||
Default: 127.0.0.1
|
||||
--input-type -i
|
||||
The type of the input supplied to the
|
||||
TTS system. Default: TEXT
|
||||
--locale -l
|
||||
The locale of the input. Default: en_GB
|
||||
--output-type -o
|
||||
The output type from the TTS system.
|
||||
Default: AUDIO
|
||||
--port -P
|
||||
The port for the TTS server
|
||||
Default: 59125
|
||||
--read -r
|
||||
Read the files passed as arguments.
|
||||
Turns off --echo|-e
|
||||
--split -s (lines|paragraphs)
|
||||
When reading files, split the input
|
||||
into lines or paragraphs. Paragraphs
|
||||
mean reading up to the next double
|
||||
newline. Note, the argument is literally
|
||||
"lines" or "paragraphs" (or some
|
||||
abbreviation of those) without the
|
||||
quotes.
|
||||
Default is paragraphs.
|
||||
--tee -t
|
||||
Act as tee: send the output to the TTS
|
||||
system, and to standard output.
|
||||
--voice -v
|
||||
The voice to use.
|
||||
Default: dfki-prudence-hsmm
|
||||
EOHELP
|
||||
exit(0)
|
||||
when "--audio", "-a"
|
||||
client.audio = arg
|
||||
when "--echo", "-e"
|
||||
args_mode = :words
|
||||
when "--host", "-H"
|
||||
client.host = arg
|
||||
when "--input-type", "-i"
|
||||
client.input_type = arg
|
||||
when "--locale", "-l"
|
||||
client.locale = arg
|
||||
when "--output-type", "-o"
|
||||
client.output_type = arg
|
||||
when "--port", "-P"
|
||||
client.port = arg.to_i
|
||||
when "--read", "-r"
|
||||
args_mode = :files
|
||||
when "--split", "-s"
|
||||
case arg
|
||||
when /^p/i
|
||||
split = ""
|
||||
when /^l/i
|
||||
split = $/
|
||||
end
|
||||
when "--tee", "-t"
|
||||
stdout_mode = :emit
|
||||
when "--voice", "-v"
|
||||
client.voice = arg
|
||||
end
|
||||
end
|
||||
|
||||
client ||= MaryClient.new()
|
||||
case args_mode
|
||||
when :words
|
||||
input_text = ARGV.join(" ")
|
||||
unless input_text =~ /\A\s*\Z/m
|
||||
sound = client.generate(input_text)
|
||||
if client.output_type == "AUDIO"
|
||||
Player.play(sound)
|
||||
end
|
||||
end
|
||||
if stdout_mode == :emit
|
||||
puts input_text
|
||||
end
|
||||
when :files
|
||||
# Slurp in paragraphs so sentences
|
||||
# don't get broken in stupid places.
|
||||
$/ = split # paragraph mode
|
||||
ARGF.each do |paragraph|
|
||||
begin
|
||||
unless paragraph =~ /\A\s*\Z/m
|
||||
sound = client.generate(paragraph)
|
||||
if client.output_type == "AUDIO"
|
||||
# and client.audio == "WAVE_FILE"
|
||||
Player.play(sound)
|
||||
end
|
||||
end
|
||||
rescue Exception => e
|
||||
puts "got error #{e} while trying to say #{paragraph.inspect}"
|
||||
raise
|
||||
end
|
||||
if stdout_mode == :emit
|
||||
puts paragraph
|
||||
end # end if
|
||||
end # end ARGF.each
|
||||
end # end case
|
||||
end # if ARGV.size.zero?
|
||||
end
|
||||
|
||||
705
external/marytts-5.1.2/doc/examples/client/maryclient.tcl
vendored
Normal file
705
external/marytts-5.1.2/doc/examples/client/maryclient.tcl
vendored
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
# Tcl/Tk MARY TTS client.
|
||||
|
||||
# This has been tested on Windows, and because
|
||||
# of the use of sound there will be portability
|
||||
# issues. However, there should be enough here
|
||||
# for a reasonable start at a client, for any
|
||||
# platform that supports Tcl/Tk. The platform
|
||||
# specific code has, as far as possible, been
|
||||
# isolated in the part of the code that detects
|
||||
# whether this is being run as a program.
|
||||
|
||||
# Notes:
|
||||
# More work will need to be done with this,
|
||||
# in order to make the code clean. It should
|
||||
# probably be wrapped in a package, to solve
|
||||
# any namespace issues. There are a lot of
|
||||
# global variables. It seems that some of
|
||||
# these are necessary for the menus to work.
|
||||
# Handling of temporary files could be improved.
|
||||
|
||||
# TODO:
|
||||
# Create modifier sliders, for the effects.
|
||||
# Extend the query proc to make use of them.
|
||||
# Turn the Help menu into something more useful.
|
||||
# Debug the actions for the Edit menu.
|
||||
# Provide a means of getting example inputs
|
||||
# from the server.
|
||||
# Provide a means of re-loading all the
|
||||
# dynamically collected information when the
|
||||
# server is changed from the menu. This means
|
||||
# that we need to delete the existing menu
|
||||
# entries in order to add them correctly.
|
||||
# How do we ensure temporary files are removed
|
||||
# in the event of a problem? if {catch {}} ...?
|
||||
# Maybe leaving them around is diagnostic info?
|
||||
# Make that an option?
|
||||
# Add error handling code for network and disk
|
||||
# failures likely to beset such clients.
|
||||
# Add sensible defaults for things the user must
|
||||
# always set at startup, but these will be
|
||||
# platform spacific. Always default to Audio
|
||||
# output for example, or is it possible that
|
||||
# people have no voices installed?
|
||||
|
||||
|
||||
# This is a GUI, so:
|
||||
package require Tk
|
||||
|
||||
# We are communicating with the Mary server
|
||||
# with HTTP.
|
||||
package require http
|
||||
|
||||
# Use the local machine in preference to the
|
||||
# one in Germany.
|
||||
set mary_tts_default_host "127.0.0.1"
|
||||
set mary_tts_default_port 59125
|
||||
|
||||
# Actual host and port, and global old
|
||||
# copies to allow revert on cancel in the
|
||||
# dialogues. Apparently upvar #0 is the
|
||||
# norm for that sort of thing [Tcl Wiki]
|
||||
set mary_tts_host $mary_tts_default_host
|
||||
set old_mary_tts_host $mary_tts_host
|
||||
set mary_tts_port $mary_tts_default_port
|
||||
set old_mary_tts_port $mary_tts_port
|
||||
|
||||
# Informational URLs
|
||||
set informational_urls [ list \
|
||||
version datatypes voices \
|
||||
audioformats audioeffects ]
|
||||
|
||||
#######
|
||||
|
||||
# Obtain a static page from the server, i.e.
|
||||
# no parameters are needed to get it.
|
||||
proc get_page { relative_url } {
|
||||
global mary_tts_host mary_tts_port
|
||||
set url http://$mary_tts_host:$mary_tts_port/$relative_url
|
||||
set result [::http::geturl $url]
|
||||
return [::http::data $result]
|
||||
}
|
||||
|
||||
proc list_of_lines {str} {
|
||||
return [ split $str "\n" ]
|
||||
}
|
||||
|
||||
|
||||
# We will need to collect this information
|
||||
# when we have the server and port chosen.
|
||||
proc get_audioeffects {} {
|
||||
return [list_of_lines [get_page audioeffects] ]
|
||||
}
|
||||
|
||||
proc get_audioformats {} {
|
||||
return [list_of_lines [get_page audioformats] ]
|
||||
}
|
||||
|
||||
proc get_datatypes {} {
|
||||
return [ list_of_lines [get_page datatypes] ]
|
||||
}
|
||||
|
||||
|
||||
proc get_voices {} {
|
||||
return [list_of_lines [get_page voices] ]
|
||||
}
|
||||
|
||||
# Handling post queries.
|
||||
|
||||
# Submit the query to the server, using the
|
||||
# http POST method.
|
||||
proc make_query {url encoded_params} {
|
||||
set http [::http::geturl $url -query $encoded_params]
|
||||
set result [::http::data $http]
|
||||
return $result
|
||||
}
|
||||
|
||||
# Get the text from the input text area
|
||||
proc get_input_text {} {
|
||||
return [.io.inp.input_area get 1.0 end]
|
||||
}
|
||||
|
||||
# Get the text from the output text area
|
||||
proc get_output_text {} {
|
||||
return [.io.out.output_area get 1.0 end]
|
||||
}
|
||||
|
||||
# Collect the audio data from the server.
|
||||
proc collect_audio_data {text_to_process} {
|
||||
global mary_tts_host mary_tts_port
|
||||
global inputtype outputtype locales
|
||||
global audioformat voice
|
||||
set url "http://$mary_tts_host:$mary_tts_port/process"
|
||||
# ::http::formatQuery converts a list of
|
||||
# key value pairs into the correct format
|
||||
# for http POST.
|
||||
set params [::http::formatQuery INPUT_TEXT $text_to_process INPUT_TYPE $inputtype OUTPUT_TYPE $outputtype LOCALE $locales($voice) AUDIO $audioformat VOICE $voice ]
|
||||
set result [make_query $url $params]
|
||||
return $result
|
||||
}
|
||||
|
||||
# Pushes the query to the server and gets
|
||||
# the results back, displaying or playing
|
||||
# them.
|
||||
proc generate_output {text_to_process} {
|
||||
global outputtype
|
||||
set result [collect_audio_data $text_to_process]
|
||||
if {$outputtype eq "AUDIO"} {
|
||||
# call the platform dependent implementation.
|
||||
play $result
|
||||
} else {
|
||||
clear_output
|
||||
add_message $result
|
||||
}
|
||||
# Return the result so we can save it if
|
||||
# the user requires it.
|
||||
return $result
|
||||
}
|
||||
|
||||
|
||||
# These next procs are for handling the
|
||||
# lists of data one gets back from the server
|
||||
# which possibly have several words per line,
|
||||
# separated by spaces.
|
||||
|
||||
# If the first word of each listed line is
|
||||
# significant, extract the list of first words.
|
||||
proc collect_first_words_of_phrase_list {a_list} {
|
||||
for {set i 0} {$i < [llength $a_list]} {incr i} {
|
||||
set data [lindex $a_list $i ]
|
||||
set word [ lindex [split $data " "] 0 ]
|
||||
lappend words $word
|
||||
}
|
||||
return $words
|
||||
}
|
||||
|
||||
|
||||
# If the second word of each listed line is
|
||||
# significant, extract the list of second words.
|
||||
proc collect_second_words_of_phrase_list {a_list} {
|
||||
for {set i 0} {$i < [llength $a_list]} {incr i} {
|
||||
set data [lindex $a_list $i ]
|
||||
set word [ lindex [split $data " "] 1 ]
|
||||
lappend words $word
|
||||
}
|
||||
return $words
|
||||
}
|
||||
|
||||
|
||||
# The list of datatypes must be separated into
|
||||
# input data types and output data types so that
|
||||
# interactions with the server make sense.
|
||||
# This handles the inputs.
|
||||
proc collect_first_words_of_input_types {a_list} {
|
||||
for {set i 0} {$i < [llength $a_list]} {incr i} {
|
||||
set data [lindex $a_list $i ]
|
||||
if {[ string match -nocase "*input*" $data ]} {
|
||||
set word [ lindex [split $data " "] 0 ]
|
||||
lappend words $word
|
||||
}
|
||||
}
|
||||
return $words
|
||||
}
|
||||
|
||||
|
||||
# The list of datatypes must be separated into
|
||||
# input data types and output data types so that
|
||||
# interactions with the server make sense.
|
||||
# This handles the outputs.
|
||||
proc collect_first_words_of_output_types {a_list} {
|
||||
for {set i 0} {$i < [llength $a_list]} {incr i} {
|
||||
set data [lindex $a_list $i ]
|
||||
if {[string match -nocase "*output*" $data]} {
|
||||
set word [ lindex [split $data " "] 0 ]
|
||||
lappend words $word
|
||||
}
|
||||
}
|
||||
return $words
|
||||
}
|
||||
|
||||
# setup all the variables to hold voices,
|
||||
# audio options, etc., based on what the
|
||||
# server can do.
|
||||
proc setup_globals {} {
|
||||
global audioeffects audioformats voices
|
||||
global inputtypes outputtypes audioformat voice
|
||||
global inputtype outputtype locales
|
||||
|
||||
set audioeffects [get_audioeffects]
|
||||
set audioformats [get_audioformats]
|
||||
set audioformat [lindex $audioformats 0 ]
|
||||
set datatypes_data [get_datatypes]
|
||||
set inputtypes [collect_first_words_of_input_types $datatypes_data]
|
||||
set inputtype [lindex $inputtypes 0]
|
||||
set outputtypes [collect_first_words_of_output_types $datatypes_data]
|
||||
set outputtype [lindex $outputtypes 0]
|
||||
set voices_data [get_voices]
|
||||
set voices [collect_first_words_of_phrase_list $voices_data]
|
||||
set locales_list [collect_second_words_of_phrase_list $voices_data ]
|
||||
for {set i 0} {$i < [llength $voices]} {incr i} {
|
||||
set locales([lindex $voices $i]) [lindex $locales_list $i]
|
||||
}
|
||||
set voice [lindex $voices 0]
|
||||
}
|
||||
|
||||
# A general procedure for filling in the
|
||||
# elements of a listbox from a list.
|
||||
# At present this is unused, but it could
|
||||
# be useful later. [It took a while to
|
||||
# figure out so I'm not ready to kill it
|
||||
# with YAGNI.]
|
||||
proc add_listbox_items {a_var a_widget} {
|
||||
upvar $a_var var
|
||||
foreach item $var {
|
||||
$a_widget insert end $item
|
||||
}
|
||||
}
|
||||
|
||||
# Create the menubuttons along the top.
|
||||
# Usual File, Edit and Help menus plus
|
||||
# those to set attributes.
|
||||
proc create_menubuttons {} {
|
||||
set buttons [ list file File edit Edit \
|
||||
server "Server" \
|
||||
inputtype "Input type" outputtype "Output type" \
|
||||
voice Voice \
|
||||
audioformat "Audio format" \
|
||||
textstyle "Text style" help Help ]
|
||||
|
||||
set count 1
|
||||
foreach { menu_tag string_tag} $buttons {
|
||||
menubutton .menus.$menu_tag -text $string_tag \
|
||||
-menu .menus.${menu_tag}.menu -underline 0 -font ClientFont
|
||||
menu .menus.${menu_tag}.menu -tearoff true
|
||||
grid .menus.$menu_tag -in .menus -row 1 -column $count -sticky w
|
||||
incr count
|
||||
}
|
||||
}
|
||||
|
||||
# Get the contents of a text file for reading
|
||||
# or loading into a text widget, etc.
|
||||
proc text_file_contents {what_for} {
|
||||
set a_file [tk_getOpenFile -title $what_for ]
|
||||
set the_text ""
|
||||
|
||||
if {$a_file != ""} {
|
||||
set a_stream [open $a_file r ]
|
||||
set the_text [read $a_stream]
|
||||
close $a_stream
|
||||
}
|
||||
|
||||
return $the_text
|
||||
}
|
||||
|
||||
|
||||
# Save the_text to a text file specified
|
||||
# by the user, for the given reason (what_for).
|
||||
# At the moment there is no error handling
|
||||
# for this (disk full, write protected, etc).
|
||||
proc save_text_file {the_text what_for} {
|
||||
set a_file [tk_getSaveFile -title $what_for -parent .]
|
||||
if {$a_file != ""} {
|
||||
set a_stream [open $a_file w ]
|
||||
puts $a_stream $the_text
|
||||
close $a_stream
|
||||
}
|
||||
}
|
||||
|
||||
# Save the_data to a binary file specified
|
||||
# by the user, for the given reason (what_for),
|
||||
# a text string.
|
||||
# At the moment there is no error handling
|
||||
# for this (disk full, write protected, etc).
|
||||
proc save_binary_file {the_data what_for} {
|
||||
set a_file [tk_getSaveFile -title $what_for -parent .]
|
||||
if {$a_file != ""} {
|
||||
set a_stream [open $a_file w ]
|
||||
fconfigure $a_stream -translation binary
|
||||
puts -nonewline $a_stream $the_data
|
||||
close $a_stream
|
||||
}
|
||||
}
|
||||
|
||||
# Create the menu for File operations
|
||||
proc create_menu_file {} {
|
||||
set fmenu .menus.file.menu
|
||||
$fmenu add command -label "New" \
|
||||
-font ClientFont -command {
|
||||
.io.inp.input_area delete 1.0 end
|
||||
}
|
||||
# Replace the contents of the input text
|
||||
# widget by the data from the open file.
|
||||
# <FIXME>YAGNI, but is there any reason
|
||||
# to allow inserting a file, rather than
|
||||
# replacing the text with file contents?
|
||||
# </FIXME>
|
||||
$fmenu add command -label "Open" \
|
||||
-font ClientFont -command {
|
||||
set the_text [text_file_contents "File to load"]
|
||||
if {$the_text != ""} {
|
||||
.io.inp.input_area delete 1.0 end
|
||||
.io.inp.input_area insert end $the_text
|
||||
}
|
||||
}
|
||||
|
||||
$fmenu add command -label "Read" \
|
||||
-font ClientFont -command {
|
||||
generate_output [text_file_contents "File to read"]
|
||||
}
|
||||
# How to make these disabled for now?
|
||||
$fmenu add command -label "Save Input" \
|
||||
-font ClientFont -command {
|
||||
set the_text [get_input_text]
|
||||
save_text_file $the_text "Save Input"
|
||||
}
|
||||
$fmenu add command -label "Save Output" \
|
||||
-font ClientFont -command {
|
||||
set the_text [get_output_text]
|
||||
save_text_file $the_text "Save Output"
|
||||
}
|
||||
}
|
||||
|
||||
# Create the menu for edit operations
|
||||
proc create_menu_edit {} {
|
||||
set emenu .menus.edit.menu
|
||||
$emenu add command -label "Select All from Input Area" \
|
||||
-font ClientFont -command {
|
||||
# This code says copy the selection as well.
|
||||
# May be wrong for some platforms, but is
|
||||
# it more useful?
|
||||
.io.inp.input_area tag add sel 1.0 end
|
||||
event generate .io.inp.input_area <<copy>>
|
||||
}
|
||||
$emenu add command -label "Select All from Output Area" \
|
||||
-font ClientFont -command {
|
||||
# This code says copy the selection as well.
|
||||
# May be wrong for some platforms, but is
|
||||
# it more useful?
|
||||
.io.out.output_area tag add sel 1.0 end
|
||||
event generate .io.out.output_area <<Copy>>
|
||||
}
|
||||
$emenu add command -label "Copy from Input Area" \
|
||||
-font ClientFont -command {
|
||||
# this appears not to work. FIXME
|
||||
event generate .io.inp.input_area <<Copy>>
|
||||
}
|
||||
$emenu add command -label "Copy from Output Area" \
|
||||
-font ClientFont -command {
|
||||
# this appears not to work. FIXME
|
||||
event generate .io.out.output_area <<copy>>
|
||||
}
|
||||
$emenu add command -label "Paste into Input Area" \
|
||||
-font ClientFont -command {
|
||||
# this appears not to work. FIXME
|
||||
event generate .io.inp.input_area <<Paste>>
|
||||
}
|
||||
$emenu add command \
|
||||
-font ClientFont -label "Insert example text into Input Area"\
|
||||
-command {
|
||||
}
|
||||
# Add specific editing commands here later.
|
||||
# For example, we would like to be able to
|
||||
# add whole tags to the XML based formats,
|
||||
# wrap matching tags around selected text.
|
||||
# Also we need to find out what happens with
|
||||
# copy cut and paste, given that X Windows
|
||||
# is different from MS Windows.
|
||||
# Allow example text to be inserted.
|
||||
# However, my thinking is that this should not
|
||||
# overwrite as it is in the Java application,
|
||||
# because this rubs out edits when switching
|
||||
# voices, and this can be annoying when
|
||||
# exploring the system.
|
||||
}
|
||||
|
||||
# Set the server properties, mostly just
|
||||
# host and port. Maybe later protocol will
|
||||
# be possible for https connections?
|
||||
proc create_menu_server {} {
|
||||
set smenu .menus.server.menu
|
||||
$smenu add command -label "host" -font ClientFont -command {
|
||||
create_entry_dialog "MARY TTS server name" "hostname/IP Address" mary_tts_host
|
||||
}
|
||||
$smenu add command -label "port" -font ClientFont -command {
|
||||
create_entry_dialog "MARY TTS server port" "pott number" mary_tts_port
|
||||
}
|
||||
}
|
||||
|
||||
# setup the fonts for the various areas on the dipslay.
|
||||
proc setup_font {family size} {
|
||||
foreach win {.io .controls .entry.dialogue } {
|
||||
font configure ClientFont -family $family -size $size
|
||||
}
|
||||
}
|
||||
|
||||
# Create the menu for changing the text size.
|
||||
proc create_menu_textstyle {} {
|
||||
set tmenu .menus.textstyle.menu
|
||||
|
||||
$tmenu add cascade -label "Courier" -underline 0 -menu \
|
||||
$tmenu.courier -font ClientFont
|
||||
$tmenu add cascade -label "Times" -underline 0 -menu \
|
||||
$tmenu.times -font ClientFont
|
||||
$tmenu add cascade -label "Helvetica" -underline 0 -menu \
|
||||
$tmenu.helvetica -font ClientFont
|
||||
foreach {name family} [list $tmenu.courier Courier \
|
||||
$tmenu.times Times $tmenu.helvetica Helvetica ] {
|
||||
set m1 [menu $name]
|
||||
foreach pts {6 7 8 9 10 12 14 16 18 20 24 28 32 36} {
|
||||
$m1 add command -label "$pts" -font ClientFont\
|
||||
-command [list setup_font $family $pts ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
# Create the menu for Help
|
||||
proc create_menu_help {} {
|
||||
# This is all pretty much "wet paint"
|
||||
# Is there enough to merit separate menus?
|
||||
set hmenu .menus.help.menu
|
||||
$hmenu add command -label "Introduction" -font ClientFont\
|
||||
-command {
|
||||
tk_messageBox -message "This is a basic Tcl/Tk
|
||||
client for the MARY TTS system. Most of the options
|
||||
are reached through the menus on the top. Some
|
||||
facilities are presently lacking.
|
||||
|
||||
Most of the interface should be self-explanatory.
|
||||
In the File menu, Read will read a given file aloud
|
||||
(or at least take it as input for the present
|
||||
form of processing), whereas Open will load it
|
||||
into the input area. Save input and Save output
|
||||
refer to the contents of the text windows. The
|
||||
save button next to the play button will save
|
||||
the output to a file; this is assumed to be a
|
||||
text file, unless the output is audio, in which
|
||||
case it is a binary file.
|
||||
|
||||
The Edit menu has cut and paste facilities,
|
||||
but these don't seem to work reliably. The
|
||||
default key bindings for text areas should
|
||||
be useable.
|
||||
|
||||
You will need to set the input and output types
|
||||
and the audio format before pressing play.
|
||||
Code does not yet exist to figure out sensible
|
||||
defaults for your platform.
|
||||
|
||||
This does not have support for the effects, yet.
|
||||
|
||||
Contributions from developers welcome." -type ok
|
||||
}
|
||||
$hmenu add command -label "About" -command {} -font ClientFont
|
||||
}
|
||||
|
||||
# We need to create menus for the available
|
||||
# voices and audio formats, etc.
|
||||
# When we have the data for these menus from
|
||||
# the server, create them by using the global
|
||||
# lists of information.
|
||||
proc create_radio_menu_from_list {what} {
|
||||
global $what
|
||||
set plural "${what}s"
|
||||
upvar 1 $plural var
|
||||
foreach item $var {
|
||||
.menus.${what}.menu add radiobutton -label $item -variable $what \
|
||||
-value $item -font ClientFont
|
||||
}
|
||||
}
|
||||
|
||||
proc reset_entry_and_var {a_variable} {
|
||||
upvar #0 $a_variable var
|
||||
upvar #0 old_$a_variable old_var
|
||||
set var $old_var
|
||||
destroy .entry_dialogue
|
||||
}
|
||||
# Create the toplevel for choosing a host
|
||||
# or port, something taken from an entry.
|
||||
proc create_entry_dialog {a_message a_label a_variable} {
|
||||
upvar #0 $a_variable var
|
||||
upvar #0 old_$a_variable old_var
|
||||
toplevel .entry_dialogue
|
||||
label .entry_dialogue.the_message -text $a_message \
|
||||
-font ClientFont
|
||||
label .entry_dialogue.the_label -text $a_label -font ClientFont
|
||||
entry .entry_dialogue.the_entry -textvariable $a_variable \
|
||||
-font ClientFont
|
||||
button .entry_dialogue.ok -text "OK" -font ClientFont -command {
|
||||
destroy .entry_dialogue
|
||||
}
|
||||
button .entry_dialogue.cancel -text "Cancel" -font ClientFont \
|
||||
-command "reset_entry_and_var $a_variable"
|
||||
|
||||
grid .entry_dialogue.the_message -row 1 -column 1
|
||||
grid .entry_dialogue.the_label -row 2 -column 1
|
||||
grid .entry_dialogue.the_entry -row 2 -column 2
|
||||
grid .entry_dialogue.ok -row 3 -column 1
|
||||
grid .entry_dialogue.cancel -row 3 -column 2
|
||||
}
|
||||
|
||||
# Add a message to the end of the output
|
||||
# text widget.
|
||||
proc add_message {a_message} {
|
||||
.io.out.output_area configure -state normal
|
||||
.io.out.output_area insert end $a_message
|
||||
.io.out.output_area configure -state disabled
|
||||
}
|
||||
|
||||
|
||||
# Clear the text in the output text widget.
|
||||
proc clear_output {} {
|
||||
.io.out.output_area configure -state normal
|
||||
.io.out.output_area delete 1.0 end
|
||||
.io.out.output_area configure -state disabled
|
||||
}
|
||||
|
||||
# Sound generation is platform dependent.
|
||||
# This provides an "abstract" function to
|
||||
# be overridden by the platform dependent
|
||||
# code. In this case it alerts the user
|
||||
# in the output window that nothing is going
|
||||
# to happen.
|
||||
proc play {sound} {
|
||||
add_message \
|
||||
"play sound not implemented on this platform apparently"
|
||||
}
|
||||
|
||||
# Graphical stuff.
|
||||
|
||||
# In order to be able to scale the font, define a font.
|
||||
font create ClientFont -family [font actual TkDefaultFont -family] \
|
||||
-size [font actual TkDefaultFont -size]
|
||||
|
||||
frame .menus
|
||||
create_menubuttons
|
||||
create_menu_file
|
||||
create_menu_edit
|
||||
create_menu_server
|
||||
create_menu_textstyle
|
||||
create_menu_help
|
||||
# Fill in the other menus at runtime.
|
||||
|
||||
# .io communicates text with the user,
|
||||
# through an input and output window.
|
||||
frame .io
|
||||
frame .io.inp
|
||||
frame .io.out
|
||||
# .controls will hold the play button and
|
||||
# the effects controls.
|
||||
frame .controls
|
||||
|
||||
# Draw the controls in .io
|
||||
label .io.inp.input_label -text "Input Area" -font ClientFont
|
||||
text .io.inp.input_area -height 10 -width 40 \
|
||||
-xscrollcommand ".io.inp.input_x set" \
|
||||
-yscrollcommand ".io.inp.input_y set" -font ClientFont
|
||||
scrollbar .io.inp.input_x -orient horizontal \
|
||||
-command ".io.inp.input_area xview"
|
||||
scrollbar .io.inp.input_y -orient vertical \
|
||||
-command ".io.inp.input_area yview"
|
||||
|
||||
label .io.out.output_label -text "Output Area" -font ClientFont
|
||||
text .io.out.output_area -height 10 -width 40 -state disabled \
|
||||
-xscrollcommand ".io.out.output_x set" \
|
||||
-yscrollcommand ".io.out.output_y set" -font ClientFont
|
||||
scrollbar .io.out.output_x -orient horizontal \
|
||||
-command ".io.out.output_area xview"
|
||||
scrollbar .io.out.output_y -orient vertical \
|
||||
-command ".io.out.output_area yview"
|
||||
|
||||
grid .io.inp -in .io -row 1 -column 1
|
||||
grid .io.out -in .io -row 1 -column 2
|
||||
grid .io.inp.input_label -in .io.inp -row 1 -column 1
|
||||
grid .io.inp.input_area -in .io.inp -row 2 -column 1
|
||||
grid .io.inp.input_y -in .io.inp -row 2 -column 2 -sticky ns
|
||||
grid .io.inp.input_x -in .io.inp -row 3 -column 1 -sticky ew
|
||||
|
||||
grid .io.out.output_label -in .io.out -row 1 -column 1
|
||||
grid .io.out.output_area -in .io.out -row 2 -column 1
|
||||
grid .io.out.output_y -in .io.out -row 2 -column 2 -sticky ns
|
||||
grid .io.out.output_x -in .io.out -row 3 -column 1 -sticky ew
|
||||
|
||||
button .controls.play -text "play" -font ClientFont -command {
|
||||
generate_output [get_input_text]
|
||||
}
|
||||
grid .controls.play -in .controls -row 1 -column 1
|
||||
|
||||
button .controls.save -text "save" -font ClientFont -command {
|
||||
global outputtype
|
||||
set input_text [get_input_text]
|
||||
if { $outputtype eq "AUDIO" } {
|
||||
save_binary_file [collect_audio_data $input_text ] "Save audio file"
|
||||
} else {
|
||||
save_text_file [collect_audio_data $input_text ] "Save output to file"
|
||||
}
|
||||
}
|
||||
|
||||
grid .controls.save -in .controls -row 1 -column 2
|
||||
|
||||
pack .menus .io .controls -in . -side top
|
||||
|
||||
|
||||
|
||||
# Detect whether this is the main program
|
||||
# This test was taken from the Tcl Wiki, and
|
||||
# seems to work OK.
|
||||
|
||||
if {[info exists argv0] && [file tail [info script]] eq [file tail $argv0]} {
|
||||
|
||||
# Try to find the temporary files directory.
|
||||
catch { set tmpdir "/tmp" }
|
||||
catch { set tmpdir $::env(TRASH_FOLDER) }
|
||||
catch { set tmpdir $::env(TMP) }
|
||||
catch { set tmpdir $::env(TEMP) }
|
||||
# <FIXME>This needs better handling of
|
||||
# possible alternatives</FIXME>
|
||||
# This is needed for Windows sound only.
|
||||
|
||||
# Do the platform dependent things.
|
||||
if {$tcl_platform(platform) eq "windows"} {
|
||||
package require twapi
|
||||
|
||||
proc play {sound} {
|
||||
global tmpdir
|
||||
# Write sound to a temporary file
|
||||
set sndfile [file join $tmpdir "MARYTTS_sound.[pid].wav" ]
|
||||
set stream [open $sndfile w]
|
||||
# Make sure the file is binary:
|
||||
fconfigure $stream -translation binary
|
||||
puts -nonewline $stream $sound
|
||||
close $stream
|
||||
# Play the file.
|
||||
::twapi::play_sound $sndfile
|
||||
# Remove the file.
|
||||
file delete $sndfile
|
||||
}
|
||||
}
|
||||
# Put other platforms here.
|
||||
|
||||
# Setup the globals with reference to the
|
||||
# server, which is assumed to be working.
|
||||
# Since we have options to alter this with
|
||||
# menu items, there probably needs to be
|
||||
# some way to reload all this. But we need
|
||||
# to know how to delete the existing menu
|
||||
# entries to do that.
|
||||
setup_globals
|
||||
create_radio_menu_from_list inputtype
|
||||
create_radio_menu_from_list outputtype
|
||||
create_radio_menu_from_list voice
|
||||
create_radio_menu_from_list audioformat
|
||||
|
||||
# Note, at the moment voices holds locales,
|
||||
# gender, and voice type
|
||||
|
||||
# At the moment this is just diagnostic:
|
||||
## add_message [ join $voices "\n" ]
|
||||
# it tells us we have a basically working
|
||||
# system and the list of voices has been
|
||||
# picked up and manipulated correctly.
|
||||
# So it is commented out now.
|
||||
}
|
||||
|
||||
|
||||
81
external/marytts-5.1.2/doc/examples/client/texttospeechdemo.html
vendored
Normal file
81
external/marytts-5.1.2/doc/examples/client/texttospeechdemo.html
vendored
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
<html>
|
||||
<!--
|
||||
Copyright 2000-2006 DFKI GmbH.
|
||||
All Rights Reserved. Use is subject to license terms.
|
||||
|
||||
Permission is hereby granted, free of charge, to use and distribute
|
||||
this software and its documentation without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of this work, and to
|
||||
permit persons to whom this work is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
1. The code must retain the above copyright notice, this list of
|
||||
conditions and the following disclaimer.
|
||||
2. Any modifications must be clearly marked as such.
|
||||
3. Original authors' names are not deleted.
|
||||
4. The authors' names are not used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
DFKI GMBH AND THE CONTRIBUTORS TO THIS WORK DISCLAIM ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DFKI GMBH NOR THE
|
||||
CONTRIBUTORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||
THIS SOFTWARE.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||
<link rel=stylesheet type="text/css" href="mary.css">
|
||||
<script type="text/javascript">
|
||||
</head>
|
||||
<body>
|
||||
<h1 align="center">The MARY Text-to-Speech System: Online Demo</h1>
|
||||
<div align="center">
|
||||
<p>Synthesise any text online (max. 5000 characters):
|
||||
</p>
|
||||
<form name="InputForm" method="get" action="maryclient.cgi">
|
||||
<!-- Set the language of your input here: TEXT_DE=German, TEXT_EN=English... -->
|
||||
<input type="hidden" name="in" value="TEXT"/>
|
||||
<input type="hidden" name="out" value="AUDIO"/>
|
||||
<p>Input text:</p>
|
||||
<textarea name="inputtext" rows=8 cols=50 wrap=virtual>
|
||||
Welcome to the world of speech synthesis!
|
||||
</textarea><br>
|
||||
<table align="center">
|
||||
<tr>
|
||||
<td>
|
||||
Voice:
|
||||
<select name="voice">
|
||||
<option value="us1">us1 (American English, female)</option>
|
||||
<option value="us2">us2 (American English, male)</option>
|
||||
</select>
|
||||
</td><td>
|
||||
Audio format:
|
||||
<select name="audiotype">
|
||||
<option value="AU">Sun Audio, 16 bit</option>
|
||||
<option value="AIFF">AIFF, 16 bit</option>
|
||||
<option value="WAVE" selected>WAV, 16 bit</option>
|
||||
<option value="MP3">mp3</option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">
|
||||
<input type=submit value="Speak">
|
||||
</td><td align="left">
|
||||
<input type=reset value="Reset">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p>
|
||||
<input type=radio name="save_to_disk" value="0" checked>Hear directly
|
||||
|
||||
<input type=radio name="save_to_disk" value="1">Save to disk
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue