Python Sound!

okay how do you use the sound modules for the BGE? i’m primarily wanting to know how to change things like pitch by pressing a button or something. please answer as soon as possible. i’m trying to play around with it now.

Audaspace’s aud module is sound using Python. The API can be found here, and a little more here. It can do quite a bit, including filtering, pitching up and down, generating sounds, etc.

You want to use the aud module.

The basic usage:

import aud

sound = aud.Factory.file("path/to/file.mp3")
aud.device().play(sound)

Change the pitch with:

import aud

sound = aud.Factory.file("...")
sound.pitch(factor)

aud.device().play(sound)

Check out the docs for aud.Factory for some more functions.

1 Like

Thanks! i needed it. i’m trying to brush up on my BGE python cause i think its interesting.

uhhhh…is it normal when you here reoccurring duplicates of the same sound everytime the script is activated?

I tried this, but the script doesn’t work. The error is “No module named aud”. I’m using Blender 2.49b, could this be a reason as to why it doesn’t work?

Yes actually. It works mostly fine in 2.5 (only the sound plays every time the script is activated making a horrible jumble of noises).

@TWS - No, that is not usual (if you’re doing it correctly). You need to create the sound at particular times - you wouldn’t really use a script like that, so much as store the sounds and play them on a key-press, for example.

Each time you call ‘aud.device().play(sound)’, it’s playing the sound. If you’re running both scripts that Andrew posted, then you’ll be hearing the sound play twice (once for each play() function called), in addition to any amount of times you’re playing the sounds yourself.

It’s generally best to store the variables, and then call them later. Example:


import aud from bge import logic

cont = logic.getCurrentController() # Python controller running this script
obj = cont.owner # The object that the controller belongs to

path = logic.expandPath("\\path/to/file.mp3") 

sound = aud.Factory.file(path) #Get the path to the file, relative to the blend file

if not 'play' in obj:
     obj['device'] = aud.device() 
     obj['device'].play(sound)
     obj['play'] = 1


This code will play the sound in the path specified, relative to the blend file (or standalone, when you’ve exported it), only once, no matter how many times you run the script (this is just an example).

In real practice, you would hook up the obj[‘device’].play(sound) to an event, like if a sensor is positive, or if you press a key.

okay. i will try it in a few minutes here.

Yes, the aud module is only available in 2.5.

After reading over your ‘sound jumble’ problem again, TWS, it could be that you might need to change the sound device buffer on the User Preferences menu (maybe that will help).

@ andrew-101: Ok, thanks.

I have a question about this as well- does audaspace look in the same directory as the .blend by default? I’ve tried both

s = aud.Factory('sectionA.ogg')

and

s = aud.Factory('./sectionA.ogg')

but neither seem to work. Is that expandPath method required? Also, I noticed you’re using aud.Factory.file method, which isn’t present on the wiki (is it outdated?)

At any rate, I’ve tried both with and without it, and neither technique works… Here’s the relevant block of code:

device = aud.device()
		s = aud.Factory.file('sectionA.ogg')
		buffered = aud.Factory.buffer(s)
		c = device.play(buffered)

EDIT: Btw, the error I’m getting is

aud.error: AUD_FileFactory: File couldn't be read.

Use bge.logic.expandPath, so try:

s = aud.Factory.file(bge.logic.expandPath("//sectionA.ogg"))

The // is the .blends directory.

Also, it may be worth pre loading the sounds:

if 's' not in bge.logic.globalDict:
    bge.logic.globalDict['s'] = aud.Factory.file(..).buffer()

The buffer() function returns a new factory whose buffer is loaded into ram.

Thanks! Works great.

Any ideas why this doesn’t work? Trying to adjust the volume of the different sounds but the volume() function seems to have absolutely no effect.

from bge import logic as g
import aud

s = aud.Factory.file(g.expandPath("//Sounds/s.wav"))
s.volume(0.1)
aud.device().play(s)

The sound plays but it’s always at maximum volume whatever volume() is set to.

volume() doesn’t alter the volume of the current factory but returns a new one with altered volume:

from bge import logic as g
import aud

original_sound = aud.Factory.file(g.expandPath("//Sounds/s.wav"))
quite_sound = original_sound.volume(0.1)
aud.device().play(quite_sound)

Alternatively:

from bge import logic as g
import aud

s = aud.Factory.file(g.expandPath("//Sounds/s.wav"))
handle = aud.device().play(s)
handle.volume = 0.1