Introduction
This article describes a sample class that uses winmm.dll in C# through P/Invoke to enumerate sound recording devices.
Using the code
Let's start by including all the namespaces we are going to use:
using System.Runtime.InteropServices;
using System.Collections;
The second step is declaring all the APIs we need:
[DllImport("winmm.dll")]
public static extern int waveInGetNumDevs();
[DllImport("winmm.dll", EntryPoint = "waveInGetDevCaps")]
public static extern int waveInGetDevCapsA(int uDeviceID, ref WaveInCaps lpCaps, int uSize);
The third step is to declare the "WaveInCaps
" struct returned by the waveInGetDevCaps
API. I found this one in "http://www.dotnetjunkies.com/WebLog/debasish/archive/2006/11/25/160495.aspx" - thanks to "debasish" for the hard work.
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct WaveInCaps
{
public short wMid;
public short wPid;
public int vDriverVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] szPname;
public uint dwFormats;
public short wChannels;
public short wReserved1;
}
From here, it's just straightforward C# coding...
I implemented this in a clsRecDevices
class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Collections;
namespace winApp
{
class clsRecDevices
{
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public struct WaveInCaps
{
public short wMid;
public short wPid;
public int vDriverVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] szPname;
public uint dwFormats;
public short wChannels;
public short wReserved1;
}
[DllImport("winmm.dll")]
public static extern int waveInGetNumDevs();
[DllImport("winmm.dll", EntryPoint = "waveInGetDevCaps")]
public static extern int waveInGetDevCapsA(int uDeviceID,
ref WaveInCaps lpCaps, int uSize);
ArrayList arrLst = new ArrayList();
public int Count
{
get {return arrLst.Count;}
}
public string this[int indexer]
{
get{return (string)arrLst[indexer];}
}
public clsRecDevices()
{
int waveInDevicesCount = waveInGetNumDevs();
if (waveInDevicesCount > 0)
{
for (int uDeviceID = 0; uDeviceID < waveInDevicesCount; uDeviceID++)
{
WaveInCaps waveInCaps = new WaveInCaps();
waveInGetDevCapsA(uDeviceID,ref waveInCaps,
Marshal.SizeOf(typeof(WaveInCaps)));
arrLst.Add(new string(waveInCaps.szPname).Remove(
new string(waveInCaps.szPname).IndexOf('\0')).Trim());
}
}
}
}
}
This class can be used as follows:
clsRecDevices recDev = new clsRecDevices();
for (int i = 0; i < recDev.Count; i++){
MessageBox.Show(recDev[i]);
}
History
You can also implement IEnumerator
and IEnumerable
to add some cool indexing features.