Created
November 28, 2024 13:11
-
-
Save DaTweaks/b6a01279338c5820ac15ab68cca32f70 to your computer and use it in GitHub Desktop.
Getting sounddevices from comport
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // 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