IMMDeviceTest.cs 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // -----------------------------------------
  2. // SoundScribe (TM) and related software.
  3. //
  4. // Copyright (C) 2007-2011 Vannatech
  5. // http://www.vannatech.com
  6. // All rights reserved.
  7. //
  8. // This source code is subject to the MIT License.
  9. // http://www.opensource.org/licenses/mit-license.php
  10. //
  11. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  13. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  14. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  15. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  16. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  17. // THE SOFTWARE.
  18. // -----------------------------------------
  19. using System;
  20. using System.Runtime.InteropServices;
  21. using CoreAudioTests.Common;
  22. using Microsoft.VisualStudio.TestTools.UnitTesting;
  23. using Vannatech.CoreAudio.Constants;
  24. using Vannatech.CoreAudio.Enumerations;
  25. using Vannatech.CoreAudio.Externals;
  26. using Vannatech.CoreAudio.Interfaces;
  27. namespace CoreAudioTests.MMDeviceApi
  28. {
  29. /// <summary>
  30. /// Tests all methods of the IMMDevice interface.
  31. /// </summary>
  32. [TestClass]
  33. public class IMMDeviceTest
  34. {
  35. /// <summary>
  36. /// This test ensures that each device can use any valid COM interface returned from the Activate method.
  37. /// It checks to make sure each received interface is not null and an HRESULT of S_OK is returned.
  38. /// </summary>
  39. [TestMethod]
  40. public void IMMDevice_Activate()
  41. {
  42. var devices = TestUtilities.CreateIMMDeviceCollection(EDataFlow.eAll, DEVICE_STATE_XXX.DEVICE_STATE_ACTIVE);
  43. foreach (var d in devices)
  44. {
  45. var iid = Guid.Empty;
  46. var result = -1;
  47. object objInterface = null;
  48. // Check IAudioClient
  49. iid = new Guid(ComIIDs.IAudioClientIID);
  50. result = d.Activate(iid, (uint)CLSCTX.CLSCTX_INPROC_SERVER, IntPtr.Zero, out objInterface);
  51. AssertCoreAudio.IsHResultOk(result);
  52. Assert.IsNotNull(objInterface as IAudioClient);
  53. // Check IAudioEndpointVolume
  54. iid = new Guid(ComIIDs.IAudioEndpointVolumeIID);
  55. result = d.Activate(iid, (uint)CLSCTX.CLSCTX_INPROC_SERVER, IntPtr.Zero, out objInterface);
  56. AssertCoreAudio.IsHResultOk(result);
  57. Assert.IsNotNull(objInterface as IAudioEndpointVolume);
  58. // Check IAudioMeterInformation
  59. iid = new Guid(ComIIDs.IAudioMeterInformationIID);
  60. result = d.Activate(iid, (uint)CLSCTX.CLSCTX_INPROC_SERVER, IntPtr.Zero, out objInterface);
  61. AssertCoreAudio.IsHResultOk(result);
  62. Assert.IsNotNull(objInterface as IAudioMeterInformation);
  63. // Check IAudioSessionManager
  64. iid = new Guid(ComIIDs.IAudioSessionManagerIID);
  65. result = d.Activate(iid, (uint)CLSCTX.CLSCTX_INPROC_SERVER, IntPtr.Zero, out objInterface);
  66. AssertCoreAudio.IsHResultOk(result);
  67. Assert.IsNotNull(objInterface as IAudioSessionManager);
  68. // Check IAudioSessionManager2
  69. iid = new Guid(ComIIDs.IAudioSessionManager2IID);
  70. result = d.Activate(iid, (uint)CLSCTX.CLSCTX_INPROC_SERVER, IntPtr.Zero, out objInterface);
  71. AssertCoreAudio.IsHResultOk(result);
  72. Assert.IsNotNull(objInterface as IAudioSessionManager2);
  73. // Check IDeviceTopology
  74. iid = new Guid(ComIIDs.IDeviceTopologyIID);
  75. result = d.Activate(iid, (uint)CLSCTX.CLSCTX_INPROC_SERVER, IntPtr.Zero, out objInterface);
  76. AssertCoreAudio.IsHResultOk(result);
  77. Assert.IsNotNull(objInterface as IDeviceTopology);
  78. }
  79. }
  80. /// <summary>
  81. /// This test ensures that each device can get its ID. It also checks that the received ID is not null.
  82. /// </summary>
  83. [TestMethod]
  84. public void IMMDevice_GetId()
  85. {
  86. var devices = TestUtilities.CreateIMMDeviceCollection();
  87. foreach (var d in devices)
  88. {
  89. string strId;
  90. var result = d.GetId(out strId);
  91. AssertCoreAudio.IsHResultOk(result);
  92. Assert.IsNotNull(strId);
  93. }
  94. }
  95. /// <summary>
  96. /// This test ensures that each device can get its state. It also checks that the received state is a valid device state constant.
  97. /// </summary>
  98. [TestMethod]
  99. public void IMMDevice_GetState()
  100. {
  101. var devices = TestUtilities.CreateIMMDeviceCollection();
  102. foreach (var d in devices)
  103. {
  104. UInt32 deviceState;
  105. var result = d.GetState(out deviceState);
  106. AssertCoreAudio.IsHResultOk(result);
  107. AssertCoreAudio.IsDeviceStateValid(deviceState);
  108. }
  109. }
  110. /// <summary>
  111. /// This test ensures that each device can open a property store in READWRITE mode and that the received property store is non-null.
  112. /// It also checks that the property store object works correctly by making a call to get the property count.
  113. /// </summary>
  114. [TestMethod]
  115. public void IMMDevice_OpenPropertyStore()
  116. {
  117. var tested = false;
  118. var devices = TestUtilities.CreateIMMDeviceCollection();
  119. foreach (var d in devices)
  120. {
  121. // Open the property store
  122. IPropertyStore propertyStore;
  123. var result = d.OpenPropertyStore(STGM.STGM_READ, out propertyStore);
  124. AssertCoreAudio.IsHResultOk(result);
  125. // Verify the count can be received.
  126. var propertyCount = UInt32.MaxValue;
  127. result = propertyStore.GetCount(out propertyCount);
  128. AssertCoreAudio.IsHResultOk(result);
  129. Assert.AreNotEqual(UInt32.MaxValue, propertyCount, "The property count was not received.");
  130. // Get each property key, then get value.
  131. for (uint i = 0; i < propertyCount; i++)
  132. {
  133. PROPERTYKEY propertyKey;
  134. result = propertyStore.GetAt(i, out propertyKey);
  135. AssertCoreAudio.IsHResultOk(result);
  136. var value = GetPropertyValue(propertyStore, propertyKey);
  137. if (value != null)
  138. tested = true;
  139. }
  140. }
  141. if (!tested) Assert.Inconclusive("No property values returned valid, non-null values.");
  142. }
  143. private object GetPropertyValue(IPropertyStore propertyStore, PROPERTYKEY propertyKey)
  144. {
  145. object returnObj = null;
  146. PROPVARIANT propVariant;
  147. var result = propertyStore.GetValue(ref propertyKey, out propVariant);
  148. AssertCoreAudio.IsHResultOk(result);
  149. var vType = (VarEnum)propVariant.vt;
  150. if (vType == VarEnum.VT_EMPTY)
  151. return null;
  152. switch (vType)
  153. {
  154. case VarEnum.VT_BOOL:
  155. returnObj = propVariant.Data.AsBoolean;
  156. break;
  157. case VarEnum.VT_UI4:
  158. returnObj = propVariant.Data.AsUInt32;
  159. break;
  160. case VarEnum.VT_LPWSTR:
  161. case VarEnum.VT_CLSID:
  162. returnObj = Marshal.PtrToStringUni(propVariant.Data.AsStringPtr);
  163. break;
  164. case VarEnum.VT_BLOB:
  165. returnObj = propVariant.Data.AsFormatPtr;
  166. break;
  167. }
  168. if (propertyKey.fmtid == PropertyKeys.PKEY_AudioEngine_DeviceFormat ||
  169. propertyKey.fmtid == PropertyKeys.PKEY_AudioEngine_OEMFormat)
  170. {
  171. Assert.AreEqual(VarEnum.VT_BLOB, vType, "The device format property was not of varient type VT_BLOB.");
  172. var format = (WAVEFORMATEX)Marshal.PtrToStructure((IntPtr)returnObj, typeof(WAVEFORMATEX));
  173. if (format.nChannels != 0 && format.nSamplesPerSec != 0 && format.wBitsPerSample != 0)
  174. Assert.AreEqual(format.nChannels * format.nSamplesPerSec * format.wBitsPerSample, format.nAvgBytesPerSec * 8, "The wave format was not valid.");
  175. }
  176. return returnObj;
  177. }
  178. }
  179. }