2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Collections.Generic;
20 namespace Tizen.Multimedia
23 /// Provides the ability to control volume levels and monitor audio devices.
25 /// <since_tizen> 3 </since_tizen>
26 public static class AudioManager
30 VolumeController = new AudioVolume();
34 /// Gets the volume controller.
36 /// <value>The <see cref="AudioVolume"/>.</value>
37 /// <since_tizen> 3 </since_tizen>
38 public static AudioVolume VolumeController { get; }
41 /// Gets the all devices currently connected.
43 /// <returns>An IEnumerable<AudioDevice> that contains connected devices.</returns>
44 /// <since_tizen> 4 </since_tizen>
45 public static IEnumerable<AudioDevice> GetConnectedDevices()
47 IntPtr deviceListHandle = IntPtr.Zero;
51 var ret = Interop.AudioDevice.GetDeviceList(AudioDeviceOptions.All, out deviceListHandle);
53 if (ret == AudioManagerError.NoData)
55 return new List<AudioDevice>();
58 ret.ThrowIfError("Failed to get connected devices");
60 return RetrieveDevices();
64 Interop.AudioDevice.FreeDeviceList(deviceListHandle);
67 IEnumerable<AudioDevice> RetrieveDevices()
69 var result = new List<AudioDevice>();
73 var ret = Interop.AudioDevice.GetNextDevice(deviceListHandle, out var deviceHandle);
75 if (ret == AudioManagerError.NoData)
80 ret.ThrowIfError("Failed to get connected devices");
82 result.Add(new AudioDevice(deviceHandle));
88 #region DeviceConnectionChanged event
89 private static int _deviceConnectionChangedCallbackId = -1;
91 private static Interop.AudioDevice.ConnectionChangedCallback _audioDeviceConnectionChangedCallback;
92 private static EventHandler<AudioDeviceConnectionChangedEventArgs> _audioDeviceConnectionChanged;
93 private static readonly object _audioDeviceConnectionLock = new object();
96 /// Occurs when the state of a connection of an audio device changes.
98 /// <since_tizen> 3 </since_tizen>
99 public static event EventHandler<AudioDeviceConnectionChangedEventArgs> DeviceConnectionChanged
108 lock (_audioDeviceConnectionLock)
110 if (_audioDeviceConnectionChanged == null)
112 RegisterAudioDeviceEvent();
114 _audioDeviceConnectionChanged += value;
124 lock (_audioDeviceConnectionLock)
126 if (_audioDeviceConnectionChanged == value)
128 UnregisterDeviceConnectionChangedEvent();
130 _audioDeviceConnectionChanged -= value;
135 private static void RegisterAudioDeviceEvent()
137 _audioDeviceConnectionChangedCallback = (device, isConnected, _) =>
139 _audioDeviceConnectionChanged?.Invoke(null,
140 new AudioDeviceConnectionChangedEventArgs(new AudioDevice(device), isConnected));
143 Interop.AudioDevice.AddDeviceConnectionChangedCallback(AudioDeviceOptions.All,
144 _audioDeviceConnectionChangedCallback, IntPtr.Zero, out _deviceConnectionChangedCallbackId).
145 ThrowIfError("Unable to add device connection changed callback");
148 private static void UnregisterDeviceConnectionChangedEvent()
150 Interop.AudioDevice.RemoveDeviceConnectionChangedCallback(_deviceConnectionChangedCallbackId).
151 ThrowIfError("Unable to remove device connection changed callback");
155 #region DeviceStateChanged event
156 private static int _deviceStateChangedCallbackId = -1;
158 #pragma warning disable CS0618 // Type or member is obsolete
160 private static Interop.AudioDevice.StateChangedCallback _audioDeviceStateChangedCallback;
161 private static EventHandler<AudioDeviceStateChangedEventArgs> _audioDeviceStateChanged;
162 private static readonly object _audioDeviceStateLock = new object();
165 /// Occurs when the state of an audio device changes.
167 /// <since_tizen> 3 </since_tizen>
168 [Obsolete("Deprecated since API level 5. Please use the DeviceRunningStateChanged property instead.")]
169 public static event EventHandler<AudioDeviceStateChangedEventArgs> DeviceStateChanged
178 lock (_audioDeviceStateLock)
180 if (_audioDeviceStateChanged == null)
182 RegisterDeviceStateChangedEvent();
184 _audioDeviceStateChanged += value;
194 lock (_audioDeviceStateLock)
196 if (_audioDeviceStateChanged == value)
198 UnregisterDeviceStateChangedEvent();
200 _audioDeviceStateChanged -= value;
205 private static void RegisterDeviceStateChangedEvent()
207 _audioDeviceStateChangedCallback = (device, changedState, _) =>
209 _audioDeviceStateChanged?.Invoke(null,
210 new AudioDeviceStateChangedEventArgs(new AudioDevice(device), changedState));
213 Interop.AudioDevice.AddDeviceStateChangedCallback(AudioDeviceOptions.All,
214 _audioDeviceStateChangedCallback, IntPtr.Zero, out _deviceStateChangedCallbackId).
215 ThrowIfError("Failed to add device state changed event");
218 #pragma warning restore CS0618 // Type or member is obsolete
220 private static void UnregisterDeviceStateChangedEvent()
222 Interop.AudioDevice.RemoveDeviceStateChangedCallback(_deviceStateChangedCallbackId).
223 ThrowIfError("Failed to remove device state changed event");
227 #region DeviceRunningStateChanged event
228 private static int _deviceRunningChangedCallbackId = -1;
229 private static Interop.AudioDevice.RunningChangedCallback _audioDeviceRunningChangedCallback;
230 private static EventHandler<AudioDeviceRunningChangedEventArgs> _audioDeviceRunningChanged;
231 private static readonly object _audioDeviceRunningLock = new object();
234 /// Occurs when the audio stream started actually to run on the device.
237 /// If this event is invoked once and the audio stream is still running on the device,<br/>
238 /// this event will not be invoked anymore, even if there are more audio streams to run.<br/>
239 /// This event is invoked only when all streams are stopped and a new stream starts to run.
241 /// <exception cref="InvalidOperationException">
242 /// AudioManager failed to communicate internally or allocate memory.
244 /// <since_tizen> 5 </since_tizen>
245 public static event EventHandler<AudioDeviceRunningChangedEventArgs> DeviceRunningChanged
253 lock (_audioDeviceRunningLock)
255 if (_audioDeviceRunningChanged == null)
257 RegisterDeviceRunningChangedEvent();
259 _audioDeviceRunningChanged += value;
268 lock (_audioDeviceRunningLock)
270 _audioDeviceRunningChanged -= value;
271 if (_audioDeviceRunningChanged == null)
273 UnregisterDeviceRunningChangedEvent();
279 private static void RegisterDeviceRunningChangedEvent()
281 _audioDeviceRunningChangedCallback = (device, isRunning, _) =>
283 _audioDeviceRunningChanged?.Invoke(null,
284 new AudioDeviceRunningChangedEventArgs(new AudioDevice(device), isRunning));
286 Interop.AudioDevice.AddDeviceRunningChangedCallback(AudioDeviceOptions.All,
287 _audioDeviceRunningChangedCallback, IntPtr.Zero, out _deviceRunningChangedCallbackId).
288 ThrowIfError("Failed to add DeviceRunningChanged event");
291 private static void UnregisterDeviceRunningChangedEvent()
293 Interop.AudioDevice.RemoveDeviceRunningChangedCallback(_deviceRunningChangedCallbackId).
294 ThrowIfError("Failed to remove DeviceRunningChanged event");