1. Devices, Buffers and X-Ram

OpenTK.Audio.AudioContext handles Device and Context allocation through Alc.

Instantiating a new AudioContext with a parameterless constructor will initialize the default Device and Context and makes it current. Calling the instance's Dispose method will destroy the Device and Context.

Buffers
Buffers in OpenAL are merely the storage for audio data in raw format, a Buffer Name (often called Handle) must be generated using AL.GenBuffers(). This buffer can now be filled using AL.BufferData() or using the AudioReader class (which loads a file from disk). The AudioReader functions implicitly use AL.BufferData() to pass the raw sound data into OpenAL's internal memory.

X-Ram
The X-Ram Extension allows to manually assign Buffers a storage space, it's use is optional and not required. To use the Extension, the XRam wrapper must be instantiated (per used Device), which will take care of most ugly things with Extensions for you. The instantiated object contains a bool that returns if the Extension is usable, which should be checked before calling one of the Extension's Methods.

Example code:

try
{
AudioContext AC = new AudioContext();
} catch( AudioException e)
{ // problem with Device or Context, cannot continue
  Application.Exit();
}
 
XRam = new XRamExtension( ); // must be instantiated per used Device if X-Ram is desired.
 
// reserve 2 Handles
uint[] MyBuffers = new uint[2]; 
AL.GenBuffers( 2, out MyBuffers ); 
 
// Load a .wav file from disk
if ( XRam.IsInitialized ) XRam.SetBufferMode( ref MyBuffer[0], XRamStorage.Hardware ); // optional
 
AudioReader sound = new AudioReader(filename)
AL.BufferData(MyBuffers[0], sound.ReadToEnd());
if ( AL.GetError() != ALError.NoError )
{
   // respond to load error etc.
}
 
// Create a sinus waveform through parameters, this currently requires Alut.dll in the application directory
if ( XRam.IsInitialized ) XRam.SetBufferMode( ref MyBuffer[1], XRamStorage.Hardware ); // optional
MyBuffers[1] = Alut.CreateBufferWaveform(AlutWaveform.Sine, 500f, 42f, 1.5f);
 
// See next book page how to connect the buffers to sources in order to play them.
 
// Cleanup on application shutdown
AL.DeleteBuffers( 2, ref MyBuffers ); // free previously reserved Handles
AC.Dispose();

A description of the sound data in the Buffer can be queried using AL.GetBuffer().

Now that the Buffer Handle has been assigned a sound, we need to attach it to a Source for playback.