ear.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. print(22)
  21. import pyaudio
  22. pa = pyaudio.PyAudio()
  23. #print(pa.get_device_count())
  24. return
  25. if self.detector is not None:
  26. self.detector.terminate()
  27. self.getConfig()
  28. self.detector = snowboydecoder.HotwordDetector(self.config['models'], sensitivity=self.config['sensitivity'], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'])
  29. # main loop
  30. try:
  31. self.detector.start(detected_callback=self.config['callbacks'],
  32. audio_recorder_callback=self.robot.mouth.talk,
  33. interrupt_check=self.interruptCallback,
  34. silent_count_threshold=int(self.config['silent_threshold']),
  35. recording_timeout=int(self.config['recording_timeout']) * 4,
  36. sleep_time=0.03)
  37. self.detector.terminate()
  38. except Exception as e:
  39. self.robot.logger.critical(self.log('离线唤醒机制初始化失败:{}'.format(e)))
  40. # listen
  41. def listen(self, silent=False):
  42. self.robot.logger.info(self.log('聆听模式'))
  43. try:
  44. if not silent:
  45. time.sleep(1)
  46. self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
  47. listener = snowboydecoder.ActiveListener([self.robot.data + self.config['hotword']], outname=Demeter.config['vecan']['outname'], temp=Demeter.config['vecan']['temp'])
  48. voice = listener.listen(
  49. silent_count_threshold=int(self.config['silent_threshold']),
  50. recording_timeout=int(self.config['recording_timeout']) * 4
  51. )
  52. if not silent:
  53. self.robot.mouth.speek(self.robot.data + 'beep_lo.wav')
  54. if voice:
  55. query = self.robot.tool['asr'].asr(voice)
  56. Demeter.remove(voice)
  57. return query
  58. except Exception as e:
  59. Demeter.logger.error(e)
  60. return ''
  61. # snowboy配置,后续改成从数据库读取
  62. def getConfig(self):
  63. self.config = Demeter.config['snowboy']
  64. if self.config['hotword_switch'] == True:
  65. self.config['models'] = [
  66. self.robot.data + self.config['hotword'],
  67. self.robot.data + self.config['on_hotword'],
  68. self.robot.data + self.config['off_hotword']
  69. ]
  70. self.config['callbacks'] = [
  71. self.detectedCallback,
  72. self.onHotwordCallback,
  73. self.offHotwordCallback
  74. ]
  75. else:
  76. self.config['models'] = self.robot.data + self.config['hotword']
  77. self.config['callbacks'] = self.detectedCallback
  78. # close
  79. def close(self):
  80. self.interrupted = True
  81. # callback
  82. def detectedCallback(self):
  83. print(33)
  84. if not self.isProperTime():
  85. self.robot.logger.warning(self.log('勿扰模式开启中'))
  86. return
  87. if self.robot.isRecording:
  88. self.robot.logger.warning(self.log('正在录音中,跳过'))
  89. return
  90. self.robot.mouth.speek(self.robot.data + 'beep_hi.wav')
  91. self.robot.logger.info(self.log('开始录音'))
  92. self.robot.interrupt()
  93. self.robot.isRecording = True;
  94. def onHotwordCallback(self):
  95. if self.config['hotword_switch'] == True:
  96. self.bother = True
  97. self.robot.mouth.speek(self.robot.data + 'off.wav')
  98. self.robot.logger.info(self.log('勿扰模式打开'))
  99. def offHotwordCallback(self):
  100. if self.config['hotword_switch'] == True:
  101. self.bother = False
  102. self.robot.mouth.speek(self.robot.data + 'on.wav')
  103. self.robot.logger.info(self.log('勿扰模式关闭'))
  104. def interruptCallback(self):
  105. return self.interrupted
  106. def isProperTime(self):
  107. if self.bother == True:
  108. return False
  109. if 'bother_enable' not in self.config:
  110. return True
  111. if self.config['bother_enable'] == False:
  112. return True
  113. if 'bother_since' not in self.config or 'bother_till' not in self.config:
  114. return True
  115. since = self.config['bother_since']
  116. till = self.config['bother_till']
  117. current = time.localtime(time.time()).tm_hour
  118. if till > since:
  119. return current not in range(since, till)
  120. else:
  121. return not (current in range(since, 25) or
  122. current in range(-1, till))
  123. def log(self, text):
  124. return 'Ear:' + text