General Philosophy

The sound_play node considers each sound (built-in, wave file or synthesized text) as an entity that can be playing, playing repeatedly or stopped. Nodes change the state of a sound by publishing to the robotsound topic. Multiple sounds can be played at once.

Supported Hardware

This node has been tested on the Logitech USB speakers on the PR2 and on some built-in Intel sound-cards, but should support any sound card that is supported by SDL. Because it accesses SDL via pygame, it has no control over which sound device is used. You will have to configure SDL and ALSA/OSS to default to the sound device you want to use.

API Stability

  • The C++ and Python APIs are stable.
  • The ROS API and in particular the message format should not be relied on and may change at any time to support extended functionality.

Known Limitations

Please let us know if these limitations actually bother you.

  • Two nodes independently using the same sound may have strange interactions. For example one node may stop a sound that was started by the other one.
  • There is no way to tell when a sound stops playing.
  • When a sound is played multiple times, at most two copies of that sound will accumulate in the queue at once.

C++/Python API

C++ and Python bindings are provided. It should be unnecessary to directly generate messages when playing sounds from C++ or Python. Documentation of the language bindings are in doxygen.

Command-line utilities

The following utilities can be used to play sound when is running. For help on getting running refer to the tutorial.

Playing a .WAV or .OGG file

The script can play any .WAV or .OGG file. The file must be available on the computer on which is running, and an absolute path should be given.

$ rosrun sound_play --help
Usage: /u/blaise/ros/ros-pkg/stacks/sound_drivers/sound_play/scripts/ sound_to_play.(ogg|wav)

Plays an .OGG or .WAV file. The path to the file should be absolute, and be valid on the computer on which sound_play is running.

For example ( should be running first):

$rosrun sound_play /usr/share/xemacs21/xemacs-packages/etc/sounds/im_so_happy.wav
Playing "/usr/share/xemacs21/xemacs-packages/etc/sounds/im_so_happy.wav".

Playing a built in sound

Some standard sounds are built-into the driver, and can be played only by specifying their integer identifier using

$ rosrun sound_play 
Usage: /u/blaise/ros/ros-pkg/stacks/sound_drivers/sound_play/scripts/ <sound_id>

Plays one of the built-in sounds based on its integer ID. Look at the <<MsgLink(sound_play/SoundRequest)>> message definition for IDs.

For example ( should be running first):

$ rosrun sound_play 2
Playing sound 2".

To get an up-to-date list of the built-in sounds, consult the definition of the sound_play/SoundRequest message. The relevant information is below the "Sounds" comment.

$ cat `rospack find sound_play`/msg/SoundRequest.msg
# Sounds
byte BACKINGUP = 1

# Sound identifiers that have special meaning
byte ALL = -1 # Only legal with PLAY_STOP
byte PLAY_FILE = -2
byte SAY = -3

byte sound # Selects which sound to play (see above)

# Commands
byte PLAY_STOP = 0 # Stop this sound from playing
byte PLAY_ONCE = 1 # Play the sound once
byte PLAY_START = 2 # Play the sound in a loop until a stop request occurs

byte command # Indicates what to do with the sound

string arg # file name or text to say

Saying Some Text

The sound node can also be used to synthesize speech using the festival speech synthesis system. The script gives command-line access to this functionality. This script can take its input from the command line, or if the command-line is empty it can take input from standard input.

$ rosrun sound_play --help
$ rosrun sound_play --help
Usage: /u/blaise/ros/ros-pkg/stacks/sound_drivers/sound_play/scripts/ 'String to say.'
       /u/blaise/ros/ros-pkg/stacks/sound_drivers/sound_play/scripts/ < file_to_say.txt

Says a string. For a string on the command line, you must use quotes as
appropriate. For a string on standard input, the command will wait for
EOF before saying anything.

Examples ( should be running first):

$ rosrun sound_play 'Hello world'
Saying: Hello world.
$ echo Hello again|rosrun sound_play
Awaiting something to say on standard input.
Saying: Hello again

Silencing the Robot

The most immediate way to silence the robot is to use alsamixer to mute or lower the volume. In some cases, a node that had requested a continuous sound could crash with the sound still playing. In order to stop that sound the script can be used.

The script sends a stop command on all sounds every 100ms until it is terminated. This behavior will immediately stop any continuous sounds that were playing, and will cut short any new sounds that are played. It will not completely silence the robot, however, as the first tens of milliseconds of newly requested sounds will be played before they are silenced.

For example:

$ rosrun sound_play 
Sending stopall command every 100 ms.
Note: This will not prevent a node that is continuing to issue commands
from producing sound.
Press Ctrl+C to exit.

Testing Sound Play Node Operation

To test that is operating correctly, you can use the script. It will play the various built-in sounds, and exercise the .WAV playing and text-to-speech capabilities. To run it:

$ rosrun sound_play

Nodes subscribes to robotsound and plays sounds on the sound card. This node must be running before the command-line utilities described below will work.

Subscribed Topics

robotsound (sound_play/SoundRequest)
  • Topic for playing sound.

Published Topics

diagnostics (diagnostic_msgs/DiagnosticArray)
  • Reports driver diagnostic information. Detection of a disconnected sound device can only happen when no sounds have been played for a few seconds.

Example Launch File

The following launch file, which starts, can be found in soundplay_node.launch:

  <node name="soundplay_node" pkg="sound_play" type=""/>

Message Format

Programmers should use the C++/Python bindings to send messages to robotsound, rather than creating messages themselves. If you need the information in this section for something other than satisfying curiosity, you are probably doing something wrong.

Sound commands are issued to via a sound_play/SoundRequest message. Commands define two things: a sound, and what to do with that sound.

The sound is defined by the sound (int) and arg (string) fields of the message, and can be one of four types:

  • a built-in sound, identified by its identifier in sound

  • a file, identified by PLAY_FILE in sound and the file name (absolute path on the computer running in arg

  • some text to be synthesized into speech, identified by SAY in sound and the text in arg

  • the wildcard sound, that can only be used when stopping sound, identified by ALL in sound

The action that can be carried out on a sound can be:

  • stop playing the sound
  • play the sound once (if it is already playing, it will be played again after the current playback ends)
  • play the sound continuously

Each message on the robotsound topic will cause a sound to transition between the playing continuously, playing once (or twice) and stopped states. For example, a backing up sound could be initiated by sending a command for a backing up sound to play continuously. When the robot stops backing up, a stop command will stop playback. Likewise, verbal debugging messages could be used by telling a sound to play once. In this case there is no need to stop playing the sound.

The special wildcard sound can be used to stop playback on all sounds.

Wiki: sound_play (last edited 2016-06-11 17:28:54 by AustinHendrix)