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.message import Message
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 os.path import expanduser
logger = getLogger("SpeechClient")
ws = None
tts = TTSFactory.create()
@ -44,10 +42,12 @@ config = ConfigurationManager.get()
def handle_record_begin():
logger.info("Begin Recording...")
# If enabled, play a wave file with a short sound to indicate recording has
# begun.
# If enabled, play a wave file with a short sound to audibly
# indicate recording has begun.
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'))
@ -105,6 +105,7 @@ def handle_speak(event):
else:
mute_and_speak(utterance)
def handle_sleep(event):
loop.sleep()

View File

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

Binary file not shown.

View File

@ -28,6 +28,52 @@ from os.path import dirname
__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):
return subprocess.Popen(["aplay", get_http(uri)])