diff --git a/Source/OpenTK/Audio/AudioContext.cs b/Source/OpenTK/Audio/AudioContext.cs index 9d9ba1c7..357eeda1 100644 --- a/Source/OpenTK/Audio/AudioContext.cs +++ b/Source/OpenTK/Audio/AudioContext.cs @@ -29,6 +29,7 @@ namespace OpenTK.Audio static object audio_context_lock = new object(); static List available_devices = new List(); static Dictionary available_contexts = new Dictionary(); + bool context_exists; #endregion @@ -41,10 +42,10 @@ namespace OpenTK.Audio /// /// Runs before the actual class constructor, to load available devices. /// - //static AudioContext() - //{ - // LoadAvailableDevices(); - //} + static AudioContext() + { + LoadAvailableDevices(); + } #endregion @@ -115,14 +116,14 @@ namespace OpenTK.Audio #endregion - #region public AudioContext(string device, int freq, int refresh, bool sync, int maxEfxSends) + #region public AudioContext(string device, int freq, int refresh, bool sync, int maxSends) /// Creates the audio context using the specified device and device parameters. /// The device descriptor obtained through AudioContext.AvailableDevices. /// Frequency for mixing output buffer, in units of Hz. Pass 0 for driver default. /// Refresh intervals, in units of Hz. Pass 0 for driver default. /// Flag, indicating a synchronous context. - /// Number of auxilliary send slots for the EFX extensions. Can be 0 (use driver default) or higher. + /// Number of auxilliary send slots for the EFX extensions. Can be 0 (use driver default) or higher. /// Occurs when the device string is invalid. /// Occurs when a specified parameter is invalid. /// @@ -131,19 +132,20 @@ namespace OpenTK.Audio /// /// Occurs when an audio context could not be created with the specified parameters. /// + /// + /// Occurs when an AudioContext already exists. /// - /// - /// Use AudioContext.AvailableDevices to obtain a list of all available audio devices. - /// + /// For maximum compatibility, you are strongly recommended to use the default constructor. + /// Multiple AudioContexts are not supported at this point. /// /// The number of auxilliary EFX sends depends on the audio hardware and drivers. Most Realtek devices, as well /// as the Creative SB Live!, support 1 auxilliary send. Creative's Audigy and X-Fi series support 4 sends. - /// Values not supported will be clamped by the driver. + /// Values higher than supported will be clamped by the driver. /// /// - public AudioContext(string device, int freq, int refresh, bool sync, int maxEfxSends) + public AudioContext(string device, int freq, int refresh, bool sync, int maxSends) { - CreateContext(device, freq, refresh, sync, maxEfxSends); + CreateContext(device, freq, refresh, sync, maxSends); } #endregion @@ -195,26 +197,26 @@ namespace OpenTK.Audio /// /// Occurs when an audio context could not be created with the specified parameters. /// + /// + /// Occurs when an AudioContext already exists. /// + /// For maximum compatibility, you are strongly recommended to use the default constructor. + /// Multiple AudioContexts are not supported at this point. + /// /// The number of auxilliary EFX sends depends on the audio hardware and drivers. Most Realtek devices, as well /// as the Creative SB Live!, support 1 auxilliary send. Creative's Audigy and X-Fi series support 4 sends. /// Values higher than supported will be clamped by the driver. + /// /// void CreateContext(string device, int freq, int refresh, bool sync, int maxEfxSends) { + if (context_exists) throw new NotSupportedException("Multiple AudioContexts not supported."); //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."); if (maxEfxSends < 0) throw new ArgumentOutOfRangeException("maxEfxSends", maxEfxSends, "Should be greater than zero."); //if (available_devices.Count == 0) throw new NotSupportedException("No audio hardware is available."); - if (available_devices.Count == 0) - LoadAvailableDevices(); - - // HACK: Do not allow multiple contexts under linux (crashes under Ubuntu 7.04 and 7.10) - if (available_contexts.Count > 0) - throw new NotSupportedException("Multiple AudioContexts are not supported under Linux."); - device_handle = Alc.OpenDevice(device); if (device_handle == IntPtr.Zero) throw new AudioDeviceException("The specified audio device does not exist or is tied up by another application."); @@ -268,6 +270,7 @@ namespace OpenTK.Audio lock (audio_context_lock) { available_contexts.Add(this.context_handle, this); + context_exists = true; } } @@ -312,79 +315,6 @@ namespace OpenTK.Audio // TODO: Remove before release! public IntPtr Device { get { return device_handle.Handle; } } - #region --- Public Members --- - - #region public static string[] AvailableDevices - - /// - /// Gets a System.String array containing all available audio devices. - /// - /// This property allocates memory. - public static string[] AvailableDevices - { - get - { - if (available_devices.Count == 0) - LoadAvailableDevices(); - return available_devices.ToArray(); - } - } - - #endregion - - #region public void MakeCurrent() - - /// Makes the AudioContext current in the calling thread. - /// - /// Occurs if this function is called after the AudioContext has been disposed. - /// - /// - /// Occurs when the AudioContext could not be made current. - /// - /// - /// Only one AudioContext can be current in the application at any time, - /// regardless of the number of threads. - /// - public void MakeCurrent() - { - AudioContext.MakeCurrent(this); - } - - #endregion - - #region public bool IsCurrent - - /// - /// Gets or sets a System.Boolean indicating whether the AudioContext - /// is current. - /// - /// - /// Only one AudioContext can be current in the application at any time, - /// regardless of the number of threads. - /// - public bool IsCurrent - { - get - { - lock (audio_context_lock) - { - if (available_contexts.Count == 0) - return false; - else - { - return AudioContext.CurrentContext == this; - } - } - } - set - { - if (value) AudioContext.MakeCurrent(this); - else AudioContext.MakeCurrent(null); - } - } - - #endregion - #region public bool IsProcessing /// @@ -492,6 +422,79 @@ namespace OpenTK.Audio #endregion + #region --- Public Members --- + + #region public static string[] AvailableDevices + + /// + /// Gets a System.String array containing all available audio devices. + /// + /// This property allocates memory. + public static string[] AvailableDevices + { + get + { + if (available_devices.Count == 0) + LoadAvailableDevices(); + return available_devices.ToArray(); + } + } + + #endregion + + #endregion + + #region internal void MakeCurrent() + + /// Makes the AudioContext current in the calling thread. + /// + /// Occurs if this function is called after the AudioContext has been disposed. + /// + /// + /// Occurs when the AudioContext could not be made current. + /// + /// + /// Only one AudioContext can be current in the application at any time, + /// regardless of the number of threads. + /// + internal void MakeCurrent() + { + AudioContext.MakeCurrent(this); + } + + #endregion + + #region internal bool IsCurrent + + /// + /// Gets or sets a System.Boolean indicating whether the AudioContext + /// is current. + /// + /// + /// Only one AudioContext can be current in the application at any time, + /// regardless of the number of threads. + /// + internal bool IsCurrent + { + get + { + lock (audio_context_lock) + { + if (available_contexts.Count == 0) + return false; + else + { + return AudioContext.CurrentContext == this; + } + } + } + set + { + if (value) AudioContext.MakeCurrent(this); + else AudioContext.MakeCurrent(null); + } + } + #endregion #region --- IDisposable Members ---