diff --git a/Source/OpenTK/OpenAL/AudioContext.cs b/Source/OpenTK/OpenAL/AudioContext.cs new file mode 100644 index 00000000..b08131df --- /dev/null +++ b/Source/OpenTK/OpenAL/AudioContext.cs @@ -0,0 +1,190 @@ +#region --- License --- +/* Copyright (c) 2008 the OpenTK team + * See license.txt for license details + * http://www.opentk.com + */ +#endregion + +using System; +using System.Collections.Generic; +using System.Text; + +using OpenTK.OpenAL; +using OpenTK.OpenAL.Enums; + +namespace OpenTK.Audio +{ + /// + /// Provides methods to create and use an audio context. + /// + public sealed class AudioContext : IDisposable + { + #region --- Fields --- + + bool disposed; + static List available_devices; + IntPtr device_handle, context_handle; + static object audio_context_lock = new object(); + + #endregion + + #region --- Constructors --- + + // Runs before the actual class constructor, to load available devices. + static AudioContext() + { + LoadAvailableDevices(); + } + + /// Constructs a new AudioContext, using the default audio device. + /// Occurs when no audio devices are available. + public AudioContext() + { + if (available_devices.Count == 0) + throw new NotSupportedException("No audio hardware is available."); + CreateContext(available_devices[0], 44100, 0, false); + } + + /// Constructs a new AudioContext, using the specified audio device. + /// The name of the audio device to use. + /// + /// Use AudioContext.AvailableDevices to obtain a list of all available audio + /// devices. + /// + public AudioContext(string device) + { + + } + + #endregion + + #region --- Private Members --- + + #region static void LoadAvailableDevices() + + // Loads all available audio devices into the available_devices array. + static void LoadAvailableDevices() + { + lock (audio_context_lock) + { + if (available_devices == null) + { + available_devices = new List(); + available_devices.AddRange(Alc.GetString(IntPtr.Zero, OpenTK.OpenAL.Enums.AlcGetStringList.AllDevicesSpecifier)); + } + } + } + + #endregion + + #region void CreateContext(string device) + + /// + /// Creates the audio context using the specified device. + /// The device descriptor obtained through AudioContext.AvailableDevices. + /// Frequency for mixing output buffer, in units of Hz. + /// Refresh intervalls, in units of Hz. + /// Flag, indicating a synchronous context. + /// + /// Occurs when the specified device is not available, or is in use by another program. + /// + /// + /// Occurs when an audio context could not be created with the specified parameters. + /// + void CreateContext(string device, int freq, int refresh, bool sync) + { + if (String.IsNullOrEmpty(device)) throw new ArgumentNullException("device"); + if (freq < 0) throw new ArgumentOutOfRangeException("freq", freq, "Should be greater than zero"); + if (refresh < 0) throw new ArgumentOutOfRangeException("refresh", refresh, "Should be greater than zero"); + + device_handle = Alc.OpenDevice(device); + if (device_handle == IntPtr.Zero) + throw new InvalidAudioDeviceException(); + + List attributes = new List(); + if (freq != 0) + { + attributes.Add((int)AlcContextAttributes.Frequency); + attributes.Add(freq); + } + if (refresh != 0) + { + attributes.Add((int)AlcContextAttributes.Refresh); + attributes.Add(refresh); + } + attributes.Add((int)AlcContextAttributes.Frequency); + attributes.Add(sync ? 1 : 0); + + context_handle = Alc.CreateContext(device_handle, attributes.ToArray()); + if (context_handle == IntPtr.Zero) + { + Alc.CloseDevice(device_handle); + throw new InvalidAudioContextException(); + } + } + + + #endregion + + #endregion + + #region --- Public Members --- + + #region public static string[] AvailableDevices + + /// + /// Gets a System.String array containing all available audio devices. + /// + public static IEnumerable AvailableDevices + { + get + { + return (IEnumerable)available_devices; + } + } + + #endregion + + #endregion + + #region --- IDisposable Members --- + + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + void Dispose(bool manual) + { + if (!disposed) + { + if (manual) + { + } + disposed = true; + } + } + + ~AudioContext() + { + this.Dispose(false); + } + + #endregion + } + + #region --- Exceptions --- + + public class InvalidAudioDeviceException : Exception + { + public InvalidAudioDeviceException() : base("The specified audio device does not exist or is tied up by another application.") { } + } + + public class InvalidAudioContextException : Exception + { + public InvalidAudioContextException() : base("The audio context could not be created with the specified parameters.") { } + } + + #endregion +}