Skip to content

Commit

Permalink
Merge branch 'pix64-devicetop'
Browse files Browse the repository at this point in the history
  • Loading branch information
markheath committed Aug 6, 2019
2 parents 4fec46f + 70f7f0a commit 128d565
Show file tree
Hide file tree
Showing 11 changed files with 346 additions and 1 deletion.
105 changes: 105 additions & 0 deletions NAudio/CoreAudioApi/Connector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using NAudio.CoreAudioApi.Interfaces;

namespace NAudio.CoreAudioApi
{
/// <summary>
/// Connector
/// </summary>
public class Connector
{
private readonly IConnector connectorInterface;

internal Connector(IConnector connector)
{
connectorInterface = connector;
}

/// <summary>
/// Connects this connector to a connector in another device-topology object
/// </summary>
public void ConnectTo(Connector other)
{
connectorInterface.ConnectTo(other.connectorInterface);
}

/// <summary>
/// Retreives the type of this connector
/// </summary>
public ConnectorType Type
{
get
{
connectorInterface.GetType(out var result);
return result;
}
}

/// <summary>
/// Retreives the data flow of this connector
/// </summary>
public DataFlow DataFlow
{
get
{
connectorInterface.GetDataFlow(out var result);
return result;
}
}

/// <summary>
/// Disconnects this connector from it's connected connector (if connected)
/// </summary>
public void Disconnect()
{
connectorInterface.Disconnect();
}

/// <summary>
/// Indicates whether this connector is connected to another connector
/// </summary>
public bool IsConnected
{
get
{
connectorInterface.IsConnected(out var result);
return result;
}
}

/// <summary>
/// Retreives the connector this connector is connected to (if connected)
/// </summary>
public Connector ConnectedTo
{
get
{
connectorInterface.GetConnectedTo(out var result);
return new Connector(result);
}
}

/// <summary>
/// Retreives the global ID of the connector this connector is connected to (if connected)
/// </summary>
public string ConnectedToConnectorId
{
get
{
connectorInterface.GetConnectorIdConnectedTo(out var result);
return result;
}
}

/// <summary>
/// Retreives the device ID of the audio device this connector is connected to (if connected)
/// </summary>
public string ConnectedToDeviceId
{
get
{
connectorInterface.GetDeviceIdConnectedTo(out var result);
return result;
}
}
}
}
33 changes: 33 additions & 0 deletions NAudio/CoreAudioApi/ConnectorType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
namespace NAudio.CoreAudioApi
{
/// <summary>
/// Connector Type
/// </summary>
public enum ConnectorType
{
/// <summary>
/// The connector is part of a connection of unknown type.
/// </summary>
UnknownConnector,
/// <summary>
/// The connector is part of a physical connection to an auxiliary device that is installed inside the system chassis
/// </summary>
PhysicalInternal,
/// <summary>
/// The connector is part of a physical connection to an external device.
/// </summary>
PhysicalExternal,
/// <summary>
/// The connector is part of a software-configured I/O connection (typically a DMA channel) between system memory and an audio hardware device on an audio adapter.
/// </summary>
SoftwareIo,
/// <summary>
/// The connector is part of a permanent connection that is fixed and cannot be configured under software control.
/// </summary>
SoftwareFixed,
/// <summary>
/// The connector is part of a connection to a network.
/// </summary>
Network,
}
}
54 changes: 54 additions & 0 deletions NAudio/CoreAudioApi/DeviceTopology.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using NAudio.CoreAudioApi.Interfaces;
using System;
using System.Collections.Generic;
using System.Text;

namespace NAudio.CoreAudioApi
{
/// <summary>
/// Windows CoreAudio DeviceTopology
/// </summary>
public class DeviceTopology
{
private readonly IDeviceTopology deviceTopologyInterface;

internal DeviceTopology(IDeviceTopology deviceTopology)
{
deviceTopologyInterface = deviceTopology;
}

/// <summary>
/// Retrieves the number of connections associated with this device-topology object
/// </summary>
public uint ConnectorCount
{
get
{
deviceTopologyInterface.GetConnectorCount(out var count);
return count;
}
}

/// <summary>
/// Retrieves the connector at the supplied index
/// </summary>
public Connector GetConnector(uint index)
{
deviceTopologyInterface.GetConnector(index, out var connectorInterface);
return new Connector(connectorInterface);
}

/// <summary>
/// Retrieves the device id of the device represented by this device-topology object
/// </summary>
public string DeviceId
{
get
{
deviceTopologyInterface.GetDeviceId(out var result);
return result;
}
}

}
}
26 changes: 26 additions & 0 deletions NAudio/CoreAudioApi/Interfaces/IConnector.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace NAudio.CoreAudioApi.Interfaces
{
/// <summary>
/// Windows CoreAudio IConnector interface
/// Defined in devicetopology.h
/// </summary>
[Guid("9C2C4058-23F5-41DE-877A-DF3AF236A09E"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComImport]
internal interface IConnector
{
int GetType(out ConnectorType type);
int GetDataFlow(out DataFlow flow);
int ConnectTo([In] IConnector connectTo);
int Disconnect();
int IsConnected(out bool connected);
int GetConnectedTo(out IConnector conTo);
int GetConnectorIdConnectedTo([MarshalAs(UnmanagedType.LPWStr)] out string id);
int GetDeviceIdConnectedTo([MarshalAs(UnmanagedType.LPWStr)] out string id);
}
}
25 changes: 25 additions & 0 deletions NAudio/CoreAudioApi/Interfaces/IDeviceTopology.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace NAudio.CoreAudioApi.Interfaces
{
/// <summary>
/// Windows CoreAudio IDeviceTopology interface
/// Defined in devicetopology.h
/// </summary>
[Guid("2A07407E-6497-4A18-9787-32F79BD0D98F"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComImport]
internal interface IDeviceTopology
{
int GetConnectorCount(out uint count);
int GetConnector(uint index, out IConnector connector);
int GetSubunitCount(out uint count);
int GetSubunit(uint index, out ISubunit subunit);
int GetPartById(uint id, out IPart part);
int GetDeviceId([MarshalAs(UnmanagedType.LPWStr)] out string id);
int GetSignalPath(IPart from, IPart to, bool rejectMixedPaths, out IPartsList parts);
}
}
19 changes: 19 additions & 0 deletions NAudio/CoreAudioApi/Interfaces/IPart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace NAudio.CoreAudioApi.Interfaces
{
/// <summary>
/// Windows CoreAudio IPart interface
/// Defined in devicetopology.h
/// </summary>
[Guid("AE2DE0E4-5BCA-4F2D-AA46-5D13F8FDB3A9"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComImport]
internal interface IPart
{
// Stub, Not implemented
}
}
20 changes: 20 additions & 0 deletions NAudio/CoreAudioApi/Interfaces/IPartsList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace NAudio.CoreAudioApi.Interfaces
{
/// <summary>
/// Windows CoreAudio IPartsList interface
/// Defined in devicetopology.h
/// </summary>
[Guid("6DAA848C-5EB0-45CC-AEA5-998A2CDA1FFB"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComImport]
internal interface IPartsList
{
int GetCount(out uint count);
int GetPart(uint index, out IPart part);
}
}
15 changes: 15 additions & 0 deletions NAudio/CoreAudioApi/Interfaces/ISubunit.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace NAudio.CoreAudioApi.Interfaces
{
[Guid("82149A85-DBA6-4487-86BB-EA8F7FEFCC71"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComImport]
internal interface ISubunit
{
// Stub, Not Implemented
}
}
44 changes: 44 additions & 0 deletions NAudio/CoreAudioApi/MMDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class MMDevice : IDisposable
private AudioMeterInformation audioMeterInformation;
private AudioEndpointVolume audioEndpointVolume;
private AudioSessionManager audioSessionManager;
private DeviceTopology deviceTopology;
#endregion

#region Guids
Expand All @@ -47,6 +48,7 @@ public class MMDevice : IDisposable
private static Guid IID_IAudioEndpointVolume = new Guid("5CDF2C82-841E-4546-9722-0CF74078229A");
private static Guid IID_IAudioClient = new Guid("1CB9AD4C-DBFA-4c32-B178-C2F568A703B2");
private static Guid IDD_IAudioSessionManager = new Guid("BFA971F1-4D5E-40BB-935E-967039BFBEE4");
private static Guid IDD_IDeviceTopology = new Guid("2A07407E-6497-4A18-9787-32F79BD0D98F");
// ReSharper restore InconsistentNaming
#endregion

Expand Down Expand Up @@ -85,6 +87,13 @@ private void GetAudioSessionManager()
Marshal.ThrowExceptionForHR(deviceInterface.Activate(ref IDD_IAudioSessionManager, ClsCtx.ALL, IntPtr.Zero, out var result));
audioSessionManager = new AudioSessionManager(result as IAudioSessionManager);
}

private void GetDeviceTopology()
{
Marshal.ThrowExceptionForHR(deviceInterface.Activate(ref IDD_IDeviceTopology, ClsCtx.ALL, IntPtr.Zero, out var result));
deviceTopology = new DeviceTopology(result as IDeviceTopology);
}

#endregion

#region Properties
Expand Down Expand Up @@ -139,6 +148,21 @@ public AudioSessionManager AudioSessionManager
}
}

/// <summary>
/// DeviceTopology instance
/// </summary>
public DeviceTopology DeviceTopology
{
get
{
if (deviceTopology == null)
{
GetDeviceTopology();
}
return deviceTopology;
}
}

/// <summary>
/// Properties
/// </summary>
Expand Down Expand Up @@ -214,6 +238,26 @@ public string IconPath
}
}

/// <summary>
/// Device Instance Id of Device
/// </summary>
public string InstanceId
{
get
{
if (propertyStore == null)
{
GetPropertyInformation();
}
if (propertyStore.Contains(PropertyKeys.PKEY_Device_InstanceId))
{
return (string)propertyStore[PropertyKeys.PKEY_Device_InstanceId].Value;
}

return "Unknown";
}
}

/// <summary>
/// Device ID
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions NAudio/CoreAudioApi/PropertyKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,9 @@ public static class PropertyKeys
/// Device interface key property.
/// </summary>
public static readonly PropertyKey PKEY_Device_InterfaceKey = new PropertyKey(new Guid(unchecked((int)0x233164c8), unchecked((short)0x1b2c), 0x4c7d, 0xbc, 0x68, 0xb6, 0x71, 0x68, 0x7a, 0x25, 0x67), 1);
/// <summary>
/// System-supplied device instance identification string, assigned by PnP manager, persistent across system restarts.
/// </summary>
public static readonly PropertyKey PKEY_Device_InstanceId = new PropertyKey(new Guid(0x78c34fc8, 0x104a, 0x4aca, 0x9e, 0xa4, 0x52, 0x4d, 0x52, 0x99, 0x6e, 0x57), 256);
}
}
Loading

0 comments on commit 128d565

Please sign in to comment.