/* * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.InteropServices; using System.Collections.Generic; using System.Linq; namespace Tizen.Multimedia { /// /// Provides the ability to query the information of sound devices. /// /// 3 public class AudioDevice { private readonly int _id; private readonly AudioDeviceType _type; private readonly AudioDeviceIoDirection _ioDirection; private const string Tag = "Tizen.Multimedia.AudioDevice"; internal AudioDevice(IntPtr deviceHandle) { int ret = Interop.AudioDevice.GetDeviceId(deviceHandle, out _id); MultimediaDebug.AssertNoError(ret); ret = Interop.AudioDevice.GetDeviceName(deviceHandle, out var name); MultimediaDebug.AssertNoError(ret); Name = Marshal.PtrToStringAnsi(name); ret = Interop.AudioDevice.GetDeviceType(deviceHandle, out _type); MultimediaDebug.AssertNoError(ret); ret = Interop.AudioDevice.GetDeviceIoDirection(deviceHandle, out _ioDirection); MultimediaDebug.AssertNoError(ret); } /// /// Gets the ID of the device. /// /// The id of the device. /// 3 public int Id => _id; /// /// Gets the name of the device. /// /// The name of the device. /// 3 public string Name { get; } /// /// Gets the type of the device. /// /// The of the device. /// 3 public AudioDeviceType Type => _type; /// /// Gets the IO direction of the device. /// /// The IO direction of the device. /// 3 public AudioDeviceIoDirection IoDirection => _ioDirection; /// /// Gets the state of the device. /// /// The of the device. /// 3 [Obsolete("Deprecated since API level 5. Please use the IsRunning property instead.")] public AudioDeviceState State { get { Interop.AudioDevice.GetDeviceState(Id, out var state). ThrowIfError("Failed to get the state of the device"); return state; } } /// /// Gets the running state of the device. /// /// true if the audio stream of device is running actually; otherwise, false. /// 5 public bool IsRunning { get { Interop.AudioDevice.IsDeviceRunning(_id, out bool isRunning). ThrowIfError("Failed to get the running state of the device"); return isRunning; } } /// /// Gets the device's supported sample formats. /// /// An IEnumerable<AudioSampleFormat> that contains supported sample formats. /// /// This device should be type and direction. /// /// This device is not valid or is disconnected. /// 5 public IEnumerable GetSupportedSampleFormats() { Interop.AudioDevice.GetSupportedSampleFormats(_id, out IntPtr formats, out uint numberOfElements). ThrowIfError("Failed to get supported sample formats"); return RetrieveFormats(); IEnumerable RetrieveFormats() { int[] formatsResult = new int[numberOfElements]; Marshal.Copy(formats, formatsResult, 0, (int)numberOfElements); Interop.Libc.Free(formats); foreach (int f in formatsResult) { Log.Debug(Tag, $"supported sample format:{f}"); } return formatsResult.Cast(); } } /// /// Sets the device's sample format. /// /// The to set to the device. /// /// This device should be type and direction. /// /// This device is not valid or is disconnected. /// 5 public void SetSampleFormat(AudioSampleFormat format) { Interop.AudioDevice.SetSampleFormat(_id, format). ThrowIfError("Failed to set sample format of the device"); } /// /// Gets the device's sample format. /// /// The of the device. /// /// This device should be type and direction. /// /// This device is not valid or is disconnected. /// 5 public AudioSampleFormat GetSampleFormat() { Interop.AudioDevice.GetSampleFormat(_id, out AudioSampleFormat format). ThrowIfError("Failed to get sample format of the device"); return format; } private uint ConvertCoreRateValToUint(int value) { switch (value) { case 0: return 8000; case 1: return 16000; case 2: return 22050; case 3: return 44100; case 4: return 48000; case 5: return 88200; case 6: return 96000; case 7: return 192000; default: Log.Error(Tag, $"unknown value from core:{value}"); return 0; } } private uint ConvertRateToCoreValue(uint rate) { switch (rate) { case 8000: return 0; case 16000: return 1; case 22050: return 2; case 44100: return 3; case 48000: return 4; case 88200: return 5; case 96000: return 6; case 192000: return 7; default: Log.Error(Tag, $"not supported rate:{rate}"); return 0; } } /// /// Gets the device's supported sample rates. /// /// An IEnumerable<uint> that contains supported sample rates. /// /// This device should be type and direction. /// /// This device is not valid or is disconnected. /// 5 public IEnumerable GetSupportedSampleRates() { Interop.AudioDevice.GetSupportedSampleRates(_id, out IntPtr rates, out uint numberOfElements). ThrowIfError("Failed to get supported sample formats"); return RetrieveRates(); IEnumerable RetrieveRates() { int[] ratesResult = new int[numberOfElements]; uint[] convertedRates = new uint[numberOfElements]; Marshal.Copy(rates, ratesResult, 0, (int)numberOfElements); Interop.Libc.Free(rates); for (int i = 0; i < ratesResult.Length; i++) { convertedRates[i] = ConvertCoreRateValToUint(ratesResult[i]); Log.Debug(Tag, $"supported sample rate:{convertedRates[i]}"); } return convertedRates; } } /// /// Sets the device's sample rate. /// /// The sample rate to set to the device. /// /// This device should be type and direction. /// /// This device is not valid or is disconnected. /// 5 public void SetSampleRate(uint rate) { Interop.AudioDevice.SetSampleRate(_id, ConvertRateToCoreValue(rate)). ThrowIfError("Failed to set sample rate of the device"); } /// /// Gets the device's sample rate. /// /// The sample rate of the device. /// /// This device should be type and direction. /// /// This device is not valid or is disconnected. /// 5 public uint GetSampleRate() { Interop.AudioDevice.GetSampleRate(_id, out uint rate). ThrowIfError("Failed to get sample rate of the device"); return ConvertCoreRateValToUint((int)rate); } /// /// Sets the device's 'avoid resampling' property. /// /// The 'avoid resampling' value to set to the device. /// /// This device should be type and direction. /// This property is not enabled as default. With this enabled, this device will use the first stream's original sample format /// and rate without resampling if supported. /// /// This device is not valid or is disconnected. /// 5 public void SetAvoidResampling(bool enable) { Interop.AudioDevice.SetAvoidResampling(_id, enable). ThrowIfError("Failed to set avoid-resampling property of the device"); } /// /// Gets the device's 'avoid resampling' property. /// /// The 'avoid resampling' property of the device. /// /// This device should be type and direction. /// This property is not enabled as default. With this enabled, this device will use the first stream's original sample format /// and rate without resampling if supported. /// /// This device is not valid or is disconnected. /// 5 public bool GetAvoidResampling() { Interop.AudioDevice.GetAvoidResampling(_id, out bool enabled). ThrowIfError("Failed to get avoid-resampling property of the device"); return enabled; } /// /// Sets the restriction of stream type only for media. /// /// The 'media stream only' value to set to the device. /// /// This device should be type and direction. /// This property is not enabled as default. With this enabled, no other stream types except /// are not allowed to this device. /// /// This device is not valid or is disconnected. /// 5 public void SetMediaStreamOnly(bool enable) { Interop.AudioDevice.SetMediaStreamOnly(_id, enable). ThrowIfError("Failed to set media-stream-only property of the device"); } /// /// Gets the restriction of stream type only for media. /// /// The 'media stream only' property of the device. /// /// This device should be type and direction. /// This property is not enabled as default. With this enabled, no other stream types except /// are not allowed to this device. /// /// This device is not valid or is disconnected. /// 5 public bool GetMediaStreamOnly() { Interop.AudioDevice.GetMediaStreamOnly(_id, out bool enabled). ThrowIfError("Failed to get media-stream-only property of the device"); return enabled; } /// /// Returns a string that represents the current object. /// /// A string that represents the current object. /// 4 public override string ToString() => $"Id={Id}, Name={Name}, Type={Type}, IoDirection={IoDirection}, IsRunning={IsRunning}"; /// /// Compares an object to an instance of for equality. /// /// A to compare. /// true if the two devices are equal; otherwise, false. /// 4 public override bool Equals(object obj) { var rhs = obj as AudioDevice; if (rhs == null) { return false; } return Id == rhs.Id; } /// /// Gets the hash code for this instance of . /// /// The hash code for this instance of . /// 4 public override int GetHashCode() { return Id.GetHashCode(); } } }