00001
00002
00003
00004 """Copyright (c) 2016 Xu Zhihao (Howe). All rights reserved.
00005 This program is free software; you can redistribute it and/or modify
00006 This programm is tested on kuboki base turtlebot."""
00007
00008 from pyaudio import PyAudio, paInt16
00009 import json
00010 import base64
00011 import os
00012 import sys
00013 import requests
00014 import wave
00015 import rospy
00016 import numpy as np
00017 import array
00018 import chunk
00019
00020
00021 class recoder():
00022
00023 def __init__(self):
00024 if_continue=''
00025 while not rospy.is_shutdown() and if_continue == '':
00026
00027 self.define()
00028
00029 self.recode()
00030
00031 self.reg()
00032
00033
00034
00035 if_continue = raw_input('pls input ENTER to continue')
00036
00037 def reg(self):
00038
00039
00040 requestData = { "grant_type": self.Grant_type,
00041 "client_id": self.Api_Key,
00042 "client_secret": self.Secrect_Key}
00043
00044 result = requests.post(url = self.Token_url, data = requestData)
00045
00046 token_data = json.loads(result.text)
00047
00048
00049
00050 if 'access_token' in token_data:
00051 token = token_data['access_token']
00052 rospy.loginfo('token success\n')
00053 else:
00054 rospy.loginfo('token failed\n')
00055
00056
00057
00058
00059 str_voice=self.conventor(self.Voice_String)
00060
00061 speech = base64.b64encode(str_voice)
00062
00063 size = len(str_voice)
00064
00065
00066 RegData = { "format": self.FORMAT,
00067 "rate": self.SAMPLING_RATE,
00068 "channel": self.nchannel,
00069 "cuid": self.USER_ID,
00070 "token": token,
00071 "len": size,
00072 "speech": speech,
00073 "lan": self.LAN}
00074
00075 HTTP_HEADER= { 'Content-Type': 'audio/%s;rate=%s'%(self.FORMAT,self.SAMPLING_RATE),
00076 'Content-length': len(json.dumps(RegData))}
00077
00078 r = requests.post(url = self.Reg_url, data = json.dumps(RegData, sort_keys=True), headers=HTTP_HEADER)
00079
00080
00081 rospy.loginfo( 'response')
00082 self.Print_Response(r.headers)
00083 result = json.loads(r.text)
00084 self.Print_Response(result)
00085 rospy.loginfo( 'result: %s \n'%result['err_msg'])
00086 rospy.loginfo( 'response\n')
00087
00088 if result[u'err_msg']=='success.':
00089 word = result['result'][0].encode('utf-8')
00090 if word!='':
00091 if word[len(word)-3:len(word)]==',':
00092 rospy.loginfo('cog. result: %s \n'%word[0:len(word)-3])
00093 return word[0:len(word)-3]
00094 else:
00095 rospy.loginfo(word)
00096 return word
00097 else:
00098 rospy.loginfo("音频文件不存在或格式错误\n")
00099 return '音频文件不存在或格式错误'
00100 else:
00101 rospy.loginfo(self.error_reason[result[u'err_no']])
00102 return self.error_reason[result[u'err_no']]
00103
00104 rospy.sleep(2)
00105
00106
00107 def define(self):
00108 self.error_reason={3300: '输入参数不正确',
00109 3301: '识别错误',
00110 3302: '验证失败',
00111 3303: '语音服务器后端问题',
00112 3304: '请求 GPS 过大,超过限额',
00113 3305: '产品线当前日请求数超过限额'}
00114
00115 if rospy.has_param('~REG_NUM_SAMPLES'):
00116 pass
00117 else:
00118 rospy.set_param('~REG_NUM_SAMPLES', 2000)
00119
00120 if rospy.has_param('~REG_SAMPLING_RATE'):
00121 pass
00122 else:
00123 rospy.set_param('~REG_SAMPLING_RATE', 8000)
00124
00125 if rospy.has_param('~REG_UPPER_LEVEL'):
00126 pass
00127 else:
00128 rospy.set_param('~REG_UPPER_LEVEL', 5000)
00129
00130 if rospy.has_param('~REG_LOWER_LEVEL'):
00131 pass
00132 else:
00133 rospy.set_param('~REG_LOWER_LEVEL', 500)
00134
00135 if rospy.has_param('~REG_COUNT_NUM'):
00136 pass
00137 else:
00138 rospy.set_param('~REG_COUNT_NUM', 20)
00139
00140 if rospy.has_param('~REG_SAVE_LENGTH'):
00141 pass
00142 else:
00143 rospy.set_param('~REG_SAVE_LENGTH', 8)
00144
00145 if rospy.has_param('~REG_TIME_OUT'):
00146 pass
00147 else:
00148 rospy.set_param('~REG_TIME_OUT', 60)
00149
00150 if rospy.has_param('~REG_NO_WORDS'):
00151 pass
00152 else:
00153 rospy.set_param('~REG_NO_WORDS', 6)
00154
00155 if rospy.has_param('~REG_Api_Key'):
00156 pass
00157 else:
00158 rospy.set_param('~REG_Api_Key', "pmUzrWcsA3Ce7RB5rSqsvQt2")
00159
00160 if rospy.has_param('~REG_Secrect_Key'):
00161 pass
00162 else:
00163 rospy.set_param('~REG_Secrect_Key', "d39ec848d016a8474c7c25e308b310c3")
00164
00165 if rospy.has_param('~REG_Grant_type'):
00166 pass
00167 else:
00168 rospy.set_param('~REG_Grant_type', "client_credentials")
00169
00170 if rospy.has_param('~REG_Token_url'):
00171 pass
00172 else:
00173 rospy.set_param('~REG_Token_url', "https://openapi.baidu.com/oauth/2.0/token")
00174
00175 if rospy.has_param('~REG_Reg_url'):
00176 pass
00177 else:
00178 rospy.set_param('~REG_Reg_url', "http://vop.baidu.com/server_api")
00179
00180 if rospy.has_param('~REG_USER_ID'):
00181 pass
00182 else:
00183 rospy.set_param('~REG_USER_ID', "8168466")
00184
00185 if rospy.has_param('~REG_FORMAT'):
00186 pass
00187 else:
00188 rospy.set_param('~REG_FORMAT', "wav")
00189
00190 if rospy.has_param('~REG_LAN'):
00191 pass
00192 else:
00193 rospy.set_param('~REG_LAN', "zh")
00194
00195 if rospy.has_param('~REG_nchannel'):
00196 pass
00197 else:
00198 rospy.set_param('~REG_nchannel', 1)
00199
00200
00201 self.NUM_SAMPLES = rospy.get_param('~REG_NUM_SAMPLES')
00202
00203
00204 self.SAMPLING_RATE = rospy.get_param('~REG_SAMPLING_RATE')
00205
00206
00207 self.UPPER_LEVEL = rospy.get_param('~REG_UPPER_LEVEL')
00208
00209
00210 self.LOWER_LEVEL = rospy.get_param('~REG_LOWER_LEVEL')
00211
00212
00213 self.COUNT_NUM = rospy.get_param('~REG_COUNT_NUM')
00214
00215
00216 self.SAVE_LENGTH = rospy.get_param('~REG_SAVE_LENGTH')
00217
00218
00219 self.TIME_OUT = rospy.get_param('~REG_TIME_OUT')
00220
00221
00222 self.NO_WORDS = rospy.get_param('~REG_NO_WORDS')
00223
00224
00225 self.Api_Key = rospy.get_param('~REG_Api_Key')
00226
00227
00228 self.Secrect_Key = rospy.get_param('~REG_Secrect_Key')
00229
00230
00231 self.Grant_type = rospy.get_param('~REG_Grant_type')
00232
00233
00234 self.Token_url = rospy.get_param('~REG_Token_url')
00235
00236
00237 self.Reg_url = rospy.get_param('~REG_Reg_url')
00238
00239
00240 self.USER_ID = rospy.get_param('~REG_USER_ID')
00241
00242
00243 self.FORMAT = rospy.get_param('~REG_FORMAT')
00244
00245
00246 self.LAN = rospy.get_param('~REG_LAN')
00247
00248
00249 self.nchannel = rospy.get_param('~REG_nchannel')
00250
00251
00252 self.Voice_String = []
00253
00254
00255
00256
00257
00258
00259 def Print_Response(self, data):
00260 for i in data:
00261 print ' ', i , ': ' , data[i]
00262
00263
00264 def recode(self):
00265 pa = PyAudio()
00266 stream = pa.open(format=paInt16, channels=self.nchannel, rate=self.SAMPLING_RATE, input=True, frames_per_buffer=self.NUM_SAMPLES)
00267 save_count = 0
00268 save_buffer = []
00269 time_out = self.TIME_OUT
00270 NO_WORDS=self.NO_WORDS
00271
00272 while True and NO_WORDS:
00273 time_out -= 1
00274 print 'time_out in', time_out
00275 string_audio_data = stream.read(self.NUM_SAMPLES)
00276 audio_data = np.fromstring(string_audio_data, dtype=np.short)
00277
00278
00279 NO_WORDS -= 1
00280 if np.max(audio_data) > self.UPPER_LEVEL:
00281 NO_WORDS=self.NO_WORDS
00282 print 'self.NO_WORDS ', NO_WORDS
00283 print 'np.max(audio_data) ', np.max(audio_data)
00284
00285
00286 large_sample_count = np.sum( audio_data > self.LOWER_LEVEL )
00287
00288
00289 if large_sample_count > self.COUNT_NUM:
00290 save_count = self.SAVE_LENGTH
00291 else:
00292 save_count -= 1
00293
00294
00295
00296 if save_count < 0:
00297 save_count = 0
00298 elif save_count > 0 :
00299 save_buffer.append( string_audio_data )
00300 else:
00301 pass
00302
00303
00304 if len(save_buffer) > 0 and NO_WORDS==0:
00305 self.Voice_String = save_buffer
00306 save_buffer = []
00307 rospy.loginfo( "Recode a piece of voice successfully!")
00308
00309
00310 elif len(save_buffer) > 0 and time_out==0:
00311 self.Voice_String = save_buffer
00312 save_buffer = []
00313 rospy.loginfo( "Recode a piece of voice successfully!")
00314
00315 else:
00316 pass
00317
00318
00319
00320 def conventor(self, Data_to_String):
00321 Voice_data=str()
00322 for Data in Data_to_String:
00323 Voice_data_h=array.array('b',Data)
00324
00325 Voice_data_h.byteswap()
00326
00327 Voice_data_s=Voice_data_h.tostring()
00328 Voice_data+=Voice_data_s
00329 return Voice_data
00330
00331 def print_data_len(self,data):
00332 print len(data)
00333 n=0
00334 for i in data:
00335 n+=1
00336 print n
00337
00338
00339
00340
00341
00342 def savewav(self,filename):
00343 rospy.loginfo('存储音频')
00344 file_path='/home/turtlebot/xu_slam/src/simple_voice/src'
00345 WAVE_FILE = '%s/%s.wav'%(file_path,filename)
00346 wf = wave.open(WAVE_FILE, 'wb')
00347 wf.setnchannels(1)
00348 wf.setsampwidth(2)
00349 wf.setframerate(self.SAMPLING_RATE)
00350 wf.writeframes("".join(self.Voice_String))
00351 wf.close()
00352 rospy.loginfo('音频数据已存')
00353
00354 if __name__=="__main__":
00355 rospy.init_node('simple_voice')
00356 rospy.loginfo("initialization system")
00357 recoder()
00358 rospy.loginfo("process done and quit")