nict.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 
00003 import urllib2
00004 import json
00005 import base64
00006 import socket
00007 import traceback
00008 import logging
00009 
00010 
00011 # import library
00012 from rospeex_core.validators import accepts
00013 from rospeex_core.validators import check_language
00014 from rospeex_core import exceptions as ext
00015 from rospeex_core.ss.base import IClient
00016 
00017 
00018 logger = logging.getLogger(__name__)
00019 
00020 
00021 class Client(IClient):
00022     """ SpeechSynthesisCient_NICT class """
00023     URL = 'http://rospeex.nict.go.jp/nauth_json/jsServices/VoiceTraSS'
00024     FORMAT = 'x-wav'
00025     LANGUAGES = ['ja', 'en', 'zh', 'ko']
00026     VOICEFONT_DICT = {
00027         'ja': ['F128', 'F117', '*'],
00028         'en': ['EF007', '*'],
00029         'zh': ['CJF101', '*'],
00030         'ko': ['KF001', '*']
00031     }
00032 
00033     def __init__(self):
00034         """ initialize function """
00035         pass
00036 
00037     @accepts(message=basestring, language=str, voice_font=str, timeout=int)
00038     def request(
00039         self,
00040         message,
00041         language='ja',
00042         voice_font='*',
00043         timeout=socket._GLOBAL_DEFAULT_TIMEOUT
00044     ):
00045         """
00046         Send speech synthesis request to server,
00047         and get speech synthesis result.
00048         @param message: message
00049         @type  message: str
00050         @param language: speech synthesis language
00051         @type  language: str
00052         @param voice_font: taraget voice font
00053         @type  voice_font: str
00054         @param timeout: request timeout time (second)
00055         @type  timeout: float
00056         @return: voice data (wav format binary)
00057         @rtype: str
00058         @raise InvalidResponseException:
00059         @raise InvalidRequestException: send invalid request.
00060         @raise InvalidResponseException: server error.
00061         @raise RequestTimeoutException: timeout error.
00062         """
00063         check_language(language, self.LANGUAGES)
00064         self._check_voice_font(voice_font, language)
00065 
00066         # get tts data
00067         decorded_data = self._request_tts(
00068             message,
00069             language,
00070             voice_font,
00071             timeout
00072         )
00073 
00074         # check decorded data format
00075         ret_code = self._check_decorded_data(decorded_data)
00076 
00077         # check fault code
00078         voice = None
00079         if not ret_code:
00080             if decorded_data['error']['faultCode'] == 'Server.userException':
00081                 msg = 'the format is not supported.'
00082                 raise ext.InvalidResponseException(msg)
00083             msg = 'server response error. msg:%s' % decorded_data['error']
00084             raise ext.InvalidResponseException(msg)
00085         else:
00086             voice = base64.b64decode(decorded_data['result']['audio'])
00087         return voice
00088 
00089     def _check_voice_font(self, voice_font, language):
00090         """ check voice font
00091         @param voice_font:
00092         @type  voice_font:
00093         @param language:
00094         @type  language:
00095         @raise ParameterException
00096         """
00097         if voice_font not in self.VOICEFONT_DICT[language]:
00098             msg = 'invalid voice font [{voice_font}].'\
00099                   ' Expect: {voice_font_list}'.format(
00100                         voice_font=voice_font,
00101                         voice_font_list=str(self.VOICEFONT_DICT[language])
00102                     )
00103             raise ext.ParameterException(msg)
00104 
00105     def _check_decorded_data(self, decorded_data):
00106         """
00107         @param decorded_data:
00108         @type  decorded_data:
00109         @return: True to success / False to failture
00110         @rtype: bool
00111         @raise InvalidResponseException:
00112         """
00113         # result pattern
00114         if not decorded_data:
00115             msg = 'invalid server response. response has no data.'
00116             raise ext.InvalidResponseException(msg)
00117 
00118         ret_code = False
00119         if 'result' in decorded_data:
00120             if decorded_data['result'] is not None:
00121                 if 'audio' in decorded_data['result']:
00122                     ret_code = True
00123                 else:
00124                     msg = 'invalid server response.'\
00125                           ' response has no audio data.'
00126                     raise ext.InvalidResponseException(msg)
00127 
00128         # check error pattern
00129         if 'error' in decorded_data:
00130             if decorded_data['error'] is not None:
00131                 if 'faultCode' in decorded_data['error']:
00132                     ret_code = False
00133                 else:
00134                     msg = 'invalid server response. response has no faultcode.'
00135                     raise ext.InvalidResponseException(msg)
00136 
00137         return ret_code
00138 
00139     def _request_tts(self, message, language, voice_font, timeout):
00140         """
00141         request tts to NICT server
00142         @param message: message
00143         @type  message: str
00144         @param language: speech synthesis language
00145         @type  language: str
00146         @param voice_font: taraget voice font
00147         @type  voice_font: str
00148         @param timeout: request timeout time (second)
00149         @type  timeout: float
00150         @return: voice data (wav format binary)
00151         @rtype: str
00152         @raise InvalidRequestException: send invalid request.
00153         @raise InvalidResponseException: server error.
00154         @raise RequestTimeoutException: timeout error.
00155         """
00156         # create request data
00157         data = {
00158             'method': 'speak',
00159             'params': [
00160                 '1.1',
00161                 {
00162                     'language': language,
00163                     'text': message,
00164                     'voiceType': voice_font,
00165                     'audioType': 'audio/%s' % self.FORMAT,
00166                     'applicationType': 'rospeex'
00167                 }
00168             ]
00169         }
00170 
00171         # create request
00172         decorded_data = None
00173         request = urllib2.Request(self.URL)
00174         request.add_header('Content-Type', 'application/json')
00175 
00176         # get response
00177         try:
00178             response = urllib2.urlopen(
00179                 request,
00180                 json.dumps(data),
00181                 timeout=timeout
00182             )
00183             decorded_data = json.loads(response.read())
00184 
00185         except urllib2.URLError as err:
00186             if isinstance(err.reason, socket.timeout):
00187                 msg = 'request time out. Exception: %s' % str(err)
00188                 raise ext.RequestTimeoutException(msg)
00189 
00190             msg = 'request url error. Exception: %s' % str(err)
00191             raise ext.InvalidRequestException(msg)
00192 
00193         except urllib2.HTTPError as err:
00194             msg = 'http error. %s Exception:%s' % (err.code, err.msg)
00195             raise ext.InvalidResponseException(msg)
00196 
00197         except socket.timeout as err:
00198             msg = 'request time out. Exception: %s' % str(err)
00199             raise ext.RequestTimeoutException(msg)
00200 
00201         except:
00202             msg = 'unknown exception. Traceback: %s' % traceback.format_exc()
00203             raise ext.SpeechSynthesisException(msg)
00204 
00205         return decorded_data


rospeex_core
Author(s): Komei Sugiura
autogenerated on Thu Apr 20 2017 03:08:53