Danial
Danial

Reputation: 71

Python openAL 3D sound

I just started with python and I am making program for audio manipulation. I am trying to implement 3D sound with openAL in my python application, but I just can get it to work

this is my code for 3D sound:

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)

The code executes, but it doesn't play the sound

Upvotes: 5

Views: 4864

Answers (1)

CodeSurgeon
CodeSurgeon

Reputation: 2465

Updated Answer:

I mentioned in the comments below that PyAL had not been updated for a while. Indeed, while the bitbucket repo I linked to no longer exists, this is not accurate. The PyPI page for PyAL is last dated at 12/25/2019, with the repo dated at 9/11/2020 as of the time of this update. In contrast, the PyPI page for PyOpenAL is last dated at 12/17/2019, with the repo also dated at 12/17/2019. I have kept the old answer below, and am adding the code to support PyOpenAL as requested by @Caridorc above it.

In order to get PyOpenAL to work, I needed to manually add an openal.dll file to the installed library so that dependency could be found by its internal library loader utility. I also needed to avoid setting the position tuples for my Listener and Source classes directly and had to use set_position method calls instead so that the position changes would be propagated to the underlying C library (ideally PyOpenAL should be modified to use @property syntax to seamlessly handle this).

The wave sound file used in both demos is here. Note that only mono, NOT STEREO, sound files are supported.

Here is the updated code:

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()

Old Answer using PyAL:

It turns out that there are some examples of how to use PyAL at the Bitbucket repository page here. Based off the audioplayer.py example, I made this annoying-sounding example with the sound alternative between the left and right headphone speaker according to a sine wave:

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

Upvotes: 2

Related Questions