Menu

Home

Nhat Phan

Introduction

This article will instruct how to display audio device name and device ID in GUI.

I often uses "Sox" application to play or record audio from multiple sound cards. When record/play audio file, "sox" require the audio device ID to select which device to play/record. E.g. "sox -r 8000 -c 1 -t waveaudio 1 abc.wav" -->Record audio via device ID=1. This ID cannot be identify via application in control panel. Thus, I write this application to support for this purpose.

This article bases on the source code in article "Enumerating Sound Recording Devices (Using winmm.dll/C#)"

 

How to use the app

Step 1: Run the excecution file or ruin from visual studio 2010

Step 2: Click Refresh button to update the laetst status of audio device

Column "Type":  Identify type of device Microphone (MIC) or Speaker (SPK)

Column "Device Name":  Name of hardware

Column "DeviceID":  Identify device ID of Mic or Speaker

Using the code

  1.  Implementing 2 major class to get date of recording and playback devices

There are 2 classes to retrieve recording and playback devices:

clsRecDevices
clsPlaybackDevices

Detail info relate to these classes can be found in the link below

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

An array is created to store HW type, Device Name, Device ID

        public string[,] ListViewArray;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Collections;

namespace SoundCard
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new GUI());
        }
    }
    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);
        //using to store all sound recording devices strings 
        public string[,] ListViewArray;

        public clsRecDevices() //fill sound recording devices array
        {

            int waveInDevicesCount = waveInGetNumDevs(); //get total
            if (waveInDevicesCount > 0)
            {
                ListViewArray = new string[waveInDevicesCount, 4];
                for (int uDeviceID = 0; uDeviceID < waveInDevicesCount; uDeviceID++)
                {
                    WaveInCaps waveInCaps = new WaveInCaps();
                    waveInGetDevCapsA(uDeviceID, ref waveInCaps,
                                      Marshal.SizeOf(typeof(WaveInCaps)));
                    //ListViewArray[uDeviceID, 0] = "False";
                    ListViewArray[uDeviceID, 1] = "MIC";
                    ListViewArray[uDeviceID, 2] = new string(waveInCaps.szPname).Remove(
                               new string(waveInCaps.szPname).IndexOf('\0')).Trim();
                    ListViewArray[uDeviceID, 3] = uDeviceID.ToString();
                }
            }
        }
    }
    class clsPlaybackDevices
    {
        [StructLayout(LayoutKind.Sequential, Pack = 4)]
        public struct WaveOutCaps
        {
            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 waveOutGetNumDevs();
        [DllImport("winmm.dll", EntryPoint = "waveOutGetDevCaps")]
        public static extern int waveOutGetDevCapsA(int uDeviceID,
                             ref WaveOutCaps lpCaps, int uSize);
        //using to store all sound playback devices strings 
        public string[,] ListViewArray;

        public clsPlaybackDevices() //fill sound recording devices array
        {

            int waveInDevicesCount = waveOutGetNumDevs(); //get total
            if (waveInDevicesCount > 0)
            {
                ListViewArray = new string[waveInDevicesCount, 4];
                for (int uDeviceID = 0; uDeviceID < waveInDevicesCount; uDeviceID++)
                {
                    WaveOutCaps waveOutCaps = new WaveOutCaps();
                    waveOutGetDevCapsA(uDeviceID, ref waveOutCaps,
                                      Marshal.SizeOf(typeof(WaveOutCaps)));
                    //ListViewArray[uDeviceID, 0] = "False";
                    ListViewArray[uDeviceID, 1] = "SPK";
                    ListViewArray[uDeviceID, 2] = new string(waveOutCaps.szPname).Remove(
                               new string(waveOutCaps.szPname).IndexOf('\0')).Trim();
                    ListViewArray[uDeviceID, 3] = uDeviceID.ToString();
                }
            }
        }
    }
}

 

  1.  Create method to update listview from an array:
        private void printOutNewSubItem(string[,] Array)
        {
            if (Array != null)
            {
                int row = 0;
                row = Array.GetLength(0);
                for (int k = 0; k < row; k++)
                {
                    ListViewItem item = new ListViewItem(Array[k, 1]);
                    if (Array[k, 0] == "True")
                    {
                        item.Checked = true;
                    }
                    else
                    {
                        item.Checked = false;
                    }
                    for (int i = 2; i < Array.GetLength(1); i++)
                    {
                        item.SubItems.Add(Array[k, i]);
                    }
                    listView1.Items.Add(item);
                }
            }
        }
  1. Using these classes in Click button event:
        private void Refresh_Click(object sender, EventArgs e)
        {
            clsRecDevices recDev = new clsRecDevices();
            clsPlaybackDevices playDev = new clsPlaybackDevices();
            //Clear listView
            listView1.Items.Clear();
            //Update list view for record devices
            printOutNewSubItem(recDev.ListViewArray);
            //Update list view for playback devices
            printOutNewSubItem(playDev.ListViewArray);
        }

Points of Interest

  • Saving time when identifying device id of audio devices

 

History

 

20-Mar-2015: First version