示例#1
0
class Listener():
    def __init__(self, model):
        self.inter = False
        self.chunk = 2048
        self.format = pyaudio.paInt16
        self.channels = 1
        self.rate = 16000
        self.threshold = 2500
        self.cooldown = 0.03
        self.sensitivity = float(os.environ.get('SENSITIVITY')) / 100
        self.listening = bool(os.environ.get('LISTENING'))
        self.ws_whisper = create_connection("ws://195.168.1.100:9001")
        self.detector = HotwordDetector(model, sensitivity=self.sensitivity)

    ##
    ## Checks to see if the mozilla things thread has had it's vars changed.
    ##
    def checkEnvironmentVariables(self):
        self.shellSource("/tmp/.assistant")
        if self.sensitivity != float(os.environ.get('SENSITIVITY')) / 100:
            self.sensitivity = float(os.environ.get('SENSITIVITY')) / 100
            self.detector.detector.SetSensitivity(str(self.sensitivity))
        self.listening = bool(os.environ.get('LISTENING'))
        print("DEBUG::" + str(self.sensitivity) + ", " + str(self.listening))

    def shellSource(self, script):
        """Sometime you want to emulate the action of "source" in bash,
        settings some environment variables. Here is a way to do it."""
        pipe = subprocess.Popen(". %s; env" % script,
                                stdout=subprocess.PIPE,
                                shell=True)
        output = pipe.communicate()[0]
        env = dict((line.split("=", 1) for line in output.splitlines()))
        os.environ.update(env)

    def start(self):
        print("Listener started and listening..")
        self.detector.start(detected_callback=self.transcribe,
                            sleep_time=self.cooldown)

    def stop(self):
        self.detector.terminate()
        #self.ws_whisper.close()
        print("Listener stopping, terminated..")

    ##
    ## Sends captured listengin audio to Whisper server for transcription.
    ##
    def transcribe(self):
        self.checkEnvironmentVariables()

        p = pyaudio.PyAudio()
        stream = p.open(format=self.format,
                        channels=self.channels,
                        rate=self.rate,
                        input=True,
                        frames_per_buffer=self.chunk)

        print("Starting Transcription..")
        if self.listening:
            subprocess.call([
                "aplay", "-q",
                "/home/pi/voice-assistant-client/sounds/ding.wav"
            ])

        # Testing pausing audio for transcription.
        os.system("/home/pi/./tv-volume.sh Down")
        self.ws_whisper.send("start")
        t_end = time.time() + 4
        while time.time() < t_end:
            self.ws_whisper.send_binary(stream.read(self.chunk))
        self.ws_whisper.send("stop")
        self.command_handler(self.ws_whisper.recv())
        p.terminate()
        os.system("/home/pi/./tv-volume.sh Up")

    ##
    ## Takes in a string of transcriptions from whisper, attempts to parse and act upon them.
    ##
    def command_handler(self, commands):
        c = commands.split(':')
        #print("DEBUG:" + commands)

        # Checking for way out there junk and false positives using a threshold out of 10k.
        if int(c[-1]) < -7000:
            print("INFO: I am not confident what you are talking about.")
            subprocess.call([
                "aplay", "-q",
                "/home/pi/voice-assistant-client/sounds/sound2.wav"
            ])

        else:
            print("INFO: I am confident I understood your commands.")
            # Disable and enable commands basically.
            if "AWAKE" in commands:
                self.listening = True
            elif "SLEEP" in commands or not self.listening:
                self.listening = False
            elif not self.listening:
                print("INFO: I head you but I am not listening")
                pass
            elif "CANCEL" in commands:
                pass

            #Buzz Off command puts Bijou to sleep for fifteen minutes.
            elif "BUZZ" in commands and "OFF" in commands:
                print("INFO: Going to sleep for fifteen minutes!")
                subprocess.call([
                    "aplay", "-q",
                    "/home/pi/voice-assistant-client/sounds/sound6.wav"
                ])
                time.sleep(890)
                print("INFO: Yawn~ Back to work.")

            # These statements make calls to smart lights, currently manual.
            elif "LIGHT" in commands:
                for value in c:
                    if value == "ONE" or value == "ONE(2)":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w25.local-things-led1 on"
                        )
                    elif value == "TWO" or value == "TO":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w25.local-things-led2 on"
                        )
                    elif value == "THREE":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w25.local-things-led3 on"
                        )
                    elif value == "FOUR":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w25.local-things-led4 on"
                        )
                    elif value == "FIVE":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w26.local-things-led5 on"
                        )
                    elif value == "SIX":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w26.local-things-led6 on"
                        )
                    elif value == "SEVEN":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w26.local-things-led7 on"
                        )
                    elif value == "EIGHT":
                        os.system(
                            "/home/pi/./toggle-property.sh http---w26.local-things-led8 on"
                        )

            # LG TV commands.
            elif "T_V" in commands:
                if "ON" in commands:
                    os.system(
                        "/home/pi/./set-property.sh lg-tv-38:8c:50:59:24:df on true"
                    )
                if "OFF" in commands:
                    os.system(
                        "/home/pi/./set-property.sh lg-tv-38:8c:50:59:24:df on false"
                    )
            elif "OPEN" in commands:
                if "NETFLIX" in commands:
                    os.system("/home/pi/./tv-application.sh Netflix")
                if "HULU" in commands:
                    os.system("/home/pi/./tv-application.sh Hulu")
                if "YOUTUBE" in commands:
                    os.system("/home/pi/./tv-application.sh YouTube")
                if "CHROMECAST" in commands:
                    os.system("/home/pi/./tv-application.sh HDMI1")
                if "XBOX" in commands:
                    os.system("/home/pi/./tv-application.sh HDMI3")
            elif "MUTE" in commands:
                os.system(
                    "/home/pi/./set-property.sh lg-tv-38:8c:50:59:24:df mute true"
                )
            elif "UNMUTE" in commands:
                os.system(
                    "/home/pi/./set-property.sh lg-tv-38:8c:50:59:24:df mute false"
                )
            elif "PAUSE" in commands:
                os.system("/home/pi/./tv-pause-play.sh Pause")
            elif "STOP" in commands:
                os.system("/home/pi/./tv-pause-play.sh Stop")
            elif "PLAY" in commands:
                if "MUSIC" in commands:
                    print("Not yet finished.. :(")
                else:
                    os.system("/home/pi/./tv-pause-play.sh Play")
            elif "VOLUME" in commands:
                if "UP" in commands:
                    os.system("/home/pi/./tv-volume.sh Up")
                else:
                    os.system("/home/pi/./tv-volume.sh Down")

            # Action completed sound.
            if self.listening:
                subprocess.call([
                    "aplay", "-q",
                    "/home/pi/voice-assistant-client/sounds/level_up.wav"
                ])
示例#2
0
文件: app.py 项目: soon14/ai-robot
import signal
from snowboydecoder import signal_handler, HotwordDetector
from config import RESOURCE_FILE, DETECT_DING, DETECT_DONG, MODELS, SENSITIVITY
from middleware import middleware
from music import music
from tuling import tuling

signal.signal(signal.SIGINT, signal_handler)
middleware.use(music)
middleware.use(tuling)


def processDetected(context):
    print('接收到指令:%s' % context)
    middleware.handle(context)


detector = HotwordDetector(model_str=MODELS,
                           resource_filename=RESOURCE_FILE,
                           sensitivity=SENSITIVITY)
detector.start(detected_callback=processDetected,
               ding_filename=DETECT_DING,
               dong_filename=DETECT_DONG)

detector.terminate()
示例#3
0
class Ownsnowboy(Thread):
    def __init__(self, **kwargs):
        super(Ownsnowboy, self).__init__()
        self._ignore_stderr()
        # pause listening boolean
        self.interrupted = False
        self.apply_frontend = kwargs.get('apply_frontend', False)

        # callback function to call when hotword caught
        self.callback = kwargs.get('callback', None)
        if self.callback is None:
            raise MissingParameterException(
                "callback function is required with snowboy")

        self.keywords = kwargs.get('keywords', None)
        keyword_file_paths = list()
        sensitivities = list()
        for keyword in self.keywords:
            path = Utils.get_real_file_path(keyword['keyword']['pmdl_path'])
            try:
                os.path.isfile(path)
            except TypeError:
                raise SnowboyModelNotFound(
                    "The Snowboy keyword at %s does not exist" %
                    keyword['keyword']['pmdl_path'])
            keyword_file_paths.append(path)
            try:
                for sens in keyword['keyword']['sensitivity']:
                    sensitivities.append(sens)
            except KeyError:
                sensitivities.append("0.5")

        self.detector = HotwordDetector(
            keyword_file_paths,
            sensitivity=sensitivities,
            detected_callback=self.callback,
            interrupt_check=self.interrupt_callback,
            apply_frontend=self.apply_frontend,
            sleep_time=0.01)

    def interrupt_callback(self):
        """
        This function will be passed to snowboy to stop the main thread
        :return:
        """
        return self.interrupted

    def run(self):
        """
        Start the snowboy thread and wait for a Kalliope trigger word
        :return:
        """
        # start snowboy loop forever
        self.detector.daemon = True
        self.detector.start()
        self.detector.join()

    def stop(self):
        """
        Kill the snowboy process
        :return: 
        """
        logger.debug("Killing snowboy process")
        self.interrupted = True
        self.detector.terminate()

    def pause(self):
        """
        pause the Snowboy main thread
        """
        logger.debug("Pausing snowboy process")
        self.detector.paused = True

    def unpause(self):
        """
        unpause the Snowboy main thread
        """
        logger.debug("Unpausing snowboy process")
        self.detector.paused = False

    @staticmethod
    def _ignore_stderr():
        """
        Try to forward PortAudio messages from stderr to /dev/null.
        """
        ffi = _FFI()
        ffi.cdef("""
            /* from stdio.h */
            FILE* fopen(const char* path, const char* mode);
            int fclose(FILE* fp);
            FILE* stderr;  /* GNU C library */
            FILE* __stderrp;  /* Mac OS X */
            """)
        stdio = ffi.dlopen(None)
        devnull = stdio.fopen(os.devnull.encode(), b'w')
        try:
            stdio.stderr = devnull
        except KeyError:
            try:
                stdio.__stderrp = devnull
            except KeyError:
                stdio.fclose(devnull)