Using the standalone 'AUD' for looping music in the BGE

Hello everyone! (Wow, its been a while since i’ve been online…):eek:
I’ve been busy messing around with the blender game engine and recently I started to write a python code to properly loop soundtrack audio into the game engine.

How does it work? Simple: first it plays the intro once, and then it goes on to the main part which it becomes loop-able infinitely.

So far I’ve got the audio to load properly and to work, but the other problem now is to somehow stop the music. I was working on them in different modules so then it can make the music work…:mad:

Here is the code:

import bge
from bge import logic
import aud


# Setting up the controller


cont = bge.logic.getCurrentController()
obj = cont.owner



# Loading up the audio, can be as many as you want


device = aud.device()
musicFolder = logic.expandPath('//Sound/')


intro = musicFolder + '<music_name>_INTRO.ogg'
main = musicFolder + '<music_name>.ogg'


        
def bossMusic(): # Using a single module to start playing music
    
    # 'Factory' enabled music


    boss_intro = aud.Factory(intro)
    boss = aud.Factory(main)



    # Made the main part Loopable and come after the intro part


    boss_loop = boss.loop(-1)
    playlist = boss_intro.join(boss_loop)



    # This part is used to start playing music while preventing duplicates
    # if using the pulse mode in the Sensor area, even with 'TAP' enabled.


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




def bossMusicStop(): # This module was supposed to stop the music but not working...
    
    bossMusic().handle.stop()
    obj['play'] = 0

the “bossMusicStop” module was supposed to stop the music but I get an error:

NameError: name ‘handle’ is not defined

Is there a way to connect two modules together? or should I re-write the code to make this work?

You can give the code above a try to see how this code works. Use a “keyboard” sensor or an “Always” sensor to activate the code and then type: "<nameofcodeabove>.bossMusic in the “Module” of the Python Script Type in the “Python” Controller. Do the same thing over again for the bossMusicStop module to see the error.:yes:

Firstly, if bossMusic() starts playing music, you’re starting music to then stop it.

However, bossMusic doesn’t return anything, so bossMusic().handle is interpreted as “None.handle”, which doesn’t exist. What you might want to do is replace “play” with “playing_handle”, and instead of setting it to 1 in bossMusic, set it to the handle value, which you can then retrieve in other functions.

As well as this, avoid defining module-level variables as BGE data. If you imported this module, it would remain bound to that object so it makes it useless, and can be confusing at times. You’re better off using the module mode, which helps you to write neater code.

I created three functions, as this module is essentially written for “boss music”, it might as well be called boss_music.py
Run each in module mode, and ensure that the init function runs first, for which there is a special flag on the Python controller brick that marks the controller for execution before all other controllers.

I haven’t tested this.


import bge
from bge import logic
import aud




# Setting up the controller
def init(cont):
	obj = cont.owner
	
	# Loading up the audio, can be as many as you want
	device = aud.device()
	musicFolder = logic.expandPath('//Sound/')


	intro = musicFolder + '&lt;music_name&gt;_INTRO.ogg'
	main = musicFolder + '&lt;music_name&gt;.ogg'


	boss_intro = aud.Factory(intro)
	boss = aud.Factory(main)


	boss_loop = boss.loop(-1)
	playlist = boss_intro.join(boss_loop)
	
	obj['device'] = device
	obj['playlist'] = playlist




def play(cont):
	obj = cont.owner
	# This part is used to start playing music while preventing duplicates
	# if using the pulse mode in the Sensor area, even with 'TAP' enabled.
	if obj.get("playing_handle") is not None:
		return
		
	obj['playing_handle'] = obj['device'].play(playlist)


def stop(cont):
	obj = cont.owner


	obj['playing_handle'].stop()
	own['playing_handle'] = None

Thanks for the tip agoose77!:wink: I’ll be sure to give this code a try to see if this works… I’ll let you know.

So far the code just gave me an error:

Blender Game Engine Started File “C:\Users\Corruptinator\Desktop\Blender Game Engine Templates\Music Test\musicloop_test.blend
ewMusic.py”, line 14
intro = musicFolder + ‘<music_name>_INTRO.ogg’
^
IndentationError: unindent does not match any outer indentation level
Python module can’t be imported - object ‘Cube’, controller ‘Python’:
SystemError: NULL result without error in PyObject_Call

Any other ideas what to do next?

Make sure that the indents line up. (try adding or removing spaces to the start of that line)

Sorry for the delay, been busy with something else involving with my life. However, i decided to use “Convert Whitespace” to “Tabs” to remove the slight error with Unindentation and now i get this error:

Python script error - object ‘Cube’, controller ‘Python’:Traceback (most recent call last):
File “C:\Users\Corruptinator\Desktop\Blender Game Engine Templates\Music Te
newMusic.py”, line 35, in play
obj[‘playing_handle’] = obj[‘device’].play(playlist)
KeyError: ‘value = gameOb[key]: KX_GameObject, key “device” does not exist’

I’ll still fiddle around the code to see if i can get the music to work. Any other ideas? Otherwise I feel like this code should be rewritten for a good purpose.