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 packagepull/520/head
parent
990dd27c5e
commit
5f8775883a
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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.
|
@ -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)])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue