Skip to content

Instantly share code, notes, and snippets.

@DaTweaks
Created November 28, 2024 13:11
Show Gist options
  • Select an option

  • Save DaTweaks/b6a01279338c5820ac15ab68cca32f70 to your computer and use it in GitHub Desktop.

Select an option

Save DaTweaks/b6a01279338c5820ac15ab68cca32f70 to your computer and use it in GitHub Desktop.
Getting sounddevices from comport
// Copyright (c) 2024 David Hornemark
//
// This software is provided 'as-is', without any express or implied warranty. In
// no event will the authors be held liable for any damages arising from the use
// of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not claim
// that you wrote the original software. If you use this software in a product,
// an acknowledgment in the product documentation would be appreciated but is not
// required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
//
// =============================================================================
// This takes a comport, and returns a deviceNumber for the microphone and speaker GUID.
#region COMPORT HANDLING
public (Guid SpeakerGuid, int microphoneIndex) GetAudioDevicesForComPort(string comPort) // main method to get the ids needed.
{
Guid speakerGuid = Guid.Empty;
int microphoneIndex = 0;
// Get PNPDeviceID for the given COM port
(string VIP, string PID) = GetComPortPnpId(comPort);
if (string.IsNullOrEmpty(VIP) || string.IsNullOrEmpty(PID))
{
Console.WriteLine($"Comport not found.");
return (speakerGuid, microphoneIndex);
}
// Get sound devices linked to this COM port
var SpeakerName = GetLinkedSoundDevices(VIP, PID, DataFlow.Render).Trim();
var microphoneName = GetLinkedSoundDevices(VIP, PID, DataFlow.Capture).Trim();
// Microphone
for(int i = 0; i < WaveIn.DeviceCount; i++)
{
if (microphoneName == WaveIn.GetCapabilities(i).ProductName)
{
microphoneIndex = i;
break;
}
}
// Speaker
foreach (var device in DirectSoundOut.Devices)
{
if (SpeakerName == device.Description)
{
speakerGuid = device.Guid;
break;
}
}
Console.WriteLine("Speakers: "+ speakerGuid);
Console.WriteLine("Microphone: "+ microphoneIndex);
return (speakerGuid, microphoneIndex);
}
(string VIP, string PID) GetComPortPnpId(string comPort) // This works.
{
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_SerialPort"))
{
foreach (ManagementObject obj in searcher.Get())
{
string deviceId = obj["DeviceID"]?.ToString();
if (!string.IsNullOrEmpty(deviceId) && deviceId.Equals(comPort, StringComparison.OrdinalIgnoreCase))
{
return ExtractVendorAndProductId(obj["PNPDeviceID"].ToString());
}
}
}
return ("", "");
}
string GetLinkedSoundDevices(string VID, string PID, DataFlow dataflowType) // Getting the description or "name", they are the same anyways.
{
var enumerator = new MMDeviceEnumerator();
var devices = enumerator.EnumerateAudioEndPoints(dataflowType, DeviceState.Active);
foreach (var device in devices)
{
var properties = device.Properties;
(string VendorId, string ProductId) = ExtractVendorAndProductId(properties[4].Value.ToString());
var guid = properties[12].Value.ToString();
if (!string.IsNullOrEmpty(VendorId) && !string.IsNullOrEmpty(ProductId) && VendorId == VID && ProductId == PID && !string.IsNullOrEmpty(guid))
{
return device.FriendlyName;
}
}
return "";
}
(string VendorId, string ProductId) ExtractVendorAndProductId(string pnpDeviceId) // just getting the id from the pnpDeviceID from the object searcher.
{
string vendorId = null;
string productId = null;
try
{
// Look for VID and PID patterns in the PNPDeviceID
var vidIndex = pnpDeviceId.IndexOf("VID_", StringComparison.OrdinalIgnoreCase);
var pidIndex = pnpDeviceId.IndexOf("PID_", StringComparison.OrdinalIgnoreCase);
if (vidIndex >= 0)
{
vendorId = pnpDeviceId.Substring(vidIndex + 4, 4); // Extract 4 characters after "VID_"
}
if (pidIndex >= 0)
{
productId = pnpDeviceId.Substring(pidIndex + 4, 4); // Extract 4 characters after "PID_"
}
}
catch (Exception ex)
{
Console.WriteLine($"Error extracting Vendor ID and Product ID: {ex.Message}");
}
return (vendorId, productId);
}
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment