Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pygame 1.9.2 for Python 3.4: Simulating 3D sound

Long story short: I followed this tutorial here and the documentation of pygame 1.9.2. According to both it should be possible to adjust the volume for the left and right earphone in stereo mode, however, it doesn't work for me at all. Sounds remain audible on either earphone, no matter what I try.

Here my tries:

Short foreword: I use

pygame.mixer.pre_init(44100, -16, 2, 3072)

This should actually do the job for my system to enable stereo sound in pygame, but maybe I made a mistake here already which I have overlooked, so I mention it.

Try 1:

class MainProgram(object):

    def __init__(self, width = 640, height = 640):
        # Much Code

        # Sounds
        self.testsound = pygame.mixer.Sound("data\\sounds\\ping.ogg")
        self.chan1 = pygame.mixer.Channel(0)
        self.chan2 = pygame.mixer.Channel(1)

        self.mainloop()


    def mainloop(self):
        while 1:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    terminate()
                if event.type == pygame.KEYDOWN:
                    self.testsound.play().set_volume(1.0, 0.0)
                elif event.type == pygame.KEYUP:
                    self.testsound.play().set_volume(0.0, 1.0)
        # More code here

When I don't adjust the volume, I can hear the sounds at full volume on either side. If I adjust as seen above, then I still hear the sound on either side, just only half the volume (rough estimation by me, but clearly quieter), it's like, instead of setting one side to 0 and the other to 1, pygame just takes the average (0.5) for either side.

Try 2:

class MainProgram(object):

    def __init__(self, width = 640, height = 640):
        # Much Code

        # Sounds
        self.testsound = pygame.mixer.Sound("data\\sounds\\ping.ogg")
        self.chan1 = pygame.mixer.Channel(0).set_volume(1.0, 0.0)
        self.chan2 = pygame.mixer.Channel(1).set_volume(0.0, 1.0)

        self.mainloop()


    def mainloop(self):
        while 1:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    terminate()
                if event.type == pygame.KEYDOWN:
                    self.chan1.play(self.testsound)
                elif event.type == pygame.KEYUP:
                    self.chan2.play(self.testsound)
        # More code here

This has no effect whatsoever. All sounds are played at full volume.

Try 3:

class MainProgram(object):

    def __init__(self, width = 640, height = 640):
        # Much Code

        # Sounds
        self.testsound = pygame.mixer.Sound("data\\sounds\\ping.ogg")
        self.chan1 = pygame.mixer.Channel(0)
        self.chan2 = pygame.mixer.Channel(1)

        self.mainloop()


    def mainloop(self):
        while 1:
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    terminate()
                if event.type == pygame.KEYDOWN:
                    self.testsound.play()
                    self.testsound.set_volume(1.0, 0.0)
                elif event.type == pygame.KEYUP:
                    self.testsound.play()
                    self.testsound.set_volume(0.0, 1.0)
        # More code here

As you can see I just separated try 2's approach into two lines in try 3. Interestingly there's a new issue: I get a

TypeError: function takes exactly 1 argument (2 given)

Which makes everything all the more interesting as using the very same in one line triggers no error, though it doesn't do what it's supposed to.

As I have seen, my program is in stereo mode and according to the tutorials (I've checked others beside) and the documentation either of the two first approaches should yield the result I expected - but neither does...

I'm really grateful for any hints and tips in this issue. It's really important that I can add some kind of 3D-sound. If there's really an issue with pygame itself and not my code, do you know any other module I could use to achieve this effect - best would be if compatible to Pygame, then I don't have to rewrite everything (but I'd do that if necessary...).

Thank you in advance!

Pat

//Short comment by me: I just saw that Try 2 is doomed anyway, the doc says, that all volumes are reset when the channel is used again, so I can't just set a fixed volume once and for all...

like image 862
Patric Hartmann Avatar asked May 19 '26 13:05

Patric Hartmann


1 Answers

As the documentation states: set_volume takes one parameter, the volume as a float between 0.0 and 1.0.

This means:

ad "Try 1": this is syntactically wrong. play() doesn't return anything so a chained call with set_volume() is just wrong.


ad "Try 2": This actually might work if you set up your channels like this:

self.chan1 = pygame.mixer.Channel(0)
self.chan1.set_volume(1.0, 0.0)
self.chan2 = pygame.mixer.Channel(1)
self.chan2.set_volume(0.0, 1.0)

ad "Try 3: on the Sounds set_volume only one value is allowed.

like image 99
Constantinius Avatar answered May 24 '26 08:05

Constantinius