libsoundplay.py
Go to the documentation of this file.
1 #***********************************************************
2 #* Software License Agreement (BSD License)
3 #*
4 #* Copyright (c) 2009, Willow Garage, Inc.
5 #* All rights reserved.
6 #*
7 #* Redistribution and use in source and binary forms, with or without
8 #* modification, are permitted provided that the following conditions
9 #* are met:
10 #*
11 #* * Redistributions of source code must retain the above copyright
12 #* notice, this list of conditions and the following disclaimer.
13 #* * Redistributions in binary form must reproduce the above
14 #* copyright notice, this list of conditions and the following
15 #* disclaimer in the documentation and/or other materials provided
16 #* with the distribution.
17 #* * Neither the name of the Willow Garage nor the names of its
18 #* contributors may be used to endorse or promote products derived
19 #* from this software without specific prior written permission.
20 #*
21 #* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 #* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 #* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 #* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 #* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 #* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 #* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 #* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 #* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 #* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 #* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 #* POSSIBILITY OF SUCH DAMAGE.
33 #***********************************************************
34 
35 # Author: Blaise Gassend
36 
37 import rospy
38 import roslib
39 import actionlib
40 import os, sys
41 from sound_play.msg import SoundRequest
42 from sound_play.msg import SoundRequestGoal
43 from sound_play.msg import SoundRequestAction
44 
45 ## \brief Class that publishes messages to the sound_play node.
46 
55 
56 class Sound(object):
57  def __init__(self, client, snd, arg, volume=1.0):
58  self.client = client
59  self.snd = snd
60  self.arg = arg
61  self.vol = volume
62 
63 ## \brief Play the Sound.
64 
66 
67  def play(self, **kwargs):
68  self.client.sendMsg(self.snd, SoundRequest.PLAY_ONCE, self.arg,
69  vol=self.vol, **kwargs)
70 
71 ## \brief Play the Sound repeatedly.
72 
75 
76  def repeat(self, **kwargs):
77  self.client.sendMsg(self.snd, SoundRequest.PLAY_START, self.arg,
78  vol=self.vol, **kwargs)
79 
80 ## \brief Stop Sound playback.
81 
83 
84  def stop(self):
85  self.client.sendMsg(self.snd, SoundRequest.PLAY_STOP, self.arg)
86 
87 ## This class is a helper class for communicating with the sound_play node
88 ## via the \ref sound_play.SoundRequest message. There is a one-to-one mapping
89 ## between methods and invocations of the \ref sound_play.SoundRequest message.
90 
91 class SoundClient(object):
92 
93  def __init__(self, blocking=False):
94  """
95 
96  The SoundClient can send SoundRequests in two modes: non-blocking mode
97  (by publishing a message to the soundplay_node directly) which will
98  return as soon as the sound request has been sent, or blocking mode (by
99  using the actionlib interface) which will wait until the sound has
100  finished playing completely.
101 
102  The blocking parameter here is the standard behavior, but can be
103  over-ridden. Each say/play/start/repeat method can take in an optional
104  `blocking=True|False` argument that will over-ride the class-wide
105  behavior. See soundclient_example.py for an example of this behavior.
106 
107  :param blocking: Used as the default behavior unless over-ridden,
108  (default = false)
109  """
110 
111  self._blocking = blocking
112 
113  # NOTE: only one of these will be used at once, but we need to create
114  # both the publisher and actionlib client here.
116  'sound_play', SoundRequestAction)
117  self.pub = rospy.Publisher('robotsound', SoundRequest, queue_size=5)
118 
119 ## \brief Create a voice Sound.
120 
124 
125  def voiceSound(self, s, volume=1.0):
126  return Sound(self, SoundRequest.SAY, s, volume=volume)
127 
128 ## \brief Create a wave Sound.
129 
134  def waveSound(self, sound, volume=1.0):
135  if sound[0] != "/":
136  rootdir = os.path.join(roslib.packages.get_pkg_dir('sound_play'),'sounds')
137  sound = rootdir + "/" + sound
138  return Sound(self, SoundRequest.PLAY_FILE, sound, volume=volume)
139 
140 ## \brief Create a builtin Sound.
141 
145 
146  def builtinSound(self, id, volume=1.0):
147  return Sound(self, id, "", volume)
148 
149 ## \brief Say a string
150 
155 
156  def say(self,text, voice='', volume=1.0, **kwargs):
157  self.sendMsg(SoundRequest.SAY, SoundRequest.PLAY_ONCE, text, voice,
158  volume, **kwargs)
159 
160 ## \brief Say a string repeatedly
161 
165 
166  def repeat(self,text, volume=1.0, **kwargs):
167  self.sendMsg(SoundRequest.SAY, SoundRequest.PLAY_START, text,
168  vol=volume, **kwargs)
169 
170 ## \brief Stop saying a string
171 
176 
177  def stopSaying(self,text):
178  self.sendMsg(SoundRequest.SAY, SoundRequest.PLAY_STOP, text)
179 
180 ## \brief Plays a WAV or OGG file
181 
187 
188  def playWave(self, sound, volume=1.0, **kwargs):
189  if sound[0] != "/":
190  rootdir = os.path.join(roslib.packages.get_pkg_dir('sound_play'),'sounds')
191  sound = rootdir + "/" + sound
192  self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_ONCE, sound,
193  vol=volume, **kwargs)
194 
195 ## \brief Plays a WAV or OGG file repeatedly
196 
201 
202  def startWave(self, sound, volume=1.0, **kwargs):
203  if sound[0] != "/":
204  rootdir = os.path.join(roslib.packages.get_pkg_dir('sound_play'),'sounds')
205  sound = rootdir + "/" + sound
206  self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_START, sound,
207  vol=volume, **kwargs)
208 
209 ## \brief Stop playing a WAV or OGG file
210 
215 
216  def stopWave(self,sound):
217  if sound[0] != "/":
218  rootdir = os.path.join(roslib.package.get_pkg_dir('sound_play'),'sounds')
219  sound = rootdir + "/" + sound
220  self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_STOP, sound)
221 
222 ## \brief Plays a WAV or OGG file
223 
230 
231  def playWaveFromPkg(self, package, sound, volume=1.0, **kwargs):
232  self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_ONCE, sound, package,
233  volume, **kwargs)
234 
235 ## \brief Plays a WAV or OGG file repeatedly
236 
242 
243  def startWaveFromPkg(self, package, sound, volume=1.0, **kwargs):
244  self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_START, sound,
245  package, volume, **kwargs)
246 
247 ## \brief Stop playing a WAV or OGG file
248 
255 
256  def stopWaveFromPkg(self,sound, package):
257  self.sendMsg(SoundRequest.PLAY_FILE, SoundRequest.PLAY_STOP, sound, package)
258 
259 ## \brief Play a buildin sound
260 
265 
266  def play(self,sound, volume=1.0, **kwargs):
267  self.sendMsg(sound, SoundRequest.PLAY_ONCE, "", vol=volume, **kwargs)
268 
269 ## \brief Play a buildin sound repeatedly
270 
275 
276  def start(self,sound, volume=1.0, **kwargs):
277  self.sendMsg(sound, SoundRequest.PLAY_START, "", vol=volume, **kwargs)
278 
279 ## \brief Stop playing a built-in sound
280 
284 
285  def stop(self,sound):
286  self.sendMsg(sound, SoundRequest.PLAY_STOP, "")
287 
288 ## \brief Stop all currently playing sounds
289 
291 
292  def stopAll(self):
293  self.stop(SoundRequest.ALL)
294 
295  def sendMsg(self, snd, cmd, s, arg2="", vol=1.0, **kwargs):
296  """
297  Internal method that publishes the sound request, either directly as a
298  SoundRequest to the soundplay_node or through the actionlib interface
299  (which blocks until the sound has finished playing).
300 
301  The blocking behavior is nominally the class-wide setting unless it has
302  been explicitly specified in the play call.
303  """
304 
305  # Use the passed-in argument if it exists, otherwise fall back to the
306  # class-wide setting.
307  blocking = kwargs.get('blocking', self._blocking)
308 
309  msg = SoundRequest()
310  msg.sound = snd
311  # Threshold volume between 0 and 1.
312  msg.volume = max(0, min(1, vol))
313  msg.command = cmd
314  msg.arg = s
315  msg.arg2 = arg2
316 
317  rospy.logdebug('Sending sound request with volume = {}'
318  ' and blocking = {}'.format(msg.volume, blocking))
319 
320  # Defensive check for the existence of the correct communicator.
321  if not blocking and not self.pub:
322  rospy.logerr('Publisher for SoundRequest must exist')
323  return
324  if blocking and not self.actionclient:
325  rospy.logerr('Action client for SoundRequest does not exist.')
326  return
327 
328  if not blocking: # Publish message directly and return immediately
329  self.pub.publish(msg)
330  if self.pub.get_num_connections() < 1:
331  rospy.logwarn("Sound command issued, but no node is subscribed"
332  " to the topic. Perhaps you forgot to run"
333  " soundplay_node.py?")
334  else: # Block until result comes back.
335  assert self.actionclient, 'Actionclient must exist'
336  rospy.logdebug('Sending action client sound request [blocking]')
337  self.actionclient.wait_for_server()
338  goal = SoundRequestGoal()
339  goal.sound_request = msg
340  self.actionclient.send_goal(goal)
341  self.actionclient.wait_for_result()
342  rospy.logdebug('sound request response received')
343 
344  return
def start(self, sound, volume=1.0, kwargs)
Play a buildin sound repeatedly.
def repeat(self, kwargs)
Play the Sound repeatedly.
Definition: libsoundplay.py:76
def waveSound(self, sound, volume=1.0)
Create a wave Sound.
def say(self, text, voice='', volume=1.0, kwargs)
Say a string.
def startWave(self, sound, volume=1.0, kwargs)
Plays a WAV or OGG file repeatedly.
def stopWave(self, sound)
Stop playing a WAV or OGG file.
def stopWaveFromPkg(self, sound, package)
Stop playing a WAV or OGG file.
def __init__(self, client, snd, arg, volume=1.0)
Definition: libsoundplay.py:57
def startWaveFromPkg(self, package, sound, volume=1.0, kwargs)
Plays a WAV or OGG file repeatedly.
def stop(self)
Stop Sound playback.
Definition: libsoundplay.py:84
def sendMsg(self, snd, cmd, s, arg2="", vol=1.0, kwargs)
def voiceSound(self, s, volume=1.0)
Create a voice Sound.
def builtinSound(self, id, volume=1.0)
Create a builtin Sound.
def stopAll(self)
Stop all currently playing sounds.
def playWaveFromPkg(self, package, sound, volume=1.0, kwargs)
Plays a WAV or OGG file.
def play(self, kwargs)
Play the Sound.
Definition: libsoundplay.py:67
def playWave(self, sound, volume=1.0, kwargs)
Plays a WAV or OGG file.
def __init__(self, blocking=False)
Definition: libsoundplay.py:93
def stopSaying(self, text)
Stop saying a string.
This class is a helper class for communicating with the sound_play node via the sound_play.SoundRequest message.
Definition: libsoundplay.py:91
Class that publishes messages to the sound_play node.
Definition: libsoundplay.py:56


sound_play
Author(s): Blaise Gassend
autogenerated on Sun May 3 2020 03:39:32