2 * Copyright (c) 2018 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.Runtime.InteropServices;
19 using System.Collections.Generic;
22 namespace Tizen.Multimedia
25 /// Provides the ability to query the information of sound devices.
27 /// <since_tizen> 3 </since_tizen>
28 public class AudioDevice
30 private readonly int _id;
31 private readonly AudioDeviceType _type;
32 private readonly AudioDeviceIoDirection _ioDirection;
33 private const string Tag = "Tizen.Multimedia.AudioDevice";
35 internal AudioDevice(IntPtr deviceHandle)
37 int ret = Interop.AudioDevice.GetDeviceId(deviceHandle, out _id);
38 MultimediaDebug.AssertNoError(ret);
40 ret = Interop.AudioDevice.GetDeviceName(deviceHandle, out var name);
41 MultimediaDebug.AssertNoError(ret);
43 Name = Marshal.PtrToStringAnsi(name);
45 ret = Interop.AudioDevice.GetDeviceType(deviceHandle, out _type);
46 MultimediaDebug.AssertNoError(ret);
48 ret = Interop.AudioDevice.GetDeviceIoDirection(deviceHandle, out _ioDirection);
49 MultimediaDebug.AssertNoError(ret);
53 /// Gets the ID of the device.
55 /// <value>The id of the device.</value>
56 /// <since_tizen> 3 </since_tizen>
60 /// Gets the name of the device.
62 /// <value>The name of the device.</value>
63 /// <since_tizen> 3 </since_tizen>
64 public string Name { get; }
67 /// Gets the type of the device.
69 /// <value>The <see cref="AudioDeviceType"/> of the device.</value>
70 /// <since_tizen> 3 </since_tizen>
71 public AudioDeviceType Type => _type;
74 /// Gets the IO direction of the device.
76 /// <value>The IO direction of the device.</value>
77 /// <since_tizen> 3 </since_tizen>
78 public AudioDeviceIoDirection IoDirection => _ioDirection;
81 /// Gets the state of the device.
83 /// <value>The <see cref="AudioDeviceState"/> of the device.</value>
84 /// <since_tizen> 3 </since_tizen>
85 [Obsolete("Deprecated since API level 5. Please use the IsRunning property instead.")]
86 public AudioDeviceState State
90 Interop.AudioDevice.GetDeviceState(Id, out var state).
91 ThrowIfError("Failed to get the state of the device");
98 /// Gets the running state of the device.
100 /// <value>true if the audio stream of device is running actually; otherwise, false.</value>
101 /// <since_tizen> 5 </since_tizen>
102 public bool IsRunning
106 Interop.AudioDevice.IsDeviceRunning(_id, out bool isRunning).
107 ThrowIfError("Failed to get the running state of the device");
114 /// Gets the device's supported sample formats.
116 /// <returns>An IEnumerable<AudioSampleFormat> that contains supported sample formats.</returns>
118 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
120 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
121 /// <since_tizen> 5 </since_tizen>
122 public IEnumerable<AudioSampleFormat> GetSupportedSampleFormats()
124 Interop.AudioDevice.GetSupportedSampleFormats(_id, out IntPtr formats, out uint numberOfElements).
125 ThrowIfError("Failed to get supported sample formats");
127 return RetrieveFormats();
129 IEnumerable<AudioSampleFormat> RetrieveFormats()
131 int[] formatsResult = new int[numberOfElements];
133 Marshal.Copy(formats, formatsResult, 0, (int)numberOfElements);
134 Interop.Libc.Free(formats);
136 foreach (int f in formatsResult)
138 Log.Debug(Tag, $"supported sample format:{f}");
141 return formatsResult.Cast<AudioSampleFormat>();
146 /// Sets the device's sample format.
148 /// <param name="format">The <see cref="AudioSampleFormat"/> to set to the device.</param>
150 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
152 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
153 /// <since_tizen> 5 </since_tizen>
154 public void SetSampleFormat(AudioSampleFormat format)
156 Interop.AudioDevice.SetSampleFormat(_id, format).
157 ThrowIfError("Failed to set sample format of the device");
161 /// Gets the device's sample format.
163 /// <returns>The <see cref="AudioSampleFormat"/> of the device.</returns>
165 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
167 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
168 /// <since_tizen> 5 </since_tizen>
169 public AudioSampleFormat GetSampleFormat()
171 Interop.AudioDevice.GetSampleFormat(_id, out AudioSampleFormat format).
172 ThrowIfError("Failed to get sample format of the device");
177 private uint ConvertCoreRateValToUint(int value)
182 case 1: return 16000;
183 case 2: return 22050;
184 case 3: return 44100;
185 case 4: return 48000;
186 case 5: return 88200;
187 case 6: return 96000;
188 case 7: return 192000;
190 Log.Error(Tag, $"unknown value from core:{value}");
195 private uint ConvertRateToCoreValue(uint rate)
200 case 16000: return 1;
201 case 22050: return 2;
202 case 44100: return 3;
203 case 48000: return 4;
204 case 88200: return 5;
205 case 96000: return 6;
206 case 192000: return 7;
208 Log.Error(Tag, $"not supported rate:{rate}");
214 /// Gets the device's supported sample rates.
216 /// <returns>An IEnumerable<uint> that contains supported sample rates.</returns>
218 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
220 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
221 /// <since_tizen> 5 </since_tizen>
222 public IEnumerable<uint> GetSupportedSampleRates()
224 Interop.AudioDevice.GetSupportedSampleRates(_id, out IntPtr rates, out uint numberOfElements).
225 ThrowIfError("Failed to get supported sample formats");
227 return RetrieveRates();
229 IEnumerable<uint> RetrieveRates()
231 int[] ratesResult = new int[numberOfElements];
232 uint[] convertedRates = new uint[numberOfElements];
234 Marshal.Copy(rates, ratesResult, 0, (int)numberOfElements);
235 Interop.Libc.Free(rates);
237 for (int i = 0; i < ratesResult.Length; i++)
239 convertedRates[i] = ConvertCoreRateValToUint(ratesResult[i]);
240 Log.Debug(Tag, $"supported sample rate:{convertedRates[i]}");
243 return convertedRates;
248 /// Sets the device's sample rate.
250 /// <param name="rate">The sample rate to set to the device.</param>
252 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
254 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
255 /// <since_tizen> 5 </since_tizen>
256 public void SetSampleRate(uint rate)
258 Interop.AudioDevice.SetSampleRate(_id, ConvertRateToCoreValue(rate)).
259 ThrowIfError("Failed to set sample rate of the device");
263 /// Gets the device's sample rate.
265 /// <returns>The sample rate of the device.</returns>
267 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
269 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
270 /// <since_tizen> 5 </since_tizen>
271 public uint GetSampleRate()
273 Interop.AudioDevice.GetSampleRate(_id, out uint rate).
274 ThrowIfError("Failed to get sample rate of the device");
276 return ConvertCoreRateValToUint((int)rate);
280 /// Sets the device's 'avoid resampling' property.
282 /// <param name="enable">The 'avoid resampling' value to set to the device.</param>
284 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
285 /// This property is not enabled as default. With this enabled, this device will use the first stream's original sample format
286 /// and rate without resampling if supported.
288 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
289 /// <since_tizen> 5 </since_tizen>
290 public void SetAvoidResampling(bool enable)
292 Interop.AudioDevice.SetAvoidResampling(_id, enable).
293 ThrowIfError("Failed to set avoid-resampling property of the device");
298 /// Gets the device's 'avoid resampling' property.
300 /// <returns>The 'avoid resampling' property of the device.</returns>
302 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
303 /// This property is not enabled as default. With this enabled, this device will use the first stream's original sample format
304 /// and rate without resampling if supported.
306 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
307 /// <since_tizen> 5 </since_tizen>
308 public bool GetAvoidResampling()
310 Interop.AudioDevice.GetAvoidResampling(_id, out bool enabled).
311 ThrowIfError("Failed to get avoid-resampling property of the device");
317 /// Sets the restriction of stream type only for media.
319 /// <param name="enable">The 'media stream only' value to set to the device.</param>
321 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
322 /// This property is not enabled as default. With this enabled, no other stream types except <see cref="AudioStreamType.Media"/>
323 /// are not allowed to this device.
325 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
326 /// <since_tizen> 5 </since_tizen>
327 public void SetMediaStreamOnly(bool enable)
329 Interop.AudioDevice.SetMediaStreamOnly(_id, enable).
330 ThrowIfError("Failed to set media-stream-only property of the device");
334 /// Gets the restriction of stream type only for media.
336 /// <returns>The 'media stream only' property of the device.</returns>
338 /// This device should be <see cref="AudioDeviceType.UsbAudio"/> type and <see cref="AudioDeviceIoDirection.Output"/> direction.
339 /// This property is not enabled as default. With this enabled, no other stream types except <see cref="AudioStreamType.Media"/>
340 /// are not allowed to this device.
342 /// <exception cref="InvalidOperationException">This device is not valid or is disconnected.</exception>
343 /// <since_tizen> 5 </since_tizen>
344 public bool GetMediaStreamOnly()
346 Interop.AudioDevice.GetMediaStreamOnly(_id, out bool enabled).
347 ThrowIfError("Failed to get media-stream-only property of the device");
353 /// Returns a string that represents the current object.
355 /// <returns>A string that represents the current object.</returns>
356 /// <since_tizen> 4 </since_tizen>
357 public override string ToString() =>
358 $"Id={Id}, Name={Name}, Type={Type}, IoDirection={IoDirection}, IsRunning={IsRunning}";
361 /// Compares an object to an instance of <see cref="AudioDevice"/> for equality.
363 /// <param name="obj">A <see cref="Object"/> to compare.</param>
364 /// <returns>true if the two devices are equal; otherwise, false.</returns>
365 /// <since_tizen> 4 </since_tizen>
366 public override bool Equals(object obj)
368 var rhs = obj as AudioDevice;
378 /// Gets the hash code for this instance of <see cref="AudioDevice"/>.
380 /// <returns>The hash code for this instance of <see cref="AudioDevice"/>.</returns>
381 /// <since_tizen> 4 </since_tizen>
382 public override int GetHashCode()
384 return Id.GetHashCode();