Go to the documentation of this file.00001
00002
00003
00004
00005 import os
00006 import sys
00007 import rospy
00008 import rospkg
00009 import datetime
00010 import platform
00011 from datetime import datetime as dt
00012
00013
00014 import std_msgs.msg
00015 from rospeex_msgs.msg import SignalProcessingResponse
00016 from rospeex_msgs.msg import SpeechSynthesisState
00017 from rospeex_msgs.msg import SignalProcessingStream
00018
00019
00020 from rospeex_core import logging_util
00021 from rospeex_core.spi.signal_processing_interface import ConnectorInterface
00022 from rospeex_core import exceptions as ext
00023
00024 logging_util.setup_logging(use_ros_logging=True)
00025
00026
00027 class SignalProcessingInterface(object):
00028 """ SignalProcessingInterface class """
00029
00030 _SPI_RESPONSE_TOPIC_NAME = 'spi_res'
00031 _SS_STATE_TOPIC_NAME = 'ss_state'
00032 _SPI_STREAM_TOPIC_NAME = 'spi_stream'
00033
00034 def __init__(self):
00035 """ init function """
00036 package = rospkg.RosPack()
00037 rospeex_dir = package.get_path('rospeex_core')
00038 self._connector = None
00039 self._ip_addr = '127.0.0.1'
00040 self._app_dir = os.path.join(rospeex_dir, 'bin')
00041 self._controller = 'NICTmmcvController'
00042 self._nict_mmcv = 'NICTmmcv'
00043 self._mmse_setting = 'NICTmmcv.mmse.ini'
00044 self._vad_setting = 'NICTmmcv.vad.ini'
00045 self._audio_dir = 'rospeex'
00046 self._recv_port = 5002
00047 self._send_port = 16001
00048 self._websocket_port = 9000
00049 self._vadoff_during_play = True
00050 self._request_id = 0
00051 self._stream_seq = 0
00052 self._log_level = 'warn'
00053 self._audio_monitor = None
00054 self._pub_spi = None
00055 self._pub_spi_stream = None
00056 self._ss_state_dict = {}
00057
00058 def _ss_state_response(self, response):
00059 """ receive speech synthesis node state
00060 @param response: response data
00061 @type response: str
00062 """
00063 rospy.loginfo(response)
00064
00065
00066 user = response.header.user
00067 if response.header.user not in self._ss_state_dict:
00068 self._ss_state_dict[user] = [0, dt.now()]
00069
00070
00071 if response.play_state is True:
00072 self._ss_state_dict[user][0] += 1
00073 else:
00074 self._ss_state_dict[user][0] -= 1
00075 self._ss_state_dict[user][1] = dt.now()
00076
00077
00078 state_list = [state[0] for state in self._ss_state_dict.values()]
00079 if self._vadoff_during_play:
00080 play_state = True if sum(state_list) > 0 else False
00081 else:
00082 play_state = False
00083 self._connector.set_play_sound_state(play_state)
00084
00085 def _ui_response(self, data):
00086 """ receive user interface response
00087 @param data: voice data
00088 @type data: str
00089 """
00090 msg = SignalProcessingResponse()
00091 msg.header.user = rospy.get_name()
00092 msg.header.request_id = str(self._request_id)
00093 msg.data = data
00094 self._pub_spi.publish(msg)
00095 self._request_id += 1
00096
00097 now = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
00098 filename = '%s.wav' % now
00099 filepath = os.path.join(self._audio_dir, filename)
00100 with open(filepath, 'wb') as wavefile:
00101 wavefile.write(data)
00102
00103 def _stream_response(self, packet_type, packet_data):
00104 """ receive user interface response
00105
00106 @param data: voice data
00107 @type data: str
00108 """
00109 msg = SignalProcessingStream()
00110 msg.header = std_msgs.msg.Header()
00111 msg.header.stamp = rospy.Time.now()
00112 msg.packet_type = packet_type
00113 msg.packet_data = packet_data
00114 self._pub_spi_stream.publish(msg)
00115
00116 def _update_connection_parameter(self):
00117 """ update connection parameter """
00118 self._ip_addr = rospy.get_param(
00119 '~ip_addr',
00120 self._ip_addr
00121 )
00122 self._recv_port = rospy.get_param(
00123 '~recv_port',
00124 self._recv_port
00125 )
00126 self._send_port = rospy.get_param(
00127 '~send_port',
00128 self._send_port
00129 )
00130 self._log_level = rospy.get_param(
00131 '~log_level',
00132 self._log_level
00133 )
00134 self._websocket_port = rospy.get_param(
00135 '~websocket_port',
00136 self._websocket_port
00137 )
00138 self._audio_dir = rospy.get_param(
00139 '~audio_dir',
00140 self._audio_dir
00141 )
00142 self._vadoff_during_play = rospy.get_param(
00143 '~vadoff_during_play',
00144 self._vadoff_during_play
00145 )
00146 self._audio_monitor = None
00147
00148
00149 msg = 'parameter:\n'\
00150 '\tip_addr :{}\n'\
00151 '\trecv_port :{}\n'\
00152 '\tsend_port :{}\n'\
00153 '\twebsocket_port :{}\n'\
00154 '\tvadoff_during_play:{}'.format(
00155 self._ip_addr,
00156 self._recv_port,
00157 self._send_port,
00158 self._websocket_port,
00159 self._vadoff_during_play
00160 )
00161 rospy.loginfo(msg)
00162
00163 def _update_application_dir(self):
00164 """ update application directory. (32bit or 64bit) """
00165 arch = platform.architecture()
00166 try:
00167 if arch[0] == '32bit':
00168 self._app_dir = os.path.join(self._app_dir, 'x86')
00169 else:
00170 self._app_dir = os.path.join(self._app_dir, 'x64')
00171
00172 except IndexError:
00173 msg = 'platform.architecture() returns unexcepted value. '\
00174 'Value: {}'.format(str(arch))
00175 rospy.info(msg)
00176 self._app_dir = os.path.join(self._app_dir, 'x64')
00177
00178 def shutdown(self):
00179 """ shutdown speech processing interface """
00180 if self._connector:
00181 self._connector.join()
00182
00183 if self._audio_monitor:
00184 self._audio_monitor.exit()
00185
00186 def run(self):
00187 """ run application """
00188 rospy.init_node('rospeex_spi')
00189
00190
00191 self._pub_spi = rospy.Publisher(
00192 self._SPI_RESPONSE_TOPIC_NAME,
00193 SignalProcessingResponse,
00194 queue_size=10
00195 )
00196 self._pub_spi_stream = rospy.Publisher(
00197 self._SPI_STREAM_TOPIC_NAME,
00198 SignalProcessingStream,
00199 queue_size=100
00200 )
00201 rospy.Subscriber(
00202 self._SS_STATE_TOPIC_NAME,
00203 SpeechSynthesisState,
00204 self._ss_state_response
00205 )
00206
00207
00208 self._update_connection_parameter()
00209
00210
00211 self._update_application_dir()
00212
00213
00214 if not os.path.exists(self._audio_dir):
00215 os.makedirs(self._audio_dir)
00216
00217
00218 self._connector = ConnectorInterface(
00219 app_dir=self._app_dir,
00220 controller=self._controller,
00221 nict_mmcv=self._nict_mmcv,
00222 mmse_setting=self._mmse_setting,
00223 vad_setting=self._vad_setting,
00224 ip_addr=self._ip_addr,
00225 recv_port=self._recv_port,
00226 send_port=self._send_port,
00227 log_level=self._log_level
00228 )
00229
00230 self._connector.register_callback(self._ui_response)
00231 self._connector.register_stream_callback(self._stream_response)
00232 self._connector.start()
00233
00234
00235 rospy.loginfo('start signal processing interface node.')
00236 rate = rospy.Rate(100)
00237 while not rospy.is_shutdown():
00238 rate.sleep()
00239
00240
00241 def main():
00242 """ mian function """
00243 spi_node = None
00244
00245 try:
00246 spi_node = SignalProcessingInterface()
00247 spi_node.run()
00248
00249 except ext.SignalProcessingInterfaceException as err:
00250 rospy.logfatal(str(err))
00251
00252 except rospy.ROSInterruptException as err:
00253 rospy.loginfo(str(err))
00254
00255 except Exception as err:
00256 rospy.logfatal(str(err))
00257
00258 finally:
00259 if spi_node is not None:
00260 spi_node.shutdown()
00261 return 0
00262
00263
00264 if __name__ == '__main__':
00265 sys.exit(main())