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.
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.