123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- # -*- coding: utf-8 -*-
- from __future__ import division
- from .__load__ import *
- from .snowboy import snowboydecoder
- # 耳朵,聆听者
- class Ear(object):
- def init(self, robot):
- # vecan机器人
- self.robot = robot
- # 勿扰模式控制 勿扰模式关闭
- self.bother = False
- # snowboy detector
- self.detector = None
- # 中断控制
- self.interrupted = False
- return self
- # 语音唤醒模式
- def wait(self):
- self.robot.logger.info(self.log('唤醒模式:喊我名字叫醒我吧,我听着呢'))
- if self.detector is not None:
- self.detector.terminate()
- self.getConfig()
- self.detector = snowboydecoder.HotwordDetector(self.config['models'], sensitivity=self.config['sensitivity'], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'],robot=self.robot)
- # main loop
- #try:
- self.detector.start(detected_callback=self.config['callbacks'],
- audio_recorder_callback=self.recorderCallback,
- interrupt_check=self.interruptCallback,
- silent_count_threshold=int(self.config['silent_threshold']),
- recording_timeout=int(self.config['recording_timeout']) * 4,
- sleep_time=0.03)
- self.detector.terminate()
- #except Exception as e:
- #self.robot.logger.critical(self.log('离线唤醒机制初始化失败:{}'.format(e)))
- # listen
- def listen(self, silent=False):
- self.robot.logger.info(self.log('聆听模式:和我直接对话吧'))
- try:
- if not silent:
- time.sleep(1)
- self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
- listener = snowboydecoder.ActiveListener([self.robot.data + self.config['hotword']], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'])
- voice = listener.listen(
- silent_count_threshold=int(self.config['silent_threshold']),
- recording_timeout=int(self.config['recording_timeout']) * 4
- )
- if not silent:
- self.robot.mouth.speek(self.robot.data + 'beep_lo.wav')
- if voice:
- query = self.robot.tool['asr'].asr(voice)
- File.remove(voice)
- return query
- except Exception as e:
- Demeter.logger.error(e)
- return ''
- # snowboy配置,后续改成从数据库读取
- def getConfig(self):
- self.config = Demeter.config['snowboy']
- if self.config['hotword_switch'] == True:
- self.config['models'] = [
- self.robot.data + self.config['hotword'],
- self.robot.data + self.config['on_hotword'],
- self.robot.data + self.config['off_hotword']
- ]
- self.config['callbacks'] = [
- self.detectedCallback,
- self.onHotwordCallback,
- self.offHotwordCallback
- ]
- else:
- self.config['models'] = self.robot.data + self.config['hotword']
- self.config['callbacks'] = self.detectedCallback
- # close
- def close(self):
- self.interrupted = True
- # callback
- def detectedCallback(self):
- if not self.isProperTime():
- self.robot.logger.warning(self.log('勿扰模式开启中'))
- return
- if self.robot.isRecording:
- self.robot.logger.warning(self.log('正在录音中,跳过'))
- return
- self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
- self.robot.logger.info(self.log('开始录音'))
- self.robot.stop()
- self.robot.isRecording = True
- def recorderCallback(self, fp, callback=None):
- self.robot.mouth.speek(self.robot.data + 'beep_lo.wav')
- self.robot.logger.info(self.log('结束录音'))
- self.robot.isRecording = False
- if self.robot.profiling:
- self.robot.logger.info(self.log('性能调试已打开'))
- pr = cProfile.Profile()
- pr.enable()
- self.recorder(fp, callback)
- pr.disable()
- s = io.StringIO()
- sortby = 'cumulative'
- ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
- ps.print_stats()
- print(s.getvalue())
- else:
- self.recorder(fp, callback)
- def recorder(self, fp, callback=None, onSay=None):
- try:
- self.robot.stop()
- query = self.robot.tool['asr'].asr(fp)
- File.remove(fp)
- self.robot.brain.think(query, callback, onSay)
- except Exception as e:
- self.robot.logger.critical(self.log(e))
- clean()
- def onHotwordCallback(self):
- if self.config['hotword_switch'] == True:
- self.bother = True
- self.robot.mouth.speek(self.robot.data + 'off.wav')
- self.robot.logger.info(self.log('勿扰模式打开'))
- def offHotwordCallback(self):
- if self.config['hotword_switch'] == True:
- self.bother = False
- self.robot.mouth.speek(self.robot.data + 'on.wav')
- self.robot.logger.info(self.log('勿扰模式关闭'))
- def interruptCallback(self):
- return self.interrupted
- def isProperTime(self):
- if self.bother == True:
- return False
- if 'bother_enable' not in self.config:
- return True
- if self.config['bother_enable'] == False:
- return True
- if 'bother_since' not in self.config or 'bother_till' not in self.config:
- return True
- since = int(self.config['bother_since'])
- till = int(self.config['bother_till'])
- current = time.localtime(time.time()).tm_hour
- if till > since:
- return current not in range(since, till)
- else:
- return not (current in range(since, 25) or
- current in range(-1, till))
- def log(self, text):
- return 'Ear:' + text
|