Sending function to another define

Hi, so ive got scripts that play sound files fine with audaspace but iv been having trouble altering the created factory volume every frame. (this is for altering large amounts of sounds on the fly) However if I use the handle method way something like (handle.volume = mastersfx) im able to send this to an update def in a part of the script to run every frame.

Its just if I use the factory handle way instead of doing it at the audaspace factory level I lose the control of then reducing the volume of specific sounds at audaspaces handle.volume level.

So if you see the test script its trying to send the factory function “(factory = factory.volume(s)” over to the update def with a key, however the volume isn’t being updated from the property “volumeporperty”. Annoyingly the script throws no errors back at me, even more annoying if I send over the created factory handle for volume it updates just fine.

from bge import logic
import aud

scene = logic.getCurrentScene()
o = logic.getCurrentController().owner

device = aud.device()

s = o.get("volumeproperty")

def play():

    file = logic.expandPath("sounds") + "/somesoundfile.wav"

    factory = aud.Factory(file)

    #can set factory volume on first play with this line
    #factory = factory.volume(s)

    handle = device.play(factory)
    handle.volume = 1.00

    #need to able to send over "factory = factory.volume(s)" to "update def" with this line
    o["factory"] = factory

def update(cont):

    o = cont.owner

    s = o.get("volumeproperty")

    o["factory"].volume(s)

You choose a really strange title ;). usually functions will not be send around. They do the sending (of data).

When looking at your code, the first thing is please avoid this cryptic one letter names. If a thing is a chicken call it a chicken. Even in two years you will know it is supposed to be a chicken.

Audaspace has a similar issue it calls the sound “Factory”. This is very confusing as a factory in terms of design pattern is an object that builds something. Referring to the API documentation:

“Factory objects … represent a sound that can be played simultaneously multiple times.”
If they represent sound why aren’t called sound?
Reason from the API: “They are called factories because they create reader objects internally that are used for playback”. I really do not care the internals as they are and should not be visible anyway. This all does not refer to your problem but if you change your code this way it makes a bit more sense:


sound = aud.Factory(soundFileName)
device.play(sound)

“handle” is a similar confusing thing. I never found an explanation what “handle” should be - because really everything is an handle. It is often used in C - but it is really just a general term. In Python it is called reference. It is better to use a name that tells a reader what it is for. In your case … “playback” would be fine.

so you get


sound = aud.Factory(soundFileName)
playback = device.play(sound)

Isn’t this readable even by a beginner?

When using this notation you see that you have to change the volume at the playback not at the sound (which would result in an error). If you store the playback in a property you can change the volume later:


owner["playback"] = playback
...

playback = owner["playback"]
playback.volume = newVolume

Here is a complete example, just from scatch (please change the filename to your needs)
audioPlayer.py


import aud
from bge.logic import getCurrentController

filename = "path to your sound file here.wav"

def loadSound():
    sound = aud.Factory(filename)
    getOwner()["sound"] = sound
    
def play():
    owner = getOwner()
    sound = owner["sound"]
    playback = aud.device().play(sound)
    owner["playback"] = playback

def setVolume():
    owner = getOwner()
    playback = owner["playback"]
    playback.volume = owner["volume"]
    print(playback.volume)

        
def getOwner():
    return getCurrentController().owner

(property “volume” to control the volume)
This works pretty well. I noticed the most difference when increasing the volume.

Be aware loading, playing and setting the volume are three different things, but they depend on each other (playing depends on loading, set volume depends on playing).

I hope it helps

Edit:
Indeed you can call a chicken “animal” - but what do you do if there is a cat too?
(and what if there is a second chicken?)

Attachments

AudaspaceDemo.blend (80.5 KB)

Thanks for help but the example you have there changes the created factory’s handle volume on the fly. This I know is possible and can do. You can see its changing the handles volume if you play a sound then lower the volume to zero then play another one. You shouldn’t be able to hear the next sound that’s played.

From my tests there’s 3 separate areas to change/alter volume in audaspace. Firstly the main audio device such as openal which would be (device.volume = 1.00) then you have a volume function at the factory level, and finally all the handles that are created from that factory also have a separate volume function handle.volume.

All three different levels for control of volume work independently from one another, so altering the factory’s volume will alter (all) the created handles but then you can still change a single created handles volume to be lower or higher for just that handle. This is good because if you were to have a global sfx slider that changes all sfx sounds you could put it at the factory level while still being able to then change individual sounds/handles within all your sfx sounds.

Problem is ive not been able to update a factory’s volume once its been created. Handle volume Ive been able to update as well the main audio device volume. I guess it might just not be possible with audaspace to update a factory’s settings once its been created. its just needed to have a 3 tier hierarchy for volume control.

I normally use different naming conventions for my stuff, but most people ive seen use the term handles factory’s as its whats documented and it makes sense once understood. So I changed them to the norm before posting the script.

Yeah im not sure why i called the thread that. It should have just been (updating a created factory’s volume) :yes: