Sound is being played twice (using aud library)

I want to use the aud python library to play sounds in my game, but the sound is being played twice and I can’t figure out why. I have set up an example blend so you can check it out. I know someone on here will be able to figure this out. Thanks in advance for taking the time to look at this.

sound problem.zip (197 KB)
It’s a .zip file because you will need the sound file also (which is included)

Also, I’m open to other methods of playing sounds if someone knows of a better one. I could just use the sound actuator, but overlapping sounds will cut each other off. There’s a way around this by using more than one actuator for the same sound, but that can get very cluttered. The aud library seems perfect for this project if I can figure out why it’s playing the sound twice. I suppose I could just set up a timer property and have a minimum amount of time pass before the sound can be played again. It would have to be a very small window of time though (yet large enough to avoid a double-play) and I’d like to know why it’s being played twice in the first place anyway. Any feedback would be appreciated.

Controllers are activated on both a positive and negative pulse so if you only want the sound to play once you will need to have an if statement that activates if it receives a positive pulse. Thus, your code should be:


import GameLogic
import aud

###########################################

    # sets up the directory for all sounds & defines the output device
    # NOTE: In this case the file is here:
    # <Blend File Directory>/Sounds/BumperHit.wav
    
def _Init(owner):        
    
    owner['init'] = 1
    GameLogic.device = aud.device()
    owner['SoundDir'] = GameLogic.expandPath('//Sounds/')
    
###########################################

def BumperHit():
    
    #get controller
    cont = GameLogic.getCurrentController()
    #get message sensor 
    bumperhit = cont.sensors["soundBumperHit"]
    #get owner
    owner = cont.owner    
        
    if not 'init' in owner:        
        _Init(owner)
            
    sound = owner['SoundDir'] + 'BumperHit.wav'
    
    owner['BumperHit'] = aud.Factory.file(sound)
    
        # plays sound
    if bumperhit.positive:
		GameLogic.device.play(owner['BumperHit'])
    
			### Troubleshooting ###
		print("BumperHit: playing sound")
		owner["Times Played"] = owner["Times Played"] + 1

That’s good to know. Thanks CrazedQuetzal!

I actually had this in the code before I started testing it, but I took it out because I thought it was redundant. Turns out it wasn’t.

You’re welcome. :slight_smile:
A cool thing about module mode is that you don’t need to assign a name to the controller using: cont = GameLogic.getCurrentController(). The controller is assigned by default to the first argument of your function so if you change-
def BumperHit(): to def BumperHit(cont): and remove your cont = GameLogic.getCurrentController() it will still work.

Also I’m not sure it’s much of a problem in this case, but having your init function run on an initial state then switching to a state with your BumperHit function instead of having the BumperHit function check for a init property every time the controller is triggered will is not a bad habit to get into.

Thanks for the tips, CrazedQuetzal! The built-in module controller assignment is something I will definitely utilize. Using a different state for the _init() function is a good idea too.