snowboy.py 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. # -*- coding: utf-8 -*-
  2. from __future__ import division
  3. from .__load__ import *
  4. from snowboy import snowboydecoder
  5. class Snowboy(object):
  6. def init(self, robot):
  7. self.bother = False
  8. self.robot = robot
  9. self.detector = None
  10. self.interrupted = False
  11. self.data = File.runtime('data')
  12. if self.detector is not None:
  13. self.detector.terminate()
  14. # snowboy配置,后续改成从数据库读取
  15. snowboyConfig = Demeter.config['snowboy']
  16. if snowboyConfig['hotword_switch'] == True:
  17. models = [
  18. self.data + snowboyConfig['hotword'],
  19. self.data + snowboyConfig['on_hotword'],
  20. self.data + snowboyConfig['off_hotword']
  21. ]
  22. else:
  23. models = self.data + snowboyConfig['hotword']
  24. self.detector = snowboydecoder.HotwordDetector(models, sensitivity=snowboyConfig['sensitivity'])
  25. # main loop
  26. try:
  27. if snowboyConfig['hotword_switch'] == True:
  28. callbacks = [self.detectedCallback,
  29. self.onHotwordCallback,
  30. self.offHotwordCallback]
  31. else:
  32. callbacks = self.detectedCallback
  33. self.detector.start(detected_callback=callbacks,
  34. audio_recorder_callback=self.robot.converse,
  35. interrupt_check=self.interruptCallback,
  36. silent_count_threshold=int(snowboyConfig['silent_threshold']),
  37. recording_timeout=int(snowboyConfig['recording_timeout']) * 4,
  38. sleep_time=0.03)
  39. self.detector.terminate()
  40. except Exception as e:
  41. Demeter.logger.critical('离线唤醒机制初始化失败:{}'.format(e))
  42. def stop(self):
  43. self.interrupted = True
  44. def detectedCallback(self):
  45. if not self.isProperTime():
  46. Demeter.logger.warning('勿扰模式开启中')
  47. return
  48. if self.robot.isRecording:
  49. Demeter.logger.warning('正在录音中,跳过')
  50. return
  51. Player.play(self.data + 'beep_hi.wav')
  52. Demeter.logger.info('开始录音')
  53. self.robot.interrupt()
  54. self.robot.isRecording = True;
  55. def onHotwordCallback(self):
  56. if snowboyConfig['hotword_switch'] == True:
  57. self.bother = True
  58. Player.play(self.data + 'off.wav')
  59. Demeter.logger.info('勿扰模式打开')
  60. def offHotwordCallback(self):
  61. if snowboyConfig['hotword_switch'] == True:
  62. self.bother = False
  63. Player.play(self.data + 'on.wav')
  64. Demeter.logger.info('勿扰模式关闭')
  65. def interruptCallback(self):
  66. return self.interrupted
  67. def isProperTime():
  68. if self.bother == True:
  69. return False
  70. if 'bother_enable' not in Demeter.config['snowboy']:
  71. return True
  72. if Demeter.config['snowboy']['bother_enable'] == False:
  73. return True
  74. if 'bother_since' not in Demeter.config['snowboy'] or 'bother_till' not in Demeter.config['snowboy']:
  75. return True
  76. since = Demeter.config['snowboy']['bother_since']
  77. till = Demeter.config['snowboy']['bother_till']
  78. current = time.localtime(time.time()).tm_hour
  79. if till > since:
  80. return current not in range(since, till)
  81. else:
  82. return not (current in range(since, 25) or
  83. current in range(-1, till))