2022-12-04 11:29:39

The Y value is arbitrary, unless you plan on setting a height value in your side scroller, you could set it to whatever you like as long as the listener and sound are of the same value. Given that you may be playing around with distances that increment by values of 1, maybe you should consider adjusting the roll off factor a bit higher. As an example, I've adjusted the 3D audio example a little:

from openal import *
import time

class Example(object):
    def __init__(self):
    #load listener
        self.listener = Listener()
    #initialize sound
        self.sound = LoadSound('tone5.wav')
    #load sound player
        self.player = Player()

    #set listener position
        self.listener.position = (0,240,0)
    #set player position
        self.player.position = (0,240,0)

    #load sound into player
        self.player.add(self.sound)

    #enable loop sound so it plays forever
        self.player.loop = True
    #set rolloff factor
        self.player.rolloff = 1.0
    #play sound
        self.player.play()

    #move sound from left to right
        for a in range(-5,5,1):
            self.player.position = (a,240,0)
            time.sleep(1)

    #stop player
        self.player.stop()

    #clean up resources
        self.player.delete()
        self.sound.delete()
        self.listener.delete()


Example()
-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2022-12-04 11:40:00

@76:

I really appreciate your help. I will give this a shot and let you know if there is anything wrong. :-)

2023-04-17 20:16:29

Hi Magurp, first of all thank you for your work. Some time has passed but only now have I managed to study it and have working examples. I would like to ask you something, if you still use it, or do you think it's better to use another library for 3d audio?
I currently have working examples of both your wrapper, and synthizer as well, and I'm comparing their functions.
I like about your wrapper that you can set the playback speed of the sound, based on your location. In this way it can automatically be said that if the y of the object is greater than the player, then the sound is more acute, and if it is less, it is more grave, which the synthizer does not have.
But the real question is this: even setting the additional parameter you provided, self.player.max_distance = 40.0, I can't get the desired effect, ie that at a certain distance the sound is no longer heard. I tried different values, but nothing. Did you find a solution to fix the problem?
I leave you my complete code, so that you have an idea of the example I use, and maybe better understand if I'm wrong.
Thank you.

import os
os.add_dll_directory(os.getcwd())
from openal import *
import time
import math

class Suona:
    def __init__(self, filename, listener_pos=(0,0,0), source_pos=(0,0,0)):
        self.listener = Listener()
        self.listener.distance_model = 1
        self.listener.gain = 0.7
        self.listener.velocity = [0.0, 50.0, 0.0]
        self.listener.orientation = [50.0, 0.0, 0.0]
        self.listener.position = listener_pos

        self.sound = LoadSound(filename)
        self.player = Player()
        self.player.position = source_pos
        self.player.add(self.sound)

        self.player.loop = True
        self.player.direction = [160.0, 0.0, 0.0]
        self.player.cone_outer_angle = 160.0
        self.player.cone_inner_angle = 160.0
        self.player.rolloff = 0.5
        self.player.max_distance = 40.0
        self.player.relative_distance = 1.0
    def play(self):
        self.player.play()

    def move_around(self, radius=100, num_circles=2, num_steps=72, delay=0.5):
        for i in range(num_circles):
            for angle in range(0, 360, 360//num_steps):
                x = math.cos(math.radians(angle)) * radius
                y = math.sin(math.radians(angle)) * radius
                self.update_source_position((self.player.position[0] + x, self.player.position[1] + y, self.player.position[2]))
                time.sleep(delay)

    def stop(self):
        self.player.stop()

    def cleanup(self):
        self.player.delete()
        self.sound.delete()
        self.listener.delete()

    def update_source_position(self, x, y, z=0):
        self.player.position =(x, y, z)

    @classmethod
    def update_listener_position(cls, x, y, z=0):
        Listener().position =(x, y, z)

2023-04-17 21:58:47 (edited by magurp244 2023-04-17 22:01:05)

That seems to be a particular issue with OpenAL, or at least perhaps with its configurations. One approach to work around that would be to simply have the sound stop playing after it meets a particular threshold, but you'd have to determine what that distance is and code it yourself. In rendering term's, this would be considered the rendering distance. So, for example lets say the player is at 0,0, and the rendering distance is at 40 in a square around the player. After it moves past 40 in either direction it stops playing, the roll_off_distance in that case just smooths the volume down before you manually stop the sound.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-04-17 23:05:09

with synthizer, you don't modify properties directly like that. You just pass the coords of the listener, then the sound source whenever it updates, it then does the math required for you.

2023-04-17 23:25:44

Current Synthizer doesn't cull sounds either.  You have to manually stop them if you want them stopped.  New Synthizer may cull sounds in some fashion, I have been asked for it, but in general the issue is that if you play half a second of audio while the sound is too far away to be heard and then bring it in, you want that half second of whatever to have been played anyway (and if it's more complex than a file, e.g. a filter, you can't "fake" it).

My math actually matches OpenAL for the most part.  The actual difference between me and OpenAL that matters is that OpenAL says "haha you want us to deal with files or whatever for you yeah right" and then makes e.g. streaming data around, etc. difficult because their abstractions were written originally to deal with PCIE buses.

My Blog
Twitter: @ajhicks1992

2023-04-19 10:56:52

Hi,
On the topic of loading data, is there a way to reuse a buffer in sound_lib as you can in synthizer? It would really cool if I could get that working.

2023-07-08 02:53:02

Hi everybody.
please tell me how to change the orientation listener's in space?
I found only how to change the position, but I would also like to turn the listener himself.

2023-07-08 03:28:32 (edited by magurp244 2023-07-08 03:32:42)

@83
In the examples section for 3D Audio is one for orientation that demonstrates how to adjust the listener's up and "at" orientation.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-07-09 09:33:05

@84
thank you very much.

2023-07-10 13:32:09

Hello.
is it possible to somehow play several sounds at the same time with one player?
if I first play, then delete and add the next sound, then it turns out that the sounds are not played immediately after the action, but in the order of the queue.
ie:
action one, sound one, action 2, action 3, sound 2, sound 3.
I had an idea to make several players for each object on the map, and play sounds in them alternately, but then I may get too many different objects, and if I make at least 5 players for each, then openal stops playing sounds.
moreover, no errors appear, is it possible to change this somehow?

2023-07-10 20:22:46 (edited by magurp244 2023-07-10 20:28:50)

Unfortunately, in order to play sounds simultaneously you will need multiple players for each sound, although it should be capable of running  more than 5 players at a time. To be clear, you should be unloading a sound from a player, and then loading the new sound before playing on a given player, loading multiple sounds into one player will queue them to play on that one player in the order they were loaded one after the other. Deleting the sound itself won't unload it from the player, and it will still have to be unloaded from it.

In term's of efficiency though, you shouldn't need one player for each and every sound, to better optimize that you can organize them in term's of context. For example, a running sound and a jumping sound aren't going to play at the same time, because they involve two different states. Because of this, you can use a single player and load either sound as needed based on the context.

A given player also has a function that can tell you if its currently playing or not, or to tell how many sounds may or may not be queued in a given player.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-07-11 05:05:09

@87
5 players yes, it is being played, I meant a little different.
the fact that if there are about 100 objects on the map, for example 500 by 500, that is, mobs, players, NPCs and some objects, then if you make at least 3 players for each of the objects, the sound stops playing.

2023-07-11 05:07:54

I had such a problem with the steps when I made the player specifically for movement.
the character moves for a while, but after his stop, his footsteps still sounded for a while.

2023-07-11 06:21:11

You should be intelligent about what you are trying to play. Have a queue of players, and only use stuff when the player can actually hear them. It doesn’t make sense to play something that is more than 500 tiles away, actually more than 30 towels away sounds good enough.

2023-07-11 09:22:03 (edited by magurp244 2023-07-11 09:23:20)

@88
I do believe there is a soft coded limit of about 256 players for Openal Soft, though this can be overridden in with a config file. Generally speaking though, its not really necessary to use so many players simultaneously and is rather inefficient. As mentioned, rather than assigning sound players to every object on creation, it may be better to have a central pool of sound players than you can pass back and forth to an object when it gets in range of the user, and only play sounds in the users vicinity, like within 8 by 8 tiles for example. That way you'll only need 64 * 3 sound players, or 192 in total for your objects.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-07-11 13:34:26

hello.
after I lost the sound several times, after playing a lot of sounds, each time it became less and less sounds to be played, at the moment I have only about three sounds being played, and the sound disappears, how can I fix it, please tell me.

2023-07-11 17:32:29

I'm trying to run the examples included with the download, but it doesn't seem to be working. I'm using Python 3.10

The universe is a rain storm. We are droplets sent to quench the problems of the world, yet we are blown sideways by the winds of distractions.

2023-07-11 17:52:27

@93
and what errors did you see?

2023-07-11 20:12:56

@92
Can you provide an example demonstrating the issue?

@93
Not working how? If there's an error traceback, it would be helpful to post it.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-07-12 02:11:08

I'm just running the .py script from the folder using python 3.10. No errors are being displayed long enough for me to capture them.

The universe is a rain storm. We are droplets sent to quench the problems of the world, yet we are blown sideways by the winds of distractions.

2023-07-12 06:15:07 (edited by magurp244 2023-07-12 06:26:18)

@96
If you run it from the command line, you should be able to get the traceback, for example "python myscript.py >> output.txt". Do you have the OpenAL soft dll in the same folder as the example script?

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-07-12 07:08:21

@95
Hello, I'm sorry, I'm texting here through a translator and I didn't quite understand you.
if you asked me to throw off the code that I wrote, then here.:
    def play_sound(self, id, sound, pos):
        path = os.getcwd()+'/sounds/'+sound+'.ogg'
#        print(path)
        try:
            self.sound_players[id].remove()
        except KeyError:
            self.sound_players[id] = Player()
        sound = oalOpen(path)
        self.sound_players[id].add(sound)
        self.sound_players[id].play()
        self.sounds.append([sound, self.sound_players[id]])
        if len(self.sounds) > 10:
            for k in self.sounds[0]:
                k.delete()
            del self.sounds[0]
here is the audio playback function, could there be a problem that I don't delete the listener when closing the program?
and also, is it possible to track the traceback somehow, when the buffer with sounds is overflowing?

2023-07-12 08:45:30

@98
Hm, what does the oalOpen() function do? I'm going to assume it loads Vorbis files, but that might cause complications. I also don't think you need the for loop near the end. Python should for the most part clean up memory, but its good practice to purge the Listener before closing the program. Also, which buffer are you referring? The buffer storing the sound data, or the Player queue? Ideally, you should only have one sound loaded per player at a time, there really isn't any need for more than that. You should also avoid creating/destroying players all the time, create X amount of Players, and swap them in and out as needed.

-BrushTone v1.3.3: Accessible Paint Tool
-AudiMesh3D v1.0.0: Accessible 3D Model Viewer

2023-07-12 16:56:45

Yeah just throws a file could not be found for Openal32.dll
I don't have any openal versions installed from what it looks like.

The universe is a rain storm. We are droplets sent to quench the problems of the world, yet we are blown sideways by the winds of distractions.