Get list of audio devices and select one using c# - c#

Hi I am creating a desktop based application in windows using C#.
I have to show list of all available audio & video devices in 2 different combo boxes.
Selecting any device from combo box will set that particular device as the default one
I am using WMI.
Code to get list of available audio devices:
ManagementObjectSearcher mo =
new ManagementObjectSearcher("select * from Win32_SoundDevice");
foreach (ManagementObject soundDevice in mo.Get())
{
String deviceId = soundDevice.GetPropertyValue("DeviceId").ToString();
String name = soundDevice.GetPropertyValue("Name").ToString();
//saving the name and device id in array
}
if i try to set the device like this:
using (RegistryKey audioDeviceKey =
Registry.LocalMachine.OpenSubKey(audioDevicesReg
+ #"\" + audioDeviceList.SelectedText.ToString(), true)){}
i get exception :
System.Security.SecurityException occurred in mscorlib.dll
Now I have few questions:
1) How to set the selected device as the default audio device?
2) The array contains device name as : "High Definition audio device"
even when I have attached a headset.
3) I want the list as speaker,headset etc...How to get that?
can anybody point me in the right direction?

There is no documented mechanism for changing the default audio device.
That's because you're enumerating the physical audio devices, not the audio endpoints.
You want to use the IMMDeviceEnumerator API to enumerate the audio endpoints (speakers, etc).
Unfortunately there is no managed interop published by Microsoft for the IMMDeviceEnumerator API, you'll need to define your own (there are several definitions available on the internet).

I am answering too late to this question.. but it may be helpful for others.
Lync 2013 SDK provides DeviceManager class which list all the audio and video devices in collections
LyncClient.GetClient().DeviceManager.AudioDevices enumerates all the audio devices on the system
LyncClient.GetClient().DeviceManager.VideoDevices enumerates all the video devices on the system
So, one can set the device as:
LyncClient client = LyncClient.GetClient();
DeviceManager dm = client.DeviceManager;
dm.ActiveAudioDevice = (AudioDevice)dm.AudioDevices[0]; //or any other found after foreach
dm.ActiveVideoDevice = (VideoDevice)dm.VideoDevices[0]; //or any other found after foreach
HTH.

Related

using an Audio Endpoint other than 'DefaultAudioEndpoint' in C#

This program is an audio visualizer for an rgb keyboard that listens to windows' default audio device. My audio setup is a bit more involved, and I use way more than just the default audio device. For instance, when I play music from Winamp it goes through the device Auxillary 1 (Synchronous Audio Router) instead of Desktop Input (Synchronous Audio Router) which I have set as Default. I'd like to be able change the device that the program listens to for the visualization.
I found in the source where the audio device is declared; Lines 32-36 in CSCoreAudioInput.cs:
public void Initialize()
{
MMDevice captureDevice = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console);
WaveFormat deviceFormat = captureDevice.DeviceFormat;
_audioEndpointVolume = AudioEndpointVolume.FromDevice(captureDevice);
}
The way that I understand it from the documentation, the section MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console) is where Windows gives the application my default IMMEndpoint "Desktop Input."
How would I go about changing DefaultAudioEndpoint?
Further Reading shows a few ways to get an IMMDevice, with DefaultAudioEnpoint being one of them. It seems to me that I'd have to enumerate the devices, and then separate out Auxillary 1 (Synchronous Audio Router) using PKEY_Device_FriendlyName. That's a bit much for me, as I have little to no C# experience. Is there an easier way to go about choosing a different endpoint? Am I on the right track? or am I missing the mark completely?
Also, what is the difference between MMDevice and IMMDevice? The source only seems to use MMDevice while all the Microsoft documentation references IMMDevice.
Thanks.
I DID IT!
I've found why the program uses MMDevice rather than IMMDevice. The developer has chosen to use the CSCore Library rather than Windows' own Core Audio API.
From continued reading of the CSCore MMDeviceEnumerator Documentation, it looks like I'll have to make a separate program that outputs all endpoints and their respective Endpoint ID Strings. Then I can substitute the DefaultAudioEndpoint method with the GetDevice(String id) method, where String id is the ID of whichever Endpoint I chose from the separate program.
To find the the Endpoint I wanted, I wrote this short program to find all the info I wanted:
static void Main(string[] args)
{
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
Console.WriteLine($"\nNumber of active Devices: {collection.GetCount()}");
int i = 0;
foreach (MMDevice device in collection){
Console.WriteLine($"\n{i} Friendly name: {device.FriendlyName}");
Console.WriteLine($"Endpoint ID: {device.DeviceID}");
i++;
}
Console.ReadKey();
}
This showed me that the Endpoint I wanted was item number 3 (2 in an array) on my list, and instead of using GetDevice(String id) I used ItemAt(int deviceIndex).
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
MMDevice captureDevice = collection.ItemAt(2);
However in this case, the program was not using captureDevice to bring in the audio data. These were the magic lines:
_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
_capture.Initialize();
I found that WasapiLoopbackCapture uses Windows' default device unless changed, and the code was using DefaultAudioEndpoint to get the properties of the default device. So I added
_capture.Device = captureDevice;
//before
_capture.Initialize();
And now the program properly pulls the audio data off of my non-default audio endpoint.
I had been asked to solve a similar type of problem this week. Although there are a few librarys to do this I was specifically asked to do this for "non ish" programmers so I developed this in PowerShell.
Powershell default audio device changer - Github
Maybe you can alter it to your needs.

SMBIOS - Get SPD (Serial Presence Detect) Modules Information C#

I searched a lot but did not find any working codes getting SPD tables information via C#. Out there there are lots of softwares which get this info but HOW?
as shown in the image, for RAM devices, you can see Manufacture's name which can not be retrieve at all by WMI etc
If there is a DLL for using in C# will be perfect also
After some Research found this:
https://github.com/sapozhnikovay/SMBIOS
but it can not read table 17 to get memory device information.
Once I was researching about this, you need to get this information through SMBUS (not SMBIOS). But you need to create a driver (WDM in C/C++) to access this information.
Make sure you have added System.Management as a reference.
Here is a string that will return almost any information you want from the component :
private string getComponent(string hwClass, string syntax)
{
ManagementObjectSearcher mos = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM " + hwClass);
foreach (ManagementObject mj in mos.Get())
{
return Convert.ToString(mj[syntax]);
}
return null;
}
Using the string would look like this, say on a button click :
label1.Text = getComponent("Win32_PhysicalMemory", "SerialNumber");
I tested it and it returned a serial number, you can also look at the list of things you can put in like manufacturer, name, capacity etc.
I got all of this information from this YouTube video.
You can find all of the devices and their properties here (CPU, GPU, etc.)

Where do I find the name displayed in "Devices and Printers"

I have a serial device connected via Bluetooth. It shows up nicely on COM4. I can communicate with it without a problem.
I want to make it simpler for the user to locate (ideally, I'll auto-detect it), so I want to find it by name. In the "Devices and Printers" list, I get a valid name, which is perfect. However, I can't seem to find that value programatically. I've tried a ton of stuff using the "ManagementObjectSearcher" class, including listing out all the Properties and SystemProperties, but no values match the name displayed in "Devices and Printers".
If I look in the "Device Manager" list, it just shows "Standard Serial over Bluetooth link (COM4)", which is not useful for identifying it, obviously.
So how the heck to I get the displayed name in the "Devices and Printers" list?
is this what you're looking for?
http://msdn.microsoft.com/en-us/library/system.drawing.printing.printersettings.installedprinters(v=vs.110).aspx
So, I found a solution. I grabbed the library from these guys:
http://32feet.codeplex.com/
Using that library, added these 2 lines:
BluetoothClient client = new BluetoothClient();
BluetoothDeviceInfo[] devices = client.DiscoverDevices();
That gave me the device "DeviceName" (the name I was after) and "DeviceAddress" (a chunk of the device id, basically).
I then queried the system using the "ManagementObjectSearcher", which gave me a list of COM ports and device IDs (System.Management namespace).
ConnectionOptions options = ProcessConnection.ProcessConnectionOptions();
ManagementScope connectionScope = ProcessConnection.ConnectionScope(Environment.MachineName, options, #"\root\CIMV2");
ObjectQuery objectQuery = new ObjectQuery("SELECT * FROM Win32_PnPEntity");
ManagementObjectSearcher comPortSearcher = new ManagementObjectSearcher(connectionScope, objectQuery);
...etc as I looped over the results, pulled out the COM ports, and so on
I mapped the device IDs from the "ManagementObject" values back to the "devices" list, merged the results, and ended up with something that had the name, device id, a flag indicating if it was a bluetooth device, and the "human readable" name from the bluetooth device, if it existed.
Painful, but it works fairly well. It's slow (client.DiscoverDevices() takes awhile), but that's survivable in my case.

List all USB audio headsets connected to a Windows PC

I want to use C# to retrieve the USB headset devices connected to PC. I tried the below solutions but didn't work:
Solution 1:
How to enumerate audio out devices in c#
I tried this but the device name appears as "(Generic USB Audio)" and not the actual name.
Solution 2:
How to get the default audio device?
Solution 3:
Detecting Audio Input & output devices connected to system
Solution 2 and Solution 3 gave me the below result:
The device name is truncated to 31 characters.
Eg: "Microphone (Sennheiser VOICE 689"
****Question: Is there any way I can get the complete name of the device?****
If you know it's an USB audio device, and assuming the driver is correctly written for the device, you could do:
foreach (ManagementObject drive in
new ManagementObjectSearcher(
"select Name from Win32_USBDevice where Service='usbaudio'").Get())
{
{
string s = drive["Name"].ToString();
// Continue
}
}
Addition
You're only getting 31 characters (technically 32) because the PInvoke to the native .DLLs use a char[32], so it can't return more than that; you won't get what you need from solution 1 & 2.
Also, I don't know why you can't use Win32_USBDevice, as I'm also using Win7 x64 and I'm having no problems. This link might help you.
Possible Alternate
You might be able to use the Win32_PnPEntity class:
foreach (ManagementObject drive in
new ManagementObjectSearcher(
"select Name from Win32_PnPEntity where Service='usbaudio'").Get())
{
{
string s = drive["Name"].ToString();
// Continue. Can look at Description, Caption, etc. too
}
}

How to get list of windows (DirectSound? ASIO?) audio devices?

1. I need list of all device names and types (playback or recording). How can I get them?
2. I also need to determine if device is Playback or Recording device.
By device names I mean names visible here under Playback and Recording tab (screenshot below). Im not familiar with audio under windows, i don't know if these devices are ASIO, DirectSound or something else.
My application should be comaptybile with Windows Vista/7/8, so I decided to use .NET 3.5, but I can use any .NET version supported by Windows Vista/7/8.
Edit: I tried to get these from WMI "SELECT * FROM Win32_SoundDevice", but this is not what I mean. It returns hardware devices, not devices visible in windows sound configuration.
Use How to enumerate audio out devices in c#:
ManagementObjectSearcher objSearcher = new ManagementObjectSearcher(
"SELECT * FROM Win32_SoundDevice");
ManagementObjectCollection objCollection = objSearcher.Get();
foreach (ManagementObject obj in objCollection)
{
foreach (PropertyData property in obj.Properties)
{
Console.Out.WriteLine(String.Format("{0}:{1}", property.Name, property.Value));
}
}

Categories

Resources