Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region License
2
//
3
// The Open Toolkit Library License
4
//
5
// Copyright (c) 2006 - 2009 the Open Toolkit library.
6
//
7
// Permission is hereby granted, free of charge, to any person obtaining a copy
8
// of this software and associated documentation files (the "Software"), to deal
9
// in the Software without restriction, including without limitation the rights to 
10
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11
// the Software, and to permit persons to whom the Software is furnished to do
12
// so, subject to the following conditions:
13
//
14
// The above copyright notice and this permission notice shall be included in all
15
// copies or substantial portions of the Software.
16
//
17
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
// OTHER DEALINGS IN THE SOFTWARE.
25
//
26
#endregion
27
 
28
using System;
29
using System.Collections.Generic;
30
using System.Collections.ObjectModel;
31
using System.Diagnostics;
32
 
33
using OpenTK.Audio.OpenAL;
34
 
35
namespace OpenTK.Audio
36
{
37
    internal static class AudioDeviceEnumerator
38
    {
39
        #region All device strings
40
 
41
        private static readonly List<string> available_playback_devices = new List<string>();
42
        private static readonly List<string> available_recording_devices = new List<string>();
43
 
44
        internal static IList<string> AvailablePlaybackDevices
45
        {
46
            get
47
            {
48
                return available_playback_devices.AsReadOnly();
49
            }
50
        }
51
        internal static IList<string> AvailableRecordingDevices
52
        {
53
            get
54
            {
55
                return available_recording_devices.AsReadOnly();
56
            }
57
        }
58
 
59
        #endregion All device strings
60
 
61
        #region Default device strings
62
 
63
        private static string default_playback_device;
64
        internal static string DefaultPlaybackDevice
65
        {
66
            get
67
            {
68
                return default_playback_device;
69
            }
70
        }
71
 
72
        private static string default_recording_device;
73
        internal static string DefaultRecordingDevice
74
        {
75
            get
76
            {
77
                return default_recording_device;
78
            }
79
        }
80
 
81
        #endregion Default device strings
82
 
83
        #region Is OpenAL supported?
84
 
85
        private static bool openal_supported = true;
86
        internal static bool IsOpenALSupported
87
        {
88
            get
89
            {
90
                return openal_supported;
91
            }
92
        }
93
 
94
        #endregion Is OpenAL supported?
95
 
96
        #region Alc Version number
97
 
98
        internal enum AlcVersion
99
        {
100
            Alc1_0,
101
            Alc1_1
102
        }
103
 
104
        private static AlcVersion version;
105
        internal static AlcVersion Version
106
        {
107
            get
108
            {
109
                return version;
110
            }
111
        }
112
 
113
        #endregion Alc Version number
114
 
115
        #region Constructors
116
 
117
        // Loads all available audio devices into the available_*_devices lists.
118
        static AudioDeviceEnumerator()
119
        {
120
            IntPtr dummy_device = IntPtr.Zero;
121
            ContextHandle dummy_context = ContextHandle.Zero;
122
 
123
            try
124
            {
125
                Debug.WriteLine("Enumerating audio devices.");
126
                Debug.Indent();
127
 
128
                // need a dummy context for correct results
129
                dummy_device = Alc.OpenDevice(null);
130
                dummy_context = Alc.CreateContext(dummy_device, (int[])null);
131
                bool dummy_success = Alc.MakeContextCurrent(dummy_context);
132
                AlcError dummy_error = Alc.GetError(dummy_device);
133
                if (!dummy_success || dummy_error != AlcError.NoError)
134
                {
135
                    throw new AudioContextException("Failed to create dummy Context. Device (" + dummy_device.ToString() +
136
                                                    ") Context (" + dummy_context.Handle.ToString() +
137
                                                    ") MakeContextCurrent " + (dummy_success ? "succeeded" : "failed") +
138
                                                    ", Alc Error (" + dummy_error.ToString() + ") " + Alc.GetString(IntPtr.Zero, (AlcGetString)dummy_error));
139
                }
140
 
141
                // Get a list of all known playback devices, using best extension available
142
                if (Alc.IsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATION_EXT"))
143
                {
144
                    version = AlcVersion.Alc1_1;
145
                    if (Alc.IsExtensionPresent(IntPtr.Zero, "ALC_ENUMERATE_ALL_EXT"))
146
                    {
147
                        available_playback_devices.AddRange(Alc.GetString(IntPtr.Zero, AlcGetStringList.AllDevicesSpecifier));
148
                        default_playback_device = Alc.GetString(IntPtr.Zero, AlcGetString.DefaultAllDevicesSpecifier);
149
                    }
150
                    else
151
                    {
152
                        available_playback_devices.AddRange(Alc.GetString(IntPtr.Zero, AlcGetStringList.DeviceSpecifier));
153
                        default_playback_device = Alc.GetString(IntPtr.Zero, AlcGetString.DefaultDeviceSpecifier);
154
                    }
155
                }
156
                else
157
                {
158
                    version = AlcVersion.Alc1_0;
159
                    Debug.Print("Device enumeration extension not available. Failed to enumerate playback devices.");
160
                }
161
                AlcError playback_err = Alc.GetError(dummy_device);
162
                if (playback_err != AlcError.NoError)
163
                    throw new AudioContextException("Alc Error occured when querying available playback devices. " + playback_err.ToString());
164
 
165
                // Get a list of all known recording devices, at least ALC_ENUMERATION_EXT is needed too
166
                if (version == AlcVersion.Alc1_1 && Alc.IsExtensionPresent(IntPtr.Zero, "ALC_EXT_CAPTURE"))
167
                {
168
                    available_recording_devices.AddRange(Alc.GetString(IntPtr.Zero, AlcGetStringList.CaptureDeviceSpecifier));
169
                    default_recording_device = Alc.GetString(IntPtr.Zero, AlcGetString.CaptureDefaultDeviceSpecifier);
170
                }
171
                else
172
                {
173
                    Debug.Print("Capture extension not available. Failed to enumerate recording devices.");
174
                }
175
                AlcError record_err = Alc.GetError(dummy_device);
176
                if (record_err != AlcError.NoError)
177
                    throw new AudioContextException("Alc Error occured when querying available recording devices. " + record_err.ToString());
178
 
179
#if DEBUG
180
                Debug.WriteLine("Found playback devices:");
181
                foreach (string s in available_playback_devices)
182
                    Debug.WriteLine(s);
183
 
184
                Debug.WriteLine("Default playback device: " + default_playback_device);
185
 
186
                Debug.WriteLine("Found recording devices:");
187
                foreach (string s in available_recording_devices)
188
                    Debug.WriteLine(s);
189
 
190
                Debug.WriteLine("Default recording device: " + default_recording_device);
191
#endif
192
            }
193
            catch (DllNotFoundException e)
194
            {
195
                Trace.WriteLine(e.ToString());
196
                openal_supported = false;
197
            }
198
            catch (AudioContextException ace)
199
            {
200
                Trace.WriteLine(ace.ToString());
201
                openal_supported = false;
202
            }
203
            finally
204
            {
205
                Debug.Unindent();
206
 
207
                // clean up the dummy context
208
                Alc.MakeContextCurrent(ContextHandle.Zero);
209
                if (dummy_context != ContextHandle.Zero && dummy_context.Handle != IntPtr.Zero)
210
                    Alc.DestroyContext(dummy_context);
211
                if (dummy_device != IntPtr.Zero)
212
                    Alc.CloseDevice(dummy_device);
213
            }
214
        }
215
 
216
        #endregion
217
    }
218
}