Example #1
0
 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
Example #2
0
File: main.py Project: justjake/ear
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
Example #4
0
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]'
Example #5
0
# 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)
Example #6
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")