ear.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from .__load__ import *
  4. from .snowboy import snowboydecoder
  5. # 耳朵,聆听者
  6. class Ear(object):
  7. def init(self, robot):
  8. # vecan机器人
  9. self.robot = robot
  10. # 勿扰模式控制 勿扰模式关闭
  11. self.bother = False
  12. # snowboy detector
  13. self.detector = None
  14. # 中断控制
  15. self.interrupted = False
  16. return self
  17. # 语音唤醒模式
  18. def wait(self):
  19. self.robot.logger.info(self.log('唤醒模式:喊我名字叫醒我吧,我听着呢'))
  20. if self.detector is not None:
  21. self.detector.terminate()
  22. self.getConfig()
  23. self.detector = snowboydecoder.HotwordDetector(self.config['models'], sensitivity=self.config['sensitivity'], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'])
  24. # main loop
  25. try:
  26. self.detector.start(detected_callback=self.config['callbacks'],
  27. audio_recorder_callback=self.robot.mouth.talk,
  28. interrupt_check=self.interruptCallback,
  29. silent_count_threshold=int(self.config['silent_threshold']),
  30. recording_timeout=int(self.config['recording_timeout']) * 4,
  31. sleep_time=0.03)
  32. self.detector.terminate()
  33. except Exception as e:
  34. self.robot.logger.critical(self.log('离线唤醒机制初始化失败:{}'.format(e)))
  35. # listen
  36. def listen(self, silent=False):
  37. self.robot.logger.info(self.log('聆听模式:和我直接对话吧'))
  38. try:
  39. if not silent:
  40. time.sleep(1)
  41. self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
  42. listener = snowboydecoder.ActiveListener([self.robot.data + self.config['hotword']], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'])
  43. voice = listener.listen(
  44. silent_count_threshold=int(self.config['silent_threshold']),
  45. recording_timeout=int(self.config['recording_timeout']) * 4
  46. )
  47. if not silent:
  48. self.robot.mouth.speek(self.robot.data + 'beep_lo.wav')
  49. if voice:
  50. query = self.robot.tool['asr'].asr(voice)
  51. Demeter.remove(voice)
  52. return query
  53. except Exception as e:
  54. Demeter.logger.error(e)
  55. return ''
  56. # snowboy配置,后续改成从数据库读取
  57. def getConfig(self):
  58. self.config = Demeter.config['snowboy']
  59. if self.config['hotword_switch'] == True:
  60. self.config['models'] = [
  61. self.robot.data + self.config['hotword'],
  62. self.robot.data + self.config['on_hotword'],
  63. self.robot.data + self.config['off_hotword']
  64. ]
  65. self.config['callbacks'] = [
  66. self.detectedCallback,
  67. self.onHotwordCallback,
  68. self.offHotwordCallback
  69. ]
  70. else:
  71. self.config['models'] = self.robot.data + self.config['hotword']
  72. self.config['callbacks'] = self.detectedCallback
  73. # close
  74. def close(self):
  75. self.interrupted = True
  76. # callback
  77. def detectedCallback(self):
  78. if not self.isProperTime():
  79. self.robot.logger.warning(self.log('勿扰模式开启中'))
  80. return
  81. if self.robot.isRecording:
  82. self.robot.logger.warning(self.log('正在录音中,跳过'))
  83. return
  84. self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
  85. self.robot.logger.info(self.log('开始录音'))
  86. self.robot.interrupt()
  87. self.robot.isRecording = True;
  88. def onHotwordCallback(self):
  89. if self.config['hotword_switch'] == True:
  90. self.bother = True
  91. self.robot.mouth.speek(self.robot.data + 'off.wav')
  92. self.robot.logger.info(self.log('勿扰模式打开'))
  93. def offHotwordCallback(self):
  94. if self.config['hotword_switch'] == True:
  95. self.bother = False
  96. self.robot.mouth.speek(self.robot.data + 'on.wav')
  97. self.robot.logger.info(self.log('勿扰模式关闭'))
  98. def interruptCallback(self):
  99. return self.interrupted
  100. def isProperTime(self):
  101. if self.bother == True:
  102. return False
  103. if 'bother_enable' not in self.config:
  104. return True
  105. if self.config['bother_enable'] == False:
  106. return True
  107. if 'bother_since' not in self.config or 'bother_till' not in self.config:
  108. return True
  109. since = self.config['bother_since']
  110. till = self.config['bother_till']
  111. current = time.localtime(time.time()).tm_hour
  112. if till > since:
  113. return current not in range(since, till)
  114. else:
  115. return not (current in range(since, 25) or
  116. current in range(-1, till))
  117. def log(self, text):
  118. return 'Ear:' + text