00001 #region License
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #endregion
00027
00028 using System;
00029 using System.Collections.Generic;
00030 using System.Collections.ObjectModel;
00031 using System.Diagnostics;
00032
00033 using OpenTK.Audio.OpenAL;
00034
00035 namespace OpenTK.Audio
00036 {
00037 internal static class AudioDeviceEnumerator
00038 {
00039 #region All device strings
00040
00041 private static readonly List<string> available_playback_devices = new List<string>();
00042 private static readonly List<string> available_recording_devices = new List<string>();
00043
00044 internal static IList<string> AvailablePlaybackDevices
00045 {
00046 get
00047 {
00048 return available_playback_devices.AsReadOnly();
00049 }
00050 }
00051 internal static IList<string> AvailableRecordingDevices
00052 {
00053 get
00054 {
00055 return available_recording_devices.AsReadOnly();
00056 }
00057 }
00058
00059 #endregion All device strings
00060
00061 #region Default device strings
00062
00063 private static string default_playback_device;
00064 internal static string DefaultPlaybackDevice
00065 {
00066 get
00067 {
00068 return default_playback_device;
00069 }
00070 }
00071
00072 private static string default_recording_device;
00073 internal static string DefaultRecordingDevice
00074 {
00075 get
00076 {
00077 return default_recording_device;
00078 }
00079 }
00080
00081 #endregion Default device strings
00082
00083 #region Is OpenAL supported?
00084
00085 private static bool openal_supported = true;
00086 internal static bool IsOpenALSupported
00087 {
00088 get
00089 {
00090 return openal_supported;
00091 }
00092 }
00093
00094 #endregion Is OpenAL supported?
00095
00096 #region Alc Version number
00097
00098 internal enum AlcVersion
00099 {
00100 Alc1_0,
00101 Alc1_1
00102 }
00103
00104 private static AlcVersion version;
00105 internal static AlcVersion Version
00106 {
00107 get
00108 {
00109 return version;
00110 }
00111 }
00112
00113 #endregion Alc Version number
00114
00115 #region Constructors
00116
00117
00118 static AudioDeviceEnumerator()
00119 {
00120 IntPtr dummy_device = IntPtr.Zero;
00121 ContextHandle dummy_context = ContextHandle.Zero;
00122
00123 try
00124 {
00125 Debug.WriteLine("Enumerating audio devices.");
00126 Debug.Indent();
00127
00128
00129 dummy_device = Alc.OpenDevice(null);
00130 dummy_context = Alc.CreateContext(dummy_device, (int[])null);
00131 bool dummy_success = Alc.MakeContextCurrent(dummy_context);
00132 AlcError dummy_error = Alc.GetError(dummy_device);
00133 if (!dummy_success || dummy_error != AlcError.NoError)
00134 {
00135 throw new AudioContextException("Failed to create dummy Context. Device (" + dummy_device.ToString() +
00136 ") Context (" + dummy_context.Handle.ToString() +
00137 ") MakeContextCurrent " + (dummy_success ? "succeeded" : "failed") +
00138 ", Alc Error (" + dummy_error.ToString() + ") " + Alc.GetString(IntPtr.Zero, (AlcGetString)dummy_error));
00139 }
00140
00141
00142 if (Alc.IsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATION_EXT"))
00143 {
00144 version = AlcVersion.Alc1_1;
00145 if (Alc.IsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATE_ALL_EXT"))
00146 {
00147 available_playback_devices.AddRange(Alc.GetString(IntPtr.Zero, AlcGetStringList.AllDevicesSpecifier));
00148 default_playback_device = Alc.GetString(IntPtr.Zero, AlcGetString.DefaultAllDevicesSpecifier);
00149 }
00150 else
00151 {
00152 available_playback_devices.AddRange(Alc.GetString(IntPtr.Zero, AlcGetStringList.DeviceSpecifier));
00153 default_playback_device = Alc.GetString(IntPtr.Zero, AlcGetString.DefaultDeviceSpecifier);
00154 }
00155 }
00156 else
00157 {
00158 version = AlcVersion.Alc1_0;
00159 Debug.Print("Device enumeration extension not available. Failed to enumerate playback devices.");
00160 }
00161 AlcError playback_err = Alc.GetError(dummy_device);
00162 if (playback_err != AlcError.NoError)
00163 throw new AudioContextException("Alc Error occured when querying available playback devices. " + playback_err.ToString());
00164
00165
00166 if (version == AlcVersion.Alc1_1 && Alc.IsExtensionPresent(IntPtr.Zero, "ALC_EXT_CAPTURE"))
00167 {
00168 available_recording_devices.AddRange(Alc.GetString(IntPtr.Zero, AlcGetStringList.CaptureDeviceSpecifier));
00169 default_recording_device = Alc.GetString(IntPtr.Zero, AlcGetString.CaptureDefaultDeviceSpecifier);
00170 }
00171 else
00172 {
00173 Debug.Print("Capture extension not available. Failed to enumerate recording devices.");
00174 }
00175 AlcError record_err = Alc.GetError(dummy_device);
00176 if (record_err != AlcError.NoError)
00177 throw new AudioContextException("Alc Error occured when querying available recording devices. " + record_err.ToString());
00178
00179 #if DEBUG
00180 Debug.WriteLine("Found playback devices:");
00181 foreach (string s in available_playback_devices)
00182 Debug.WriteLine(s);
00183
00184 Debug.WriteLine("Default playback device: " + default_playback_device);
00185
00186 Debug.WriteLine("Found recording devices:");
00187 foreach (string s in available_recording_devices)
00188 Debug.WriteLine(s);
00189
00190 Debug.WriteLine("Default recording device: " + default_recording_device);
00191 #endif
00192 }
00193 catch (DllNotFoundException e)
00194 {
00195 Trace.WriteLine(e.ToString());
00196 openal_supported = false;
00197 }
00198 catch (AudioContextException ace)
00199 {
00200 Trace.WriteLine(ace.ToString());
00201 openal_supported = false;
00202 }
00203 finally
00204 {
00205 Debug.Unindent();
00206
00207
00208 Alc.MakeContextCurrent(ContextHandle.Zero);
00209 if (dummy_context != ContextHandle.Zero && dummy_context.Handle != IntPtr.Zero)
00210 Alc.DestroyContext(dummy_context);
00211 if (dummy_device != IntPtr.Zero)
00212 Alc.CloseDevice(dummy_device);
00213 }
00214 }
00215
00216 #endregion
00217 }
00218 }