is this possible? I mean anything is but is there an easy way to check if a sound is playing?
How about playing a sound if a certain property is True, and checking if that property is True?
actuator sensor?
or have a list of sounds you want to play
[‘Sound’,owner, timeEnd, timeNow]
and each frame update the list using system time
if a sound listing length is too short
add the sound object and set properties in it, and append the game Object to the sound list
once added the list becomes
[‘Sound’,owner, timeEnd, timeNow, gameObject]
I use something just like this to run and update my ui elements.
I’m not using bricks. ??? I really do not like them for a lot of things they just get messy…for a large project…they are fine for smaller things.
So there is no direct way then?
polling the actuator maybe?
but the bricks are great for only running code when it is needed.
check the aud docs. i could swear i saw a state variable in the handler class
I believe Daed has the right idea:
import aud
sound_path = ...
sound = aud.Factory(sound_path)
handler = aud.play(sound)
This creates a handler for the sound you have referenced.
This:
if handler.status == aud.AUD_STATUS_PLAYING:
...
checks that a sound is playing under the specified handle.
I think one main drawback to this method though is you have to play the sound first to create the handler (I am not aware of a method to prevent initial playback. You may want to check out aud.Device.lock(), which guarantees no samples are read from streams until unlock() is called.)
Here’s a reference: https://docs.blender.org/api/blender_python_api_2_70a_release/aud.html
I think one main drawback to this method though is you have to play the sound first to create the handler
Or build a small framework around AUD (untested):
handles = list()
def play_sound(path):
factory = aud.Factory(path)
handle = device.play(factory)
handles.append((path, handle)) # Store path and the handle
return handle
def is_playing(sound_path):
is_playing = False
for sound in handles[:]:
path, handle = sound
if handle.status != aud.AUD_STATUS_PLAYING and not handle.keep:
handles.remove(sound)
if path == sound_path:
if handle.status == aud.AUD_STATUS_PLAYING:
is_playing = True
return is_playing
but that is fine,because I want to check if a sound is playing…unless it would give me errors…I am pretty much using that generic method already to play sounds…for entities that already have too many bricks to keep track of…the rest I am trying to tie into the animation system…since they are closely related and that code is already doing some conditional testing to play the correct anims…
for instance
if not entity.onGround:
own.blendAnimation(‘jump’, frames = 5, loop = False)
if not playing.theJumpSound:
play(sound)
No, I know the code does not look like that…it is a mockup to give the general idea what I am doing but I was looking for this from morror mirror
aud.AUD_STATUS_PLAYING
thanks for the info.
I just tried my project in UPBGE 1.9, and there is no audio…were there changes to the audio api? I was not going to switch just yet…but thought I would have a look…I know this is off topic.
i use this in my own projects , you can take what you need from it if there is anything useful to you.
http://15b.dk/modules/audioclass.py
import aud
import os
import random
import time
__all__ = ["Audio"]
class Audio:
def __init__(self,**kw):
self.filename = None
self.path=""
self.folder=""
for arg in kw:
if arg in vars(self):
self[arg] = kw[arg]
self.song = ""
self.device = aud.device()
self.handle = None
self.playlist = []
self.sound = None
random.seed(time.time())
if self.path:
self.path = os.path.join(self.path)
else:
self.path = os.path.join(os.getcwd())
if self.filename:
self.load(self.filename)
def __getitem__(self, key):
return getattr(self, key)
def __setitem__(self, key, value):
setattr(self, key, value)
def setPath(self,path):
self.path = path
def setFolder(self,folder):
self.folder = folder
def load(self,filename):
if filename:
self.filename = filename
filename = os.path.join(self.path,self.folder,self.filename)
self.sound = aud.Factory(filename)
def play(self):
if self.sound:
try:
self.handle = self.device.play(self.sound)
except:
pass
def loadplaylist(self):
for root, directories, filenames in os.walk(self.path):
for filename in filenames:
if ".flac" in filename or ".mp3" in filename:
self.playlist.append(os.path.join(root,filename))
return self.playlist
def playrandom(self):
self.stop()
if self.playlist:
random.shuffle(self.playlist)
return self.getnextsong()
else:
self.loadplaylist()
random.shuffle(self.playlist)
return self.getnextsong()
return ""
def getnextsong(self):
self.stop()
self.song = self.playlist.pop()
self.load(self.song)
self.handle = self.device.play(self.sound)
return self.song
def stop(self):
if self.handle:
self.handle.stop()
def limit(self,start,end):
self.sound = self.sound.limit(start,end)
def pause(self):
if self.handle:
self.handle.pause()
def resume(self):
if self.handle:
self.handle.resume()
def isplaying(self):
if self.handle:
return self.handle.status
else:
return False
def volume(self,setvolume):
if self.handle:
self.handle.volume = setvolume
def loop(self,loops=0):
if self.handle:
self.handle.loop_count = loops
def pitch(self,setpich):
if self.handle:
self.handle.pitch = setpich
That’s pretty in depth and relatively straightforward I don’t think I need to use a class to handle it…I mean I am not going to have more than maybe 6 sounds playing at once controlled by my world script which is handling music, time and some other small things. The player is playing his own sounds based on his anim state and aside from walking usually only get triggered once like at the beginning of a jump or attack…and that is already implemented…in any case I thank you all…I have had it working already I was just doing some optimization.