Python openAL 3D 声音

Dan*_*ial 5 python 3d audio openal

我刚刚开始使用 python,正在制作音频操作程序。我正在尝试在我的 python 应用程序中使用 openAL 实现 3D 声音,但我只能让它工作

这是我的 3D 声音代码:

from openal.loaders import load_wav_file
from openal.audio import *

sink = SoundSink()   
listener = SoundListener()
SoundSink.activate(sink)
listener.position = (0, 0, 0)
listener.velocity = (0, 0, 0)
listener.orientation = (0, 0, -1, 0, 1, 0)
source = SoundSource()
wavsound = load_wav_file("test.wav")
source.queue(wavsound)
#SoundSink.play(source)
sink.play(source)
Run Code Online (Sandbox Code Playgroud)

代码执行,但不播放声音

Cod*_*eon 2

更新答案:

我在下面的评论中提到 PyAL 已经有一段时间没有更新了。事实上,虽然我链接的 bitbucket 存储库不再存在,但这并不准确。PyAL 的 PyPI 页面的最新日期为 2019 年 12 月 25 日,截至本次更新时,存储库的日期为 2020 年 9 月 11 日。相比之下,PyOpenAL 的 PyPI 页面的最新日期为 2019 年 12 月 17 日,存储库日期也为 2019 年 12 月 17 日。我保留了下面的旧答案,并按照上面 @Caridorc 的要求添加了支持 PyOpenAL 的代码。

为了让 PyOpenAL 工作,我需要手动将openal.dll文件添加到已安装的库中,以便其内部库加载实用程序可以找到依赖项。我还需要避免直接为我的ListenerSource类设置位置元组,并且必须使用set_position方法调用,以便位置更改将传播到底层 C 库(理想情况下PyOpenAL应该修改为使用 @property 语法来无缝处理此问题))。

两个演示中使用的波形声音文件在这里。请注意,仅支持单声道而不是立体声声音文件

这是更新后的代码:

import time
from openal import * 

if __name__ == "__main__":
    x_pos = 5
    sleep_time = 5
    source = oalOpen("CantinaBand60.wav")
    source.set_position([x_pos, 0, 0])
    source.set_looping(True)
    source.play()
    listener = Listener()
    listener.set_position([0, 0, 0])

    while True:
        source.set_position([x_pos, 0, 0])
        print("Playing at: {0}".format(source.position))
        time.sleep(sleep_time)
        x_pos *= -1
    
    oalQuit()
Run Code Online (Sandbox Code Playgroud)

使用 PyAL 的旧答案:

事实证明,这里的Bitbucket 存储库页面上有一些如何使用 PyAL 的示例。基于这个audioplayer.py例子,我制作了这个听起来烦人的例子,根据正弦波在左右耳机扬声器之间进行声音替代:

import time
import math
from openal.audio import SoundSink, SoundSource
from openal.loaders import load_wav_file

if __name__ == "__main__":
    sink = SoundSink()
    sink.activate()
    source = SoundSource(position=[0, 0, 0])
    source.looping = True
    data = load_wav_file("CantinaBand60.wav")
    source.queue(data)
    sink.play(source)
    t = 0
    while True:
        x_pos = 5*math.sin(math.radians(t))
        source.position = [x_pos, source.position[1], source.position[2]]
        sink.update()
        print("playing at %r" % source.position)
        time.sleep(0.1)
        t += 5
Run Code Online (Sandbox Code Playgroud)

  • @ch4rl1e97 是的,这里的代码现在看起来已被弃用。它依赖于 PyAL 而不是 PyOpenAL 包装器。前者看起来自 2013 年以来就没有更新过。PyOpenAL 的 PyPi 页面有一个参考部分,但这应该使此代码的移植变得很简单。 (2认同)