Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Enumerating Sound Recording Devices (Using winmm.dll/C#)

4.22/5 (8 votes)
7 May 2007CPOL 3   2.1K  
This article describes a sample class that uses winmm.dll in C# through P/Invoke to enumerate sound recording devices.

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:

C#
using System.Runtime.InteropServices;//DLLimport
using System.Collections;//arrayList

The second step is declaring all the APIs we need:

C#
//return total Sound Recording Devices
[DllImport("winmm.dll")]
public static extern int waveInGetNumDevs();
//return spesific Sound Recording Devices spec
[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.

C#
[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:

C#
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();
    //using to store all sound recording devices strings 

    public int Count
    //to return total sound recording devices found
    { 
        get {return arrLst.Count;}
    }
    public string this[int indexer]
    //return spesipic sound recording device name
    {
        get{return (string)arrLst[indexer];}
    }
    public clsRecDevices() //fill sound recording devices array
    {
        int waveInDevicesCount = waveInGetNumDevs(); //get total
        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());
                           //clean garbage
            }
        }
    } 
}
}

This class can be used as follows:

C#
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)