Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ProwlEngine/Prowl/llms.txt

Use this file to discover all available pages before exploring further.

Prowl’s audio system is a thin, engine-agnostic wrapper built on top of OpenAL (via OpenALEngine), with an automatic fallback to a silent NullAudioEngine when no audio hardware is available. The static AudioSystem class manages three pools: an AudioBuffer cache keyed by AudioClip (so the same clip’s PCM data is only uploaded to the GPU once), a source pool of reusable ActiveAudio objects, and an active-source list from which finished sources are automatically recycled. Sound playback returns an ActiveAudio handle, giving callers control over gain, pitch, position, and loop state after the sound starts. A single AudioListener component represents the listener in world space; its transform drives spatial audio attenuation and panning.

Initialization

Initialize

public static void Initialize()
Creates the audio engine and pre-warms the source pool with two idle ActiveAudio sources. Attempts to construct an OpenALEngine first. If OpenAL initialisation throws (no audio device, missing drivers), a NullAudioEngine is used instead and a Debug.LogError is emitted.
// Called automatically by the engine on startup
AudioSystem.Initialize();
Engine
AudioEngine
The active audio engine instance. Will be either an OpenALEngine or NullAudioEngine.
Listener
AudioListener
The currently registered AudioListener component. There should be exactly one active listener per scene.

AudioEngine (abstract)

The backend interface that both OpenALEngine and NullAudioEngine implement:
public abstract class AudioEngine
{
    public abstract void SetListenerPosition(Vector3 position);
    public abstract void SetListenerVelocity(Vector3 velocity);
    public abstract void SetListenerOrientation(Vector3 forward, Vector3 up);
    public abstract ActiveAudio CreateAudioSource();
    public abstract AudioBuffer CreateAudioBuffer();
}
You generally do not interact with AudioEngine directly. Use the AudioSystem.PlaySound overloads and the returned ActiveAudio handle instead.

Playing Sounds

PlaySound overloads

All PlaySound variants return an ActiveAudio handle. The source is taken from the internal pool; if the pool is empty, a new source is created.

From AudioClip (simple)

public static ActiveAudio PlaySound(AudioClip clip)
public static ActiveAudio PlaySound(AudioClip clip, float volume)
public static ActiveAudio PlaySound(AudioClip clip, float volume, float pitch)
clip
AudioClip
The audio clip to play.
volume
float
default:"1.0"
Gain multiplier. 1.0 = full volume.
pitch
float
default:"1.0"
Pitch multiplier. 1.0 = original pitch.

From AudioClip with 3D position

public static ActiveAudio PlaySound(
    AudioClip clip,
    float volume,
    float pitch,
    Vector3 position,
    AudioPositionKind positionKind)
position
Vector3
World-space position of the sound source for 3D attenuation.
positionKind
AudioPositionKind
AbsoluteWorld — position is in world space; distance attenuation and panning applied.
ListenerRelative — position is relative to the listener; use for 2D / UI sounds.

From AudioBuffer (simple)

public static ActiveAudio PlaySound(AudioBuffer buffer)
Plays a pre-fetched buffer at full volume and pitch, listener-relative, with a max distance of 32 units.
buffer
AudioBuffer
Pre-fetched audio buffer (from GetAudioBuffer).

From AudioBuffer (full control)

public static ActiveAudio PlaySound(
    AudioBuffer buffer,
    float volume,
    float pitch,
    Vector3 position,
    AudioPositionKind positionKind,
    float maxDistance)
buffer
AudioBuffer
Pre-fetched audio buffer (from GetAudioBuffer).
maxDistance
float
Maximum distance in world units at which the sound is audible.
// Simple 2D sound
AudioSystem.PlaySound(explosionClip);

// Pitched variation
AudioSystem.PlaySound(footstepClip, volume: 0.8f, pitch: Random.Range(0.9f, 1.1f));

// 3D positional sound
AudioSystem.PlaySound(
    clip: ambienceClip,
    volume: 1.0f,
    pitch: 1.0f,
    position: emitterTransform.position,
    positionKind: AudioPositionKind.AbsoluteWorld);

AudioBuffer Cache

GetAudioBuffer

public static AudioBuffer GetAudioBuffer(AudioClip clip)
Returns a cached AudioBuffer for clip, uploading the PCM data to the audio engine if it has not been uploaded before. The internal cache (Dictionary<AudioClip, AudioBuffer>) ensures each clip is only uploaded once.
clip
AudioClip
The clip whose buffer to retrieve.
returns
AudioBuffer
The GPU-side audio buffer ready for playback.

ActiveAudio Handle

ActiveAudio is an abstract class returned by PlaySound. It represents an active or pooled audio source and lets you modify playback after the sound has started.
public abstract class ActiveAudio : IDisposable

Properties

Gain
float
Volume multiplier. Get or set at any time during playback.
Pitch
float
Pitch multiplier. Changing this mid-playback re-pitches the sound in real time.
MaxDistance
float
Distance in world units at which the source is fully attenuated.
Looping
bool
When true, the source loops automatically when it reaches the end.
Position
Vector3
World-space or listener-relative position of the source.
Direction
Vector3
Directional cone axis for directional audio sources.
PositionKind
AudioPositionKind
AbsoluteWorld or ListenerRelative — controls how Position is interpreted.
IsPlaying
bool
true when the source is actively playing.
PlaybackPosition
float
Normalised playback position in [0, 1]. Setting this seeks the source. When PlaybackPosition >= 1 and Looping is false, the source is considered finished and returned to the pool.

Methods

Play

public abstract void Play(AudioBuffer buffer)
Begins playback of buffer from the start. The source must be acquired from the pool before calling this.

Stop

public abstract void Stop()
Stops playback immediately. The source remains in the active list until UpdatePool recycles it.

Dispose

public abstract void Dispose()
Releases the underlying OpenAL source. Sources managed by AudioSystem are disposed automatically; only call this if you created a source manually.

Listener Registration

RegisterListener / UnregisterListener

public static void RegisterListener(AudioListener audioListener)
public static void UnregisterListener(AudioListener audioListener)
Called by AudioListener component lifecycle methods. Only one listener is supported per scene. Registering a second listener emits a Debug.LogWarning.

ListenerTransformChanged

public static void ListenerTransformChanged(Transform t, Vector3 lastPost)
Called by AudioListener whenever its transform changes. Updates the audio engine’s listener position, velocity (t.position - lastPost), and orientation (t.forward, t.up).

Pool Management

UpdatePool

public static void UpdatePool()
Scans the active-source list and moves any stopped or finished sources back to the idle pool. Called automatically by the engine each frame.

Dispose

public static void Dispose()
Stops all active and pooled sources, disposes all cached AudioBuffer objects, and disposes the AudioEngine (if it is IDisposable). Called automatically on engine shutdown.

Usage Example

// Play a 2D sound effect
ActiveAudio source = AudioSystem.PlaySound(shootClip, volume: 0.9f, pitch: 1.05f);
// No further action needed — the source is returned to the pool automatically

Build docs developers (and LLMs) love