Pygame 1.9.2 for Python 3.4:模拟3D声音

时间:2014-07-09 23:11:45

标签: pygame stereo-3d

长话短说: 我在这里按照本教程和pygame 1.9.2的文档。根据两者,应该可以在立体声模式下调节左耳机和右耳机的音量,但是,它对我来说根本不起作用。无论我尝试什么,耳机都能听到声音。

我的尝试:

简短的引言:我用

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

这实际上应该让我的系统能够在pygame中启用立体声声音,但也许我已经在这里犯了一个我忽略的错误,所以我提到了它。

尝试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

当我不调节音量时,我可以听到两侧全音量的声音。如果我如上所述进行调整,那么我仍然会听到两边的声音,只有音量的一半(粗略估计我,但显然更安静),就像是,而不是将一边设置为0而另一边设置为1,pygame只取两边的平均值(0.5)。

尝试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

这没有任何效果。所有声音都以全音量播放。

尝试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

正如你所看到的那样,我只是将尝试2的方法分成了尝试3中的两行。有趣的是,有一个新问题:我得到了一个

TypeError: function takes exactly 1 argument (2 given)

这使得一切变得更加有趣,因为在一行中使用相同的内容不会触发任何错误,尽管它没有做到它应该做的事情。

正如我所看到的,我的程序处于立体模式并且根据教程(我已经检查过其他人)并且文档中的任何一种方法都应该产生我预期的结果 - 但是......也没有...... / p>

我真的很感激这个问题的任何提示和技巧。我可以添加某种3D声音非常重要。如果pygame本身确实存在问题,而不是我的代码,你知道我可以用来实现这个效果的任何其他模块 - 最好是兼容Pygame,然后我不必重写所有内容(但我会做如果有必要......)。

提前谢谢!

专利

//我的简短评论: 我刚刚看到Try 2注定失败了,文档说,当再次使用频道时所有音量都被重置,所以我不能一劳永逸地设置一个固定的音量......

2 个答案:

答案 0 :(得分:3)

由于documentation州:set_volume采用一个参数,因此float0.0之间的数量为1.0

这意味着:

ad“Try 1”:这在语法上是错误的。 play()不会返回任何内容,因此使用set_volume()进行链接调用是错误的。


ad“Try 2”:如果你设置这样的频道,这实际上可能会有效:

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)

广告“尝试3:Sound set_volume只有一个value is allowed

答案 1 :(得分:1)

这是最适合我的版本。我在我的问题中使用了Try 2并进行了一些调整。毕竟,当谈到声音时,pygame似乎没那么有用......无论如何,我的代码是尝试一些事情的实验,所以这就是现在这样做 - 而对于最终的项目,我和#39;无论如何我会编写自己的声音模块,因为我还有一些要求尚未涵盖;)

这是最终的代码,是问题2的修改版本:

class MainProgram(object):

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

        # Sounds
        self.sound = pygame.mixer.Sound("data\\sounds\\ping.ogg")
        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)


        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.sound)
                    # IMPORTANT NOTE! We have to reset the volume after each time
                    # a sound was played by the respective channel!
                    self.chan1.set_volume(1.0, 0.0)
                elif event.type == pygame.KEYUP:
                    self.chan2.play(self.sound)
                    self.chan2.set_volume(0.0, 1.0)
        # More code here