Refining new "listening" sound mechanism

This adds several refinements to the listening sound mechanism added by:
* Added a default sound file
* Allowing various ways to override "resource files" for customization
* Moved the sound configuration path from "confirm_ding" to
  "sounds" > "start_listening"
* Also added "sounds" > "end_listening" configuration for the future

This submission adds the new mycroft.util.resolve_resource_file(res_name)
method.  This method takes a name such as "snd/start_listening.wav" and
looks (in order):
* For an absolute path <res_name>
* For ~/.mycroft/<res_name>
* For /opt/mycroft/<res_name>
* For mycroft/res/<res_name> within the source package
pull/520/head
penrods 2017-02-09 01:37:22 -08:00 committed by Arron Atchison
parent 990dd27c5e
commit 5f8775883a
4 changed files with 61 additions and 11 deletions

View File

@ -27,11 +27,9 @@ from mycroft.identity import IdentityManager
from mycroft.messagebus.client.ws import WebsocketClient from mycroft.messagebus.client.ws import WebsocketClient
from mycroft.messagebus.message import Message from mycroft.messagebus.message import Message
from mycroft.tts import TTSFactory from mycroft.tts import TTSFactory
from mycroft.util import kill, play_wav from mycroft.util import kill, play_wav, resolve_resource_file
from mycroft.util.log import getLogger from mycroft.util.log import getLogger
from os.path import expanduser
logger = getLogger("SpeechClient") logger = getLogger("SpeechClient")
ws = None ws = None
tts = TTSFactory.create() tts = TTSFactory.create()
@ -44,10 +42,12 @@ config = ConfigurationManager.get()
def handle_record_begin(): def handle_record_begin():
logger.info("Begin Recording...") logger.info("Begin Recording...")
# If enabled, play a wave file with a short sound to indicate recording has # If enabled, play a wave file with a short sound to audibly
# begun. # indicate recording has begun.
if config.get('confirm_listening'): if config.get('confirm_listening'):
play_wav(expanduser(config.get('confirm_ding'))) file = resolve_resource_file(config.get('sounds').get('start_listening'))
if file:
play_wav(file)
ws.emit(Message('recognizer_loop:record_begin')) ws.emit(Message('recognizer_loop:record_begin'))
@ -105,6 +105,7 @@ def handle_speak(event):
else: else:
mute_and_speak(utterance) mute_and_speak(utterance)
def handle_sleep(event): def handle_sleep(event):
loop.sleep() loop.sleep()

View File

@ -3,8 +3,11 @@
"system_unit": "metric", "system_unit": "metric",
"time_format": "half", "time_format": "half",
"date_format": "MDY", "date_format": "MDY",
"confirm_listening": false, "confirm_listening": true,
"confirm_ding": "~/.mycroft/ding.wav", "sounds": {
"start_listening": "snd/start_listening.wav",
"end_listening": "snd/end_listening.wav"
},
"location": { "location": {
"city": { "city": {
"code": "Lawrence", "code": "Lawrence",

Binary file not shown.

View File

@ -28,6 +28,52 @@ from os.path import dirname
__author__ = 'jdorleans' __author__ = 'jdorleans'
def resolve_resource_file(res_name):
"""Convert a resource into an absolute filename.
Resource names are in the form: 'filename.ext'
or 'path/filename.ext'
The system wil look for ~/.mycroft/res_name first, and
if not found will look at /opt/mycroft/res_name,
then finally it will look for res_name in the 'mycroft/res'
folder of the source code package.
Example:
With mycroft running as the user 'bob', if you called
resolve_resource_file('snd/beep.wav')
it would return either '/home/bob/.mycroft/snd/beep.wav' or
'/opt/mycroft/snd/beep.wav' or '.../mycroft/res/snd/beep.wav',
where the '...' is replaced by the path where the package has
been installed.
Args:
res_name (str): a resource path/name
"""
# First look for fully qualified file (e.g. a user setting)
if os.path.isfile(res_name):
return res_name
# Now look for ~/.mycroft/res_name (in user folder)
filename = os.path.expanduser("~/.mycroft/"+res_name)
if os.path.isfile(filename):
return filename
# Next look for /opt/mycroft/res/res_name
filename = os.path.expanduser("/opt/mycroft/"+res_name)
if os.path.isfile(filename):
return filename
# Finally look for it in the source package
filename = dirname(os.path.abspath(__file__))+"../res/"+res_name
filename = os.path.normpath(filename)
if os.path.isfile(filename):
return filename
return None # Resource cannot be resolved
def play_wav(uri): def play_wav(uri):
return subprocess.Popen(["aplay", get_http(uri)]) return subprocess.Popen(["aplay", get_http(uri)])