Modern, high-performance C# bindings for OpenAL Soft, with managed wrappers for ease of use.
$ dotnet add package openal_soft_bindingsModern, high-performance C# bindings for OpenAL Soft, with managed wrappers for ease of use.
Available as a NuGet package here.
LibraryImport and Span<T> for optimal performanceALDevice for device managementALContext for context creation and managementALCaptureDevice for microphone inputALSource for sourcesALFilter and ALReverbEffect for filters and effectsusing OpenAL;
using OpenAL.managed;
// Get all devices
var deviceNames = AL.GetStringList(IntPtr.Zero, AL.ALC_ALL_DEVICES_SPECIFIER);
// Open a device
var device = new ALDevice(deviceNames[0]);
// Create a context
var context = new ALContext(device, new ALContextSettings()
{
HRTFEnabled = true,
SampleRate = 48000
});
// Make the context current
context.MakeCurrent();
// Generate a buffer and source
uint buffer = AL.GenBuffer();
uint source = AL.GenSource();
// Load PCM data into the buffer
AL.BufferData(buffer, AL.AL_FORMAT_MONO16, pcmData, sampleRate);
// Configure and play the source
AL.Sourcei(source, AL.AL_BUFFER, (int)buffer);
AL.SourcePlay(source);
// Cleanup
AL.DeleteSource(source);
AL.DeleteBuffer(buffer);
context.Destroy();
device.Close();
// Generate an effect and auxiliary send
uint effect = AL.GenEffect();
uint auxSlot = AL.GenAuxiliaryEffectSlot();
// Configure reverb effect
AL.Effecti(effect, AL.AL_EFFECT_TYPE, AL.AL_EFFECT_REVERB);
AL.Effectf(effect, AL.AL_REVERB_GAIN, 0.7f);
AL.Effectf(effect, AL.AL_REVERB_DECAY_TIME, 2.5f);
// Attach effect to auxiliary slot
AL.AuxiliaryEffectSloti(auxSlot, AL.AL_EFFECTSLOT_EFFECT, (int)effect);
// Connect source to effect slot
AL.Source3i(source, AL.AL_AUXILIARY_SEND_FILTER, (int)auxSlot, 0, AL.AL_FILTER_NULL);
// Set listener orientation using span
Span<float> orientation = [ 0f, 0f, -1f, 0f, 1f, 0f ];
AL.Listenerfv(AL.AL_ORIENTATION, orientation);
// Position a source in 3D space
AL.Source3f(source, AL.AL_POSITION, 5f, 0f, -10f);
AL.Source3f(source, AL.AL_VELOCITY, 0f, 0f, 1f);
// Configure distance model
AL.DistanceModel(AL.AL_INVERSE_DISTANCE_CLAMPED);
AL.Sourcef(source, AL.AL_REFERENCE_DISTANCE, 1f);
AL.Sourcef(source, AL.AL_MAX_DISTANCE, 100f);
The library is organized into several layers:
internal/)Low-level P/Invoke declarations that directly wrap OpenAL native functions:
ALBindings.cs - Core OpenALALCBindings.cs - Context managementEFXBindings.cs - Effects and filtersALEXTBindings.cs - OpenAL extensionsDebugBindings.cs - Debug callbackpublic/)Clean C# wrappers for functions and constants:
AL.cs - Core OpenALALC.cs - Context managementAL.cs - Effects and filtersAL.cs - OpenAL extensions*Constants.cs - OpenAL constantsmanaged/)High-level classes for common use cases:
ALDevice.cs / ALCaptureDevice.cs - Device lifecycle managementALContext.cs - Context creation with HRTF supportALSource.cs - Audio source managementALFilter.cs - Filter managementALReverbEffect.cs - Reverb effect helpersOpenAL's error state is per-context rather than per-thread. For multithreaded applications:
MIT No Attribution
Copyright 2025 Vercidium Pty Ltd
See license.txt for full license text.
Contributions are welcome! The project follows modern C# conventions:
LibraryImport over DllImportThis is an actively developed project. Current focus areas: