def listen(self): client = Wit(self.wit_token) if self.voice: with speech_recognition.Microphone() as source: self.logger.debug("Słucham!") audio = self.rec.listen(source) self.logger.debug("Myślę...") with open(path.join('local', 'mic-results.wav'), 'wb') as f: f.write(audio.get_wav_data()) with open(path.join('local', 'mic-results.wav'), 'rb') as f: try: rtr = client.post_speech(f) except exceptions.BadRequestError: return None, None, None else: self.logger.debug("Czytam!") message = input('>>') self.logger.debug("Myślę...") rtr = client.get_message(message) # print('---') # print(rtr) # print('---') text = rtr['_text'] intent, entities = self.get_wit_intent(rtr, text) # print(text, '->', intent) # print('---') # print(entities) # print('---') return text, intent, entities
def event_loop(): wit = Wit(wit_token()) my_mic = Mic(DEFAULT_DICT, DEFAULT_LANG, DEFAULT_DICT, DEFAULT_LANG) while True: # listen for activation hotword try: threshold, text = my_mic.passiveListen(PERSONA) except: continue # detected hotword if threshold: audio_file = activeListenFile(threshold) if audio_file: data = None try: # retrieve wit intent data = wit.post_speech(open(audio_file)) # send to handler service raise NotImplementedError('no handler code yet') except Exception as e: print "Exception in audio_file handling:" print str(e) if data: print "Data: " print pprint(data)
def DecodeWaveFile(self, waveFileName): """Build a speech decode request around Wit""" # Form a query for Wit speech recognition w = Wit(self.witToken) try: audio = open(waveFileName) return WitAiQueryResponse(w.post_speech(audio)) except: raise
class Recorder(threading.Thread): def __init__(self, lisa_client, listener): # Init thread class threading.Thread.__init__(self) self._stopevent = threading.Event() self.lisa_client = lisa_client self.configuration = ConfigManagerSingleton.get().getConfiguration() self.pipeline = listener.get_pipeline() self.capture_buffers = deque([]) self.running_state = False self.wit = Wit(self.configuration['wit_token']) self.wit_confidence = 0.5 if self.configuration.has_key('confidence'): self.wit_confidence = self.configuration['wit_confidence'] self.record_time_start = 0 self.record_time_end = 0 # Get app sink self.rec_sink = self.pipeline.get_by_name('rec_sink') self.rec_sink.connect('new-buffer', self._capture_audio_buffer) # Configure vader # Using vader on pocketsphinx branch and not a vader on record branch, # because vader forces stream to 8KHz, so record quality would be worst vader = self.pipeline.get_by_name('vad_asr') vader.connect('vader-start', self._vader_start) vader.connect('vader-stop', self._vader_stop) # Get elements to connect/disconnect pockesphinx during record self.asr_tee = self.pipeline.get_by_name('asr_tee') self.asr_sink = self.pipeline.get_by_name('asr_sink') self.asr = self.pipeline.get_by_name('asr') self.asr_tee.unlink(self.asr_sink) # Start thread self.start() def stop(self): # Raise stop event self.running_state = False self._stopevent.set() def get_running_state(self): """ Is the recorder recording? """ return self.running_state def set_running_state(self, running): """ Start/Stop a voice record """ if running == True and self.running_state == False: self.running_state = True # Disconnect pocketsphinx from pipeline self.asr_tee.link(self.asr_sink) self.asr_tee.unlink(self.asr) elif running == True and self.running_state == True: self.running_state = False def run(self): """ Recorder main loop """ CONTENT_TYPE = 'audio/mpeg3' result = "" retry = 1 # Thread loop while not self._stopevent.isSet(): # Wait record order if self.running_state == False: sleep(.1) continue # Activate capture, wait for 2s of silence before cancelling wit_e = None self.record_time_start = 0 self.record_time_end = time.time() + 2 self.capture_buffers.clear() result = "" print '\n [Recording]' + ' ' * 20 + '[Recording]' # Send captured voice to wit try: result = self.wit.post_speech(data = self._read_audio_buffer(), content_type=CONTENT_TYPE) except Exception as e: wit_e = e # If record was stopped during recording if self.running_state == True: # If Wit did not succeeded if len(result) == 0 or result.has_key('outcome') == False or result['outcome'].has_key('confidence') == False or result['outcome']['confidence'] < self.wit_confidence: if wit_e is not None: log.err("Wit exception : " + str(e)) # If retry is available and vader detected an utterance if self.record_time_start != 0 and retry > 0: Speaker.speak('please_repeat') # Decrement retries retry = retry - 1 continue # No more retry Speaker.speak('not_understood') # Send recognized intent to the server else: self.lisa_client.sendMessage(message=result['msg_body'], type='chat', dict=result['outcome']) # Reset running state self.running_state = False retry = 1 # Reconnect pocketsphinx to pipeline print "" print "> Ready Recognize Voice" self.asr_tee.link(self.asr) self.asr_tee.unlink(self.asr_sink) def _vader_start(self, ob, message): """ Vader start detection """ # Reset max recording time if self.running_state == True: if self.record_time_start == 0: self.record_time_start = time.time() self.record_time_end = self.record_time_start + 10 def _vader_stop(self, ob, message): """ Vader stop detection """ # Stop recording if no new sentence in next 2s if self.running_state == True: if self.record_time_start != 0 and self.record_time_end > time.time() + 2: self.record_time_end = time.time() + 2 def _capture_audio_buffer(self, app): """ Gstreamer pipeline callback : Audio buffer capture """ # Get buffer Buffer = self.rec_sink.emit('pull-buffer') # If recording is running if self.running_state == True: # Add buffer to queue self.capture_buffers.append(Buffer) def _read_audio_buffer(self): """ Read buffers from capture queue """ last_progress = -1 # While recording is running while time.time() < self.record_time_end: # If there is a captured buffer if len(self.capture_buffers) > 0: data = self.capture_buffers.popleft() yield data else: # Wait another buffer sleep(.05) # Print progression if self.record_time_start != 0: progress = (int)(2 * (time.time() - self.record_time_start)) + 1 else: progress = 0 if last_progress != progress: last_progress = progress print '\x1b[1A', print '[Recording]' + '.' * progress + ' ' * (20 - progress) + '[Recording]'
# Standard Modules import sys import os # Modules from the GitHub from wit import Wit # The chunks from recorder import Recorder from interpreter import Interpreter # Constants SECONDS = 4 if __name__ == '__main__': # Set the Wit.AI token from an environment variable if 'WIT_TOKEN' not in os.environ: os.environ['WIT_TOKEN'] = raw_input("Enter your Wit.AI token: ") witToken = os.environ['WIT_TOKEN'] # Instantiate the chunks aRecording = Recorder(SECONDS) anInterpreting = Interpreter() witty = Wit(witToken) # Run with it audio_file = aRecording.record() result = witty.post_speech(audio_file.getvalue()) anInterpreting.interpret(result) # And we're done sys.exit(0)
class Recorder(threading.Thread): """ Continuous recording class. """ #----------------------------------------------------------------------------- def __init__(self, factory): # Init thread class threading.Thread.__init__(self) self._stopevent = threading.Event() self.running_state = False self.rec_sink = None self.factory = factory self.configuration = ConfigManager.getConfiguration() self.wit = Wit(self.configuration['wit_token']) self.wit_context = None self.record = {'activated' : False, 'start' : 0, 'started' : False, 'end' : 0, 'ended' : False, 'buffers' : deque({})} self.continuous_mode = False self.temp_file = "/tmp/asr_sound" # Start thread threading.Thread.start(self) #----------------------------------------------------------------------------- def setRunningState(self, state, rec_sink = None): self.running_state = state # Get app sink if rec_sink is not None and self.rec_sink is not rec_sink: self.rec_sink = rec_sink self.rec_sink.connect('new-buffer', self._captureAudioBuffer) #----------------------------------------------------------------------------- def stop(self): # Raise stop event self._stopevent.set() #----------------------------------------------------------------------------- def activate(self): """ Called to activate current utter as a record """ # Activate record if self.record['started'] == True: self.record['activated'] = True #----------------------------------------------------------------------------- def setContinuousMode(self, enabled, wit_context = None): """ Called to activate continous record mode """ # Activate record self.continuous_mode = enabled self.wit_context = wit_context #----------------------------------------------------------------------------- def run(self): """ Recorder main loop """ # Encoded format CONTENT_TYPE = 'audio/mpeg3' # Thread loop while not self._stopevent.isSet(): # Test if record is ended if self.record['started'] == True and self.record['ended'] == False and self.record['end'] <= time(): # If current record was not activated before end if self.record['activated'] == False and self.continuous_mode == False: self.record['start'] = 0 self.record['started'] = False self.record['end'] = 0 self.record['ended'] = False self.record['activated'] = False continue # Current record is activated and already ended self.record['ended'] = True # If current record is not activated if self.running_state == False or self.record['started'] == False or (self.record['activated'] == False and self.continuous_mode == False): sleep(.1) continue # Send activated record to Wit wit_e = None result = "" try: if self.configuration['asr'] == "ispeech": for b in self._readAudioBuffer(file_mode = True): pass params= {} params["action"] = "recognize" params["apikey"] = "developerdemokeydeveloperdemokey" params["freeform"] = "3" params["locale"] = "fr-FR" params["output"] = "json" params["content-type"] = "speex" params["speexmode"] = "2" params["audio"] = base64.b64encode(open(self.temp_file, 'rt').read()).replace(b'\n',b'') result = requests.get("http://api.ispeech.org/api/rest?" + urlencode(params)) result = self.wit.get_message(query = result.json()['text'], context = self.wit_context) elif self.configuration['asr'] == "google": for b in self._readAudioBuffer(file_mode = True): pass url = 'https://www.google.com/speech-api/v2/recognize?output=json&lang=fr-fr&key=AIzaSyCQv4U1mTaw_r_j1bWb1peeaTihzV0q-EQ' audio = open(self.temp_file, "rb").read() header = {"Content-Type": "audio/x-flac; rate=16000"} post = urlopen(Request(url, audio, header)) result = loads(post.read().split("\n")[1])['result'][0]['alternative'][0]['transcript'] result = self.wit.get_message(query = result, context = self.wit_context) # Defautl Wit else: result = self.wit.post_speech(data = self._readAudioBuffer(), content_type = CONTENT_TYPE, context = self.wit_context) result['msg_body'] = result['msg_body'].encode("utf-8") except Exception as e: wit_e = e # If record was stopped during Wit access if self._stopevent.isSet(): break # Question mode if len(result) > 0 and self.continuous_mode == True and result.has_key('msg_body') == True and len(result['msg_body']) > 0: # Send answer self.factory.sendChatToServer(message = result['msg_body'], outcome = result['outcome']) # If Wit did not succeeded elif len(result) == 0 or result.has_key('outcome') == False or result['outcome'].has_key('confidence') == False or result['outcome']['confidence'] < self.configuration['wit_confidence']: if wit_e is not None: log.err("Wit exception : {0}".format(str(e))) elif len(result) == 0: log.err("No response from Wit") elif result.has_key('outcome') == False or result['outcome'].has_key('confidence') == False: log.err("Wit response syntax error") log.err("result : {0}".format(result)) elif result['outcome']['confidence'] < self.configuration['wit_confidence']: log.err("Wit confidence {confidence} too low : {result}".format(confidence = result['outcome']['confidence'], result = result['msg_body'])) else: log.err("Error response from Wit : {0}".format(result['msg_body'])) # Send recognized intent to the server else: log.msg("Wit result : {0}".format(result['msg_body'])) self.factory.sendChatToServer(message = result['msg_body'], outcome = result['outcome']) # Finish current record self.record['start'] = 0 self.record['started'] = False self.record['end'] = 0 self.record['ended'] = False self.record['activated'] = False self.record['buffers'].clear() #----------------------------------------------------------------------------- def vaderStart(self): """ Vader start detection """ # If record is running if self.record['ended'] == False: # New start if self.record['started'] == False: self.record['started'] = True self.record['start'] = time() # Reset max recording time self.record['end'] = self.record['start'] + MAX_RECORD_DURATION_s #----------------------------------------------------------------------------- def vaderStop(self): """ Vader stop detection """ # If record is running if self.record['ended'] == False and self.record['end'] > time() + MAX_SILENCE_s: # End recording when no new activity during next silence self.record['end'] = time() + MAX_SILENCE_s #----------------------------------------------------------------------------- def _captureAudioBuffer(self, app): """ Gstreamer pipeline callback : Audio buffer capture """ # Get buffer buf = self.rec_sink.emit('pull-buffer') # If record is running if self.record['started'] == True and self.record['ended'] == False: cur_time = time() # Add buffer to queue self.record['buffers'].append({'time' : cur_time, 'data' : buf}) # Delete too old buffers when utter is not activated if self.record['activated'] == False and self.continuous_mode == False: while self.record['buffers'][0]['time'] + MAX_TIME_BEFORE_KWS_s < cur_time: self.record['buffers'].popleft() #----------------------------------------------------------------------------- def _readAudioBuffer(self, file_mode = False): """ Read buffers from capture queue """ # Check current record if self.record['activated'] == False and self.continuous_mode == False: return f = None if file_mode == True: f = open(self.temp_file, "wb") # While recording is running log.msg("Wit send start") while not self._stopevent.isSet(): # Test if record is ended if self.record['ended'] == False and self.record['end'] <= time(): self.record['ended'] = True # If there is no captured buffer if len(self.record['buffers']) == 0: # No more buffer when record is ended, it's over if self.record['ended'] == True: break # Record is live, wait another buffer sleep(.05) continue # Read buffer buf = None while len(self.record['buffers']) > 0 and (buf is None or len(buf) + len(self.record['buffers'][0]['data']) < 1200): data = self.record['buffers'].popleft() if buf is None: buf = data['data'] else: buf = buf.merge(data['data']) if file_mode == True: f.write(buf) yield buf if file_mode == True: f.close() log.msg("Wit send end")