def unPauseSound(self):
     '''
     Un-pause all currently paused sound effects. Method has no effect if no sound is currently paused.
     '''
     soundReqMsg = SpeakEasySound();
     soundReqMsg.command = SoundCommands.UNPAUSE;
     with self.soundLock:        
         self.rosSoundRequestor.publish(soundReqMsg);
 def pauseSound(self):
     '''
     Pause the all currently playing sound effects. Method has no effect if no sound is currently playing.
     '''
     soundReqMsg = SpeakEasySound();
     soundReqMsg.command = SoundCommands.PAUSE;
     with self.soundLock:        
         self.rosSoundRequestor.publish(soundReqMsg);
 def stopSound(self):
     '''
     Stop the all currently playing sound effects. Method has no effect if no sound is currently playing.
     '''
     soundReqMsg = SpeakEasySound();
     soundReqMsg.command = SoundCommands.STOP;
     with self.soundLock:        
         self.rosSoundRequestor.publish(soundReqMsg);
         
     # Keep this following statement out of the lock! Thread unregistration will 
     # acquire the lock (thus leading to deadlock, if lock is owned here):
     self.killSoundRepeatThreads(self.soundThreads);
 def setSoundVolume(self, volume, soundName=None):
     '''
     Change the sound effect default volume.
     @param volume: New default volume for sound effects. Value must be in range 0.0 to 1.0.
     @type volume: float
     @param soundName: Optionally the name of the sound whose volume is to be changed.
     @type soundName: string
     @raises TypeError: if any parameters are of incorrect type.
     '''
     if not SpeakeasyUtils.ensureType(volume, float):
         raise TypeError("Volume must be a float between 0.0 and 1.0. Was " + str(volume));
     
     soundReqMsg = SpeakEasySound();
     soundReqMsg.command = SoundCommands.SET_VOL;
     if soundName is None:
         soundName = '';
     soundReqMsg.sound_name = soundName;
     soundReqMsg.volume = volume;
     with self.soundLock:
         self.rosSoundRequestor.publish(soundReqMsg);
    def playSound(self, soundName, volume=None, numRepeats=0, repeatPeriod=0):
        '''
        Play a sound effect at the SpeakEasy node.
        @param soundName: Name of the sound effect. (see getSoundEffectNames()).
        @type soundName: string
        @param volume: Loudness for the sound effect. If None, current volume is used. Volume must be in range 0.0 to 1.0
        @type volume: float.
        @param numRepeats: Number of times the sound effect is to be repeated after the first time.  Use -1 to play forever.
        @type numRepeats: int
        @param repeatPeriod: Time period in fractional seconds to wait between repeats.
        @type repeatPeriod: float
        @raise TypeError: if any parameter is of the wrong type. 
        '''
        
        if not SpeakeasyUtils.ensureType(numRepeats, int):
            raise TypeError("Number of repeats must be an integer. Was " + str(numRepeats));
        if not SpeakeasyUtils.ensureType(repeatPeriod, int) and not SpeakeasyUtils.ensureType(repeatPeriod, float):
            raise TypeError("Repeat period must be an integer or a float. Was " + str(repeatPeriod));
        
        soundReqMsg = SpeakEasySound();
        soundReqMsg.command = SoundCommands.PLAY;
        soundReqMsg.sound_name = soundName;
        if volume is None:
            soundReqMsg.volume = -1.0;
        else:
            soundReqMsg.volume = volume;

        with self.soundLock:
            self.rosSoundRequestor.publish(soundReqMsg);
            
        # Keep this block out of the lock! Thread registration will 
        # acquire the lock (thus leading to deadlock, if lock is owned here):
        if numRepeats > 0 or numRepeats == -1:
            soundRepeatThread = RoboComm.SoundReplayDemon(soundName, self, volume=volume, numRepeats=numRepeats, repeatPeriod=repeatPeriod);
            self.registerSoundRepeaterThread(soundRepeatThread) 
            soundRepeatThread.start();