Skip to main content

OpenAL integration for Python

Project description

PyOpenAL

PyOpenAL provides OpenAL bindings for python as well as an interface to them.

It also provides a simple way to play WAVE and - if PyOgg is installed - even OGG Vorbis, OGG Opus and FLAC files.

You can install it using the PyPI:

pip install PyOpenAL

PyOpenAL requires a shared OpenAL library (e.g. OpenAL32.dll), one of which the Windows distributions already come with (OpenAL Soft by kcat). You can use the official OpenAL library (deprecated) or any other compatible library, like the aforementioned OpenAL Soft library, which is still actively developed.

PyOpenAL provides OpenAL bindings, as you would find them in C++, meaning you can follow any OpenAL C++ tutorial with Python. OpenAL's methods expect C types as arguments, which means you will have to convert Python's types to C types using ctypes if you want to use them directly. Don't worry though, PyOpenAL can be used without the need to do that.

I removed the support for ALUT, because it is basically impossible to build nowadays. If you want ALUT support, please use the original python-openal from forrestv

Examples

Playing a wave file
# import PyOpenAL (will require an OpenAL shared library)
from openal import * 

# import the time module, for sleeping during playback
import time

# open our wave file
source = oalOpen("test.wav")

# and start playback
source.play()

# check if the file is still playing
while source.get_state() == AL_PLAYING:
	# wait until the file is done playing
	time.sleep(1)

# release resources (don't forget this)
oalQuit()
Playing an OGG Opus file (with PyOgg)
# This requires PyOgg to be installed ( pip install pyogg )
from openal import * 

import time

source = oalOpen("test.opus")

source.play()

while source.get_state() == AL_PLAYING:
	time.sleep(1)

# remember, don't forget to quit
	oalQuit()
Streaming a file
from openal import *

# The following two lines are optional. You can use them, if you can't update the stream frequently enough
# This one specifies how much data is supposed to be stored in each buffer (only applies for OGG Vorbis and Opus files)
pyoggSetStreamBufferSize(4096*4)
# This one sets the maximum amount of buffers to be created at a time
oalSetStreamBufferCount(4)

sourceStream = oalStream("test.ogg")

sourceStream.play()

while sourceStream.get_state() == AL_PLAYING:
	# do stuff
	[...]

	# update the stream (load new data)
	# if you don't do this repeatedly, the stream will suffocate
	sourceStream.update()

oalQuit()

Using OpenAL functions

# Here we only import OpenAL's functions 
# (in case you don't need or want PyOpenAL's functions and classes)
from openal.al import *
from openal.alc import *

[...]

# It's as simple as that:
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED)

# Or a little more complicated, it really depends:
alSourceUnqueueBuffers(source_id, 1, ctypes.pointer(ctypes.c_uint(buffer_ids[id])))

[...]

Reference (for PyOpenAL's own classes and functions)

<method> oalInit(device_specifier = None, context_attr_list = None) -> None
	# initializes PyOpenAL
	# this is called automatically, unless you set OAL_DONT_AUTO_INIT
		<c_char_p> device_specifier # you can set a custom device with this
		<c_int_p> context_attr_list # you can pass additional arguments to context creation

<method> oalGetInit() -> <bool> initialized
	# finds out wether or not PyOpenAL is initialized

<method> oalQuit() -> None
	# exits out of OpenAL and destroys all existing Sources and Buffers

<method> oalOpen(path, ext_hint = None) -> Source
	# loads a WAVE / Ogg Vorbis / Ogg Opus / FLAC file to a Source object
		<str> path # path to the file (relative or absolute)
		<str> ext_hint # if the filetype is not wav, wave, ogg, vorbis or opus, you should supply a hint to the extension

<method> oalStream(path, ext_hint = None) -> SourceStream
	# loads a WAVE /  Ogg Vorbis / Ogg Opus / FLAC file to a SourceStream object, that streams the data
	# you should use this instead of Source for Soundtracks or other long tracks (as it uses less memory)
	# you will have to update it frequently to avoid suffocation of the stream
	# you can neither rewind nor loop a SourceStream (currently)
		<str> path # path to the file (relative or absolute)
		<str> ext_hint # if the filetype is not ogg, vorbis or opus, you should supply a hint to the extension

<class> openal.Listener()
	# class for hadling the listener (you)
	# an instance of this class is created when you import PyOpenAL.
	# it can be retrieved using oalGetListener()
	# you do NOT have to create an instance yourself

	<method> Listener.move(v)
		# move the listener by v
			<tuple or list> v # a translation vector represented as (x, y, z)

	<method> Listener.move_to(v)
		# set the listener's position to v
			<tuple or list> v # a position vector represented as (x, y, z)

	<method> Listener.set_position(v)
		# see Listener.move_to

	<method> Listener.set_orientation(v)
		# sets the listener's orientation to v
			<tuple or list> v # orientation represented as (frontX, frontY, frontZ, upX, upY, upZ)

	<method> Listener.set_velocity(v)
		# sets the listener's velocity to v
			<tuple or list> v # velocity represented as (vX, vY, vZ)

	<method> Listener.set_gain(value)
		# sets the listener's gain (volume) to value
			<float> value

<method> openal.oalGetListener() -> Listener
	# returns PyOpenAL's Listener

<class> openal.Source(buffer_ = None)
	# class for managing a source
		<Buffer> buffer_ # where this source finds it's data

	<method> Source.play() -> None
		# starts playing

	<method> Source.stop() -> None
		# stops playback

	<method> Source.pause() -> None
		# pauses playback (use play to resume)

	<method> Source.rewind() -> None
		# goes back to the start of the track

	<float> Source.pitch
		# the source's current pitch

	<float> Source.gain
		# the source's current gain

	<float> Source.max_distance
		# the source's current max_distance

	<float> Source.rolloff_factor
		# the source's current rolloff_factor

	<float> Source.reference_distance
		# the source's current reference_distance

	<float> Source.min_gain
		# the source's current min_gain

	<float> Source.max_gain
		# the source's current max_gain

	<float> Source.cone_outer_angle
		# the source's current cone_outer_angle

	<float> Source.cone_inner_angle
		# the source's current cone_inner_angle

	<float> Source.cone_outer_gain
		# the source's current cone_outer_gain

	<vec3> Source.position
		# the source's current position (use .x, .y, and .z to access it's items or .toTuple())

	<vec3> Source.velocity
		# the source's current velocity (use .x, .y, and .z to access it's items or .toTuple())

	<vec3> Source.direction
		# the source's current velocity (use .x, .y, and .z to access it's items or .toTuple())

	<bool> Source.relative
		# wether or not the source is relative to the listener

	<int> Source.source_type
		# the source's current source_type (either AL_UNDETERMINED, AL_STATIC or AL_STREAMING)

	<method> Source.set_pitch(value) -> None
		# set the pitch for this source
			<float> value # pitch

	<method> Source.set_gain(value) -> None
		# set the gain for this source
			<float> value # gain

	<method> Source.set_max_distance(value) -> None
		# set the max_distance for this source
			<float> value # max_distance

	<method> Source.set_rolloff_factor(value) -> None
		# set the rolloff_factor for this source
			<float> value # rolloff_factor

	<method> Source.set_reference_distance(value) -> None
		# set the reference_distance for this source
			<float> value # reference_distance

	<method> Source.set_min_gain(value) -> None
		# set the min_gain for this source
			<float> value # min_gain

	<method> Source.set_max_gain(value) -> None
		# set the max_gain for this source
			<float> value # max_gain

	<method> Source.set_cone_outer_gain(value) -> None
		# set the cone_outer_gain for this source
			<float> value # cone_outer_gain

	<method> Source.set_cone_inner_angle(value) -> None
		# set the cone_inner_angle for this source
			<float> value # cone_inner_angle

	<method> Source.set_cone_outer_angle(value) -> None
		# set the cone_outer_angle for this source
			<float> value # cone_outer_angle

	<method> Source.set_position(value) -> None
		# set the position for this source
			<tuple or list> value # position

	<method> Source.set_velocity(value) -> None
		# set the velocity for this source
			<tuple or list> value # velocity

	<method> Source.set_looping(value) -> None
		# set the looping for this source
			<bool> value # looping

	<method> Source.set_direction(value) -> None
		# set the direction for this source
			<tuple or list> value # direction

	<method> Source.set_source_relative(value) -> None
		# set the source_relative for this source
			<bool> value # source_relative

	<method> Source.set_source_type(value) -> None
		# set the source_type for this source
			<int> value # source_type

	<method> Source.set_buffer(buffer_) -> None
		# set the buffer for this source
			<Buffer> value # buffer

	<method> Source.get_state() -> <int> state of the Source (e.g. AL_PLAYING, AL_STOPPED,etc.)
		# get the current state of the source

<class> openal.SourceStream(stream)
	# class for managing a source in streaming mode
		<PYOGG-Stream> stream # where the buffer gets it's data from

	<method> update() -> <bool> playing
		# load more data to play (if necessary). 
		# if you don't call this frequently, the source will stop playing after it reaches the last buffer
		# in that case you should consider increasing the buffer size or amount using oalSetStreamBufferCount or pyoggSetStreamBufferSize

<class> openal.Buffer(*args)
	# class for managing OpenAL buffers
		<File or tuple or list> args # what to fill the buffer with (either y PyOgg file or a tuple / list with [format, data, length, frequency])

	<method> Buffer.fill(*args) -> None
		# fill the buffer
			<File or tuple or list> args # what to fill the buffer with (either y PyOgg file or a tuple / list with [format, data, length, frequency])

	<method> Buffer.destroy() -> None
		# destroy this buffer

<class> openal.StreamBuffer(stream, count)
	# class for managing OpenAL buffers for audio streaming
		<PYOGG-Stream> stream # from where to get the data
		<int> count # how many buffers to create (usually OAL_STREAM_BUFFER_COUNT, which is 2 initially)

	<method> Buffer.fill_buffer(id_) -> None
		# fill the buffer
			<int> id_ # load some data into this buffer

	<method> Buffer.destroy() -> None
		# destroy this streambuffer

<method> oalGetEnum(enum) -> <str> ENUM
	# returns a literal representation of enum 
		<int> enum # AL_ or ALC_ enumerator

<method> oalGetALEnum(enum) -> <str> ENUM
	# returns a literal representation of an AL_ enum 
		<int> enum # AL_ enumerator

<method> oalGetALCEnum(enum) -> <str> ENUM
	# returns a literal representation of an ALC_ enum 
		<int> enum # ALC_ enumerator

<method> oalGetContext() -> <int> context
	# returns the context used by PyOpenAL

<method> oalGetDevice() -> <int> device
	# returns the device used by PyOpenAL

<method> oalSetAutoInit(val) -> None
	# changes wether or not PyOpenAL initializes automatically
		<bool> val # wether or not to auto-init

	# The other methods and variables are the same as in Source 
	# (note that you can't loop, because the file can be read only once (by now))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

PyOpenAL-0.7.11a1.tar.gz (26.7 kB view details)

Uploaded Source

Built Distributions

PyOpenAL-0.7.11a1-py2.py3-none-win_amd64.whl (513.4 kB view details)

Uploaded Python 2 Python 3 Windows x86-64

PyOpenAL-0.7.11a1-py2.py3-none-win32.whl (461.4 kB view details)

Uploaded Python 2 Python 3 Windows x86

File details

Details for the file PyOpenAL-0.7.11a1.tar.gz.

File metadata

  • Download URL: PyOpenAL-0.7.11a1.tar.gz
  • Upload date:
  • Size: 26.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.8.0

File hashes

Hashes for PyOpenAL-0.7.11a1.tar.gz
Algorithm Hash digest
SHA256 33ffd00bac6208755d36c744ffe8b5866d10b3c8aac05dfc173d5166df5d76c1
MD5 7f931c04f37c9c387ac03efbd92bdcdc
BLAKE2b-256 04a88c09f20724e99790952014dd70f8c1fa6ca9cbf3bef4a43e188e09b959a4

See more details on using hashes here.

File details

Details for the file PyOpenAL-0.7.11a1-py2.py3-none-win_amd64.whl.

File metadata

  • Download URL: PyOpenAL-0.7.11a1-py2.py3-none-win_amd64.whl
  • Upload date:
  • Size: 513.4 kB
  • Tags: Python 2, Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.8.0

File hashes

Hashes for PyOpenAL-0.7.11a1-py2.py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 da5bfdbe8fb3d2987d60430bec66ec8e51ef52ae8f792c0aa8a370413e712b45
MD5 f6c0cd7f179a86026200e9090c6f3e44
BLAKE2b-256 6054e3d9fff1b60d101685e1f658792825c1012f0c02aa7c8f591796cdc4ed65

See more details on using hashes here.

File details

Details for the file PyOpenAL-0.7.11a1-py2.py3-none-win32.whl.

File metadata

  • Download URL: PyOpenAL-0.7.11a1-py2.py3-none-win32.whl
  • Upload date:
  • Size: 461.4 kB
  • Tags: Python 2, Python 3, Windows x86
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/2.0.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.36.1 CPython/3.8.0

File hashes

Hashes for PyOpenAL-0.7.11a1-py2.py3-none-win32.whl
Algorithm Hash digest
SHA256 6df4ccf1fcb03e5b385a0e68e461ef00c62a1fa3557ac6c669bb50aec45a6cbb
MD5 1891a5be0cf4480b77f383fa45c63517
BLAKE2b-256 4cd0e7ebff59051503e5eac7aabd1305dc244c77eaf55f21cd002197b01abba9

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page