check if a sound is currently playing?

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 :slight_smile: 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

1 Like

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. :slight_smile:

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 :slight_smile: 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.