Trying to learn Audaspace, EDIT: almost there, one final thing left

And before anyone asks, I have looked at an earlier thread in this forum that contained a number of code examples, while I have been able to figure a few things out and get some audaspace code running without errors, there’s still the error where the console says that the file can’t be played, even though I have imported the aud and bge modules.

The code setup I have (helped by looking at other threads and the Blender wiki), has these lines setting the basic variables for audaspace at the beginning of the script


device = aud.device()
walkSound = aud.Factory.file(bge.logic.expandPath("//Sounds/foot_steps_1.wav"))

And then further down, when the movement actuator is activated.


handle = aud.device().play(walkSound)
handle.loop_count = -1
handle.location = [Px, Py, Pz] #set the location to the player's position#

However, I’ve tried every line I’ve seen as an example to play a sound in audaspace, but the console still shows the same error saying the sound file cannot be played, it doesn’t matter if I try to use expandPath or not, noting that the file is packed within the .blend file so I’m not sure what I’m doing wrong.

This isn’t really for a new project, but converting the code in an older project to the 2.5 API which includes converting a piece of code to play a sound from the old API for the sound actuator in 2.49 to use audaspace in 2.5 (using a fairly recent build). I have nearly everything else working, but I don’t have much of an idea on how to get the sound file to play if it seems nothing I’ve gathered from other threads is working.

Huh. You’re using the most recent version of Blender? Also, try renaming the file. Perhaps it’s the format of the file itself that’s causing the problem, as well.

I had this problem as well, but then I switched to a newer version of blender and haven’t had a problem since.

Ex.

Okay, found out I did the filepath wrong, now the sound plays back as intended.

But for controlling the playback of the sound (so I could stop the sound if the player is not moving and/or colliding with the ground), I haven’t read of a straightforward way to create a handle for my Factory object other than what I saw in that code snippet. While the way in that code snippet works, it seems to prevent me from being able to use the pause() and stop() functions providing I have it in the beginning of the script (to avoid errors in it not being defined).

So ideally, I would want to create my handle in a way that doesn’t involve playing the sound at that moment as well, but I’m not sure how to go about that because the API reference on blender.org does not seem to give any examples.

The handle is created by playing the sound. You could store the handle someplace, and if the handle exists / is valid, then control it via the pause() and stop() functions. By the way, it might be a good idea to store the device once in a global variable and use that, rather than getting it every time for each sound you want to play.

EDIT: You’re right - I think that the only way to create a handle is to play the sound, if I recall correctly. However, if you play and then pause the sound, it should be the same thing as creating the handle without using it.

That’s what I figured too, I guess the best way to handle a multitude of sounds in this case is to create a global list of factories that you would use and then use them whenever you need them.

I got everything working now, the sound only plays when I tell it to, the last thing to do is find a way to remove the last console error even though everything works (below), while it’s not affecting anything it would easily prevent me from easily seeing other, more serious errors or debug prints, but this one is quite a bit different from the usual ones I see so I’m not entirely sure what I’m missing.

aud.error AUD_OpenALDevice: Source couldn't be generated

Maybe Open_AL installation is broken or try SDL as Audio Playback Device.

An old thread: blenderartists.org/forum/showthread.php?208086-Concept-User-TraX-v-0.4&

Well I’ve found that the global factory/handler list idea works well when you need to use sounds in any area of the game, just have a initialization script at the beginning and you’re good to go, this also avoids having to set different GameLogic variables for each factory and handler. (the script below being an example from one my own files where sound effects are being added back in)

import GameLogic
import bge
import aud


con = GameLogic.getCurrentController()
ob = con.owner
device = aud.device() #import the audaspace device we will be using--

if ob['Tap'] == 0:
    
    #Create a dictionary where we create all of the factories that we will be using in the game#
    GameLogic.fList = {'driveSound': aud.Factory.file(bge.logic.expandPath("//sounds\DRIVING.WAV")),
                        'donkSound': aud.Factory.file(bge.logic.expandPath("//sounds\Donk-Public_d-336.wav")),
                        'breakSound': aud.Factory.file(bge.logic.expandPath("//sounds\HANDBRAK.WAV")),
                        'thrustSound': aud.Factory.file(bge.logic.expandPath("//sounds
         
    
    #Now create another dictionary which will contain all the handles we will need to have sound in the game#
    GameLogic.hList = {'Drive': aud.device().play(GameLogic.fList["driveSound"]),
                        'DriveAir': aud.device().play(GameLogic.fList["driveSound"]),
                        'Donk': aud.device().play(GameLogic.fList["donkSound"]),
                        'Break': aud.device().play(GameLogic.fList["breakSound"]),
                        'Thrust': aud.device().play(GameLogic.fList["thrustSound"])}
    
    #set the initial values for various properties for the handlers, also pause them so they won't play until needed#
    GameLogic.hList["Drive"].loop_count = -1
    GameLogic.hList["Drive"].pause()
    GameLogic.hList["DriveAir"].loop_count = -1
    GameLogic.hList["DriveAir"].pitch = 1.5
    GameLogic.hList["DriveAir"].pause()
    GameLogic.hList["Donk"].loop_count = 0
    GameLogic.hList["Donk"].pause()
    GameLogic.hList["Break"].loop_count = 0
    GameLogic.hList["Break"].pause()
    GameLogic.hList["Thrust"].loop_count = -1
    GameLogic.hList["Thrust"].pause()
    ob['Tap'] = 1

That’s actually how my sound setup works, as well - I create a dictionary full of factories for each sound / BGM file, though I handle the handles dynamically. The error is caused, I think, by the Blender audio device running, even when it’s closed (i.e. you play music, but don’t stop it after you stop the game. The music continues, and when you open the game again, the device is busy). Try ensuring that any sounds are stopped before the game finishes. In addition, it might be a good idea to get the device once, and pass that around, rather than get the device for each sound.

Well I noticed that I needed to stop all the handles when I would quit the game when I noticed that otherwise the game would lock up after a number of test runs. I also found out that if I wanted to play a non-looping handle again and again based on sensor input (like a collision), then I have to use a line of code to set the play position back to the beginning.

Overall, you need a bit more skill in Python to use Audaspace, but it’s worth it because I can have a ton of sounds without all of the sound actuators, plus the values you can change to affect the sound playing is quite a bit more than the old 2.49 sound API, you don’t even need to cut off the end of a sound file in a sound editor manually because you can correct that at runtime with Audaspace as well.

Yeah, that’s right. With Audaspace, you can do things like play sounds at different pitches and volumes, filter them, etc. For example, I have a slight pitch change on footsteps in a game to make them sound different. It’s a pretty good effect.