亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#通過(guò)實(shí)現(xiàn)winmm枚舉音頻設(shè)備

 更新時(shí)間:2023年10月09日 08:30:25   作者:CodeOfCC  
使用C#做音頻錄制時(shí)需要獲取音頻設(shè)備信息,其中比較簡(jiǎn)單的就是使用winmm,所以本文就為大家介紹一下C#如何通過(guò)實(shí)現(xiàn)winmm枚舉音頻設(shè)備,需要的可以參考下

前言

使用C#做音頻錄制時(shí)需要獲取音頻設(shè)備信息,比如使用ffmpeg進(jìn)行錄制需要先獲取音頻設(shè)備名稱,再Windows上獲取音頻設(shè)備的方法有不少,其中比較簡(jiǎn)單的就是使用winmm,這是一套比較舊的api但是使用方法簡(jiǎn)單,當(dāng)然有個(gè)缺陷就是音頻名稱不能超過(guò)32個(gè)字符,超過(guò)會(huì)被截?cái)啵?dāng)然如果作為winmm的采集或播放配套使用則不會(huì)有問(wèn)題。

一、如何實(shí)現(xiàn)

需要先導(dǎo)入winmm的api,以及定義存放音頻設(shè)備信息的實(shí)體,最后通過(guò)調(diào)用api實(shí)現(xiàn)枚舉設(shè)備功能。

1、添加依賴

由于編寫dllimport比較麻煩,而且nuget已經(jīng)有封裝好的庫(kù),所以沒(méi)必要重復(fù)造輪子,直接nuget安裝然后補(bǔ)充一些必要的接口即可。

(1)nuget安裝winmm的封裝庫(kù)

(2)補(bǔ)充接口

由于Vanara.PInvoke.Multimedia對(duì)waveInGetDevCaps和waveOutGetDevCaps導(dǎo)入的有點(diǎn)問(wèn)題,所以需要自己dllimport。還需要添加一些相關(guān)的枚舉用于獲取聲音格式。

[DllImport("winmm.dll")]
public static extern MMRESULT waveInGetDevCapsW(uint uDeviceID, out WAVEINCAPS pwic, uint cbwic);
[DllImport("winmm.dll")]
public static extern MMRESULT waveOutGetDevCapsW(uint uDeviceID, out WAVEOUTCAPS pwoc, uint cbwoc);
public enum DWFormats
{
    WAVE_INVALIDFORMAT = 0x00000000,     /* invalid format */
    WAVE_FORMAT_1M08 = 0x00000001,    /* 11.025 kHz, Mono,   8-bit  */
    WAVE_FORMAT_1S08 = 0x00000002,    /* 11.025 kHz, Stereo, 8-bit  */
    WAVE_FORMAT_1M16 = 0x00000004,    /* 11.025 kHz, Mono,   16-bit */
    WAVE_FORMAT_1S16 = 0x00000008,    /* 11.025 kHz, Stereo, 16-bit */
    WAVE_FORMAT_2M08 = 0x00000010,    /* 22.05  kHz, Mono,   8-bit  */
    WAVE_FORMAT_2S08 = 0x00000020,    /* 22.05  kHz, Stereo, 8-bit  */
    WAVE_FORMAT_2M16 = 0x00000040,    /* 22.05  kHz, Mono,   16-bit */
    WAVE_FORMAT_2S16 = 0x00000080,    /* 22.05  kHz, Stereo, 16-bit */
    WAVE_FORMAT_4M08 = 0x00000100,    /* 44.1   kHz, Mono,   8-bit  */
    WAVE_FORMAT_4S08 = 0x00000200,    /* 44.1   kHz, Stereo, 8-bit  */
    WAVE_FORMAT_4M16 = 0x00000400,    /* 44.1   kHz, Mono,   16-bit */
    WAVE_FORMAT_4S16 = 0x00000800,    /* 44.1   kHz, Stereo, 16-bit */
    WAVE_FORMAT_44M08 = 0x00000100,     /* 44.1   kHz, Mono,   8-bit  */
    WAVE_FORMAT_44S08 = 0x00000200,     /* 44.1   kHz, Stereo, 8-bit  */
    WAVE_FORMAT_44M16 = 0x00000400,     /* 44.1   kHz, Mono,   16-bit */
    WAVE_FORMAT_44S16 = 0x00000800,     /* 44.1   kHz, Stereo, 16-bit */
    WAVE_FORMAT_48M08 = 0x00001000,     /* 48     kHz, Mono,   8-bit  */
    WAVE_FORMAT_48S08 = 0x00002000,     /* 48     kHz, Stereo, 8-bit  */
    WAVE_FORMAT_48M16 = 0x00004000,     /* 48     kHz, Mono,   16-bit */
    WAVE_FORMAT_48S16 = 0x00008000,     /* 48     kHz, Stereo, 16-bit */
    WAVE_FORMAT_96M08 = 0x00010000,     /* 96     kHz, Mono,   8-bit  */
    WAVE_FORMAT_96S08 = 0x00020000,     /* 96     kHz, Stereo, 8-bit  */
    WAVE_FORMAT_96M16 = 0x00040000,     /* 96     kHz, Mono,   16-bit */
    WAVE_FORMAT_96S16 = 0x00080000,     /* 96     kHz, Stereo, 16-bit */
}

2、定義實(shí)體

需要定義聲音格式

class SampleFormat
{
    /// <summary>
    /// 聲道數(shù)
    /// </summary>
    public ushort Channels { set; get; }
    /// <summary>
    /// 采樣率
    /// </summary>
    public uint SampleRate { set; get; }
    /// <summary>
    /// 位深
    /// </summary>
    public ushort BitsPerSample { set; get; }
};

以及聲音設(shè)備實(shí)體

class AudioDevice
{
    /// <summary>
    /// 設(shè)備Id
    /// </summary>
    public uint Id { set; get; }
    /// <summary>
    /// 設(shè)備名稱
    /// </summary>
    public string Name { set; get; } = "";
    /// <summary>
    /// 聲道數(shù)
    /// </summary>
    public int Channels { set; get; }
    /// <summary>
    /// 支持的格式
    /// </summary>
    public IEnumerable<SampleFormat>? SupportedFormats { set; get; }
};

3、實(shí)現(xiàn)枚舉

音頻采集設(shè)備

/// <summary>
/// 枚舉聲音采集設(shè)備
/// </summary>
public static IEnumerable<AudioDevice> WaveInDevices
{
    get
    {
        var deviceCount = waveInGetNumDevs();
        for (uint i = 0; i < deviceCount; i++)
        {
            var sd = GetWaveInDeviceById(i);
            if (sd != null) yield return sd;
        }
    }
}
/// <summary>
/// 通過(guò)id獲取聲音采集設(shè)備信息
/// </summary>
/// <param name="id">設(shè)備id</param>
/// <returns>設(shè)備對(duì)象</returns>
public static AudioDevice? GetWaveInDeviceById(uint id)
{
    WAVEINCAPS pwic;//聲音設(shè)備功能信息
    var result = waveInGetDevCapsW(id, out pwic, (uint)Marshal.SizeOf<WAVEINCAPS>());
    if (result != MMRESULT.MMSYSERR_NOERROR) return null;
    AudioDevice sd = new AudioDevice();
    sd.Id = id;
    sd.Channels = pwic.wChannels;
    sd.Name = pwic.szPname;
    sd.SupportedFormats = _GetSurportFormats(pwic.dwFormats);
    return sd;
}

音頻播放設(shè)備

 /// <summary>
 /// 枚舉聲音播放設(shè)備
 /// </summary>
 public static IEnumerable<AudioDevice> WaveOutDevices
 {
     get
     {
         var deviceCount = waveOutGetNumDevs();
         for (uint i = 0; i < deviceCount; i++)
         {
             var sd = GetWaveOutDeviceById(i);
             if (sd != null) yield return sd;
         }
     }
 }
/// <summary>
/// 通過(guò)id獲取聲音播放設(shè)備信息
/// </summary>
/// <param name="id">設(shè)備id</param>
/// <returns>設(shè)備對(duì)象</returns>
public static AudioDevice? GetWaveOutDeviceById(uint id)
{
    WAVEOUTCAPS pwic;//聲音設(shè)備功能信息
    var result = waveOutGetDevCapsW(id, out pwic, (uint)Marshal.SizeOf<WAVEOUTCAPS>());
    if (result != MMRESULT.MMSYSERR_NOERROR) return null;
    AudioDevice sd = new AudioDevice();
    sd.Id = id;
    sd.Channels = pwic.wChannels;
    sd.Name = pwic.szPname;
    sd.SupportedFormats = _GetSurportFormats(pwic.dwFormats);
    return sd;
}

二、完整代碼

using System.Runtime.InteropServices;
using static Vanara.PInvoke.WinMm;
/************************************************************************
* @Project:  	AC::Winmm
* @Decription:  音頻設(shè)備枚舉
* @Verision:  	v1.0.0.0
* @Author:  	Xin Nie
* @Create:  	2023/10/8 09:27:00
* @LastUpdate:  2023/10/8 15:04:00
************************************************************************
* Copyright @ 2025. All rights reserved.
************************************************************************/
namespace AC
{
    class Winmm
    {
        /// <summary>
        /// 枚舉聲音采集設(shè)備
        /// </summary>
        public static IEnumerable<AudioDevice> WaveInDevices
        {
            get
            {
                var deviceCount = waveInGetNumDevs();
                for (uint i = 0; i < deviceCount; i++)
                {
                    var sd = GetWaveInDeviceById(i);
                    if (sd != null) yield return sd;
                }
            }
        }
        /// <summary>
        /// 枚舉聲音播放設(shè)備
        /// </summary>
        public static IEnumerable<AudioDevice> WaveOutDevices
        {
            get
            {
                var deviceCount = waveOutGetNumDevs();
                for (uint i = 0; i < deviceCount; i++)
                {
                    var sd = GetWaveOutDeviceById(i);
                    if (sd != null) yield return sd;
                }
            }
        }
        /// <summary>
        /// 通過(guò)id獲取聲音采集設(shè)備信息
        /// </summary>
        /// <param name="id">設(shè)備id</param>
        /// <returns>設(shè)備對(duì)象</returns>
        public static AudioDevice? GetWaveInDeviceById(uint id)
        {
            WAVEINCAPS pwic;//聲音設(shè)備功能信息
            var result = waveInGetDevCapsW(id, out pwic, (uint)Marshal.SizeOf<WAVEINCAPS>());
            if (result != MMRESULT.MMSYSERR_NOERROR) return null;
            AudioDevice sd = new AudioDevice();
            sd.Id = id;
            sd.Channels = pwic.wChannels;
            sd.Name = pwic.szPname;
            sd.SupportedFormats = _GetSurportFormats(pwic.dwFormats);
            return sd;
        }
        /// <summary>
        /// 通過(guò)id獲取聲音播放設(shè)備信息
        /// </summary>
        /// <param name="id">設(shè)備id</param>
        /// <returns>設(shè)備對(duì)象</returns>
        public static AudioDevice? GetWaveOutDeviceById(uint id)
        {
            WAVEOUTCAPS pwic;//聲音設(shè)備功能信息
            var result = waveOutGetDevCapsW(id, out pwic, (uint)Marshal.SizeOf<WAVEOUTCAPS>());
            if (result != MMRESULT.MMSYSERR_NOERROR) return null;
            AudioDevice sd = new AudioDevice();
            sd.Id = id;
            sd.Channels = pwic.wChannels;
            sd.Name = pwic.szPname;
            sd.SupportedFormats = _GetSurportFormats(pwic.dwFormats);
            return sd;
        }
        static List<SampleFormat> _GetSurportFormats(uint foramts)
        {
            var sfs = new List<SampleFormat>();
            foreach (var j in Enum.GetValues<DWFormats>())
            {
                if ((foramts & (uint)j) != 0)
                {
                    var name = Enum.GetName(j)!.Split("_").Last();
                    var sp = name.Substring(0, name.Length - 3);
                    var ch = name.Substring(name.Length - 3, 1);
                    var bp = name.Substring(name.Length - 2, 2);
                    uint isp = 0;
                    switch (sp)
                    {
                        case "1": isp = 11025; break;
                        case "2": isp = 22050; break;
                        case "4": isp = 44100; break;
                        case "44": isp = 44100; break;
                        case "48": isp = 48000; break;
                        case "96": isp = 96000; break;
                    }
                    sfs.Add(new SampleFormat() { Channels = (ushort)(ch == "S" ? 1 : 2), SampleRate = isp, BitsPerSample = ushort.Parse(bp) });
                }
            }
            return sfs;
        }
        public enum DWFormats
        {
            WAVE_INVALIDFORMAT = 0x00000000,     /* invalid format */
            WAVE_FORMAT_1M08 = 0x00000001,    /* 11.025 kHz, Mono,   8-bit  */
            WAVE_FORMAT_1S08 = 0x00000002,    /* 11.025 kHz, Stereo, 8-bit  */
            WAVE_FORMAT_1M16 = 0x00000004,    /* 11.025 kHz, Mono,   16-bit */
            WAVE_FORMAT_1S16 = 0x00000008,    /* 11.025 kHz, Stereo, 16-bit */
            WAVE_FORMAT_2M08 = 0x00000010,    /* 22.05  kHz, Mono,   8-bit  */
            WAVE_FORMAT_2S08 = 0x00000020,    /* 22.05  kHz, Stereo, 8-bit  */
            WAVE_FORMAT_2M16 = 0x00000040,    /* 22.05  kHz, Mono,   16-bit */
            WAVE_FORMAT_2S16 = 0x00000080,    /* 22.05  kHz, Stereo, 16-bit */
            WAVE_FORMAT_4M08 = 0x00000100,    /* 44.1   kHz, Mono,   8-bit  */
            WAVE_FORMAT_4S08 = 0x00000200,    /* 44.1   kHz, Stereo, 8-bit  */
            WAVE_FORMAT_4M16 = 0x00000400,    /* 44.1   kHz, Mono,   16-bit */
            WAVE_FORMAT_4S16 = 0x00000800,    /* 44.1   kHz, Stereo, 16-bit */
            WAVE_FORMAT_44M08 = 0x00000100,     /* 44.1   kHz, Mono,   8-bit  */
            WAVE_FORMAT_44S08 = 0x00000200,     /* 44.1   kHz, Stereo, 8-bit  */
            WAVE_FORMAT_44M16 = 0x00000400,     /* 44.1   kHz, Mono,   16-bit */
            WAVE_FORMAT_44S16 = 0x00000800,     /* 44.1   kHz, Stereo, 16-bit */
            WAVE_FORMAT_48M08 = 0x00001000,     /* 48     kHz, Mono,   8-bit  */
            WAVE_FORMAT_48S08 = 0x00002000,     /* 48     kHz, Stereo, 8-bit  */
            WAVE_FORMAT_48M16 = 0x00004000,     /* 48     kHz, Mono,   16-bit */
            WAVE_FORMAT_48S16 = 0x00008000,     /* 48     kHz, Stereo, 16-bit */
            WAVE_FORMAT_96M08 = 0x00010000,     /* 96     kHz, Mono,   8-bit  */
            WAVE_FORMAT_96S08 = 0x00020000,     /* 96     kHz, Stereo, 8-bit  */
            WAVE_FORMAT_96M16 = 0x00040000,     /* 96     kHz, Mono,   16-bit */
            WAVE_FORMAT_96S16 = 0x00080000,     /* 96     kHz, Stereo, 16-bit */
        }
        [DllImport("winmm.dll")]
        public static extern MMRESULT waveInGetDevCapsW(uint uDeviceID, out WAVEINCAPS pwic, uint cbwic);
        [DllImport("winmm.dll")]
        public static extern MMRESULT waveOutGetDevCapsW(uint uDeviceID, out WAVEOUTCAPS pwoc, uint cbwoc);
    }
}

三、使用示例

foreach (var i in Winmm.WaveInDevices)
{
    Console.WriteLine("音頻采集設(shè)備" + i.Id + ":" + i.Name);
}
foreach (var i in Winmm.WaveOutDevices)
{    
    Console.WriteLine("音頻播放設(shè)備"+i.Id+":" +i.Name);
}

總結(jié)

以上就是今天要講的內(nèi)容,使用winnm枚舉設(shè)備還是比較簡(jiǎn)單的,唯一麻煩一點(diǎn)的地方就是支持格式的獲取,但是通過(guò)C#使用字符串處理,實(shí)現(xiàn)也變得很簡(jiǎn)單。總的來(lái)說(shuō),這算是一種獲取音頻設(shè)備信息的方法,能夠滿足一些使用場(chǎng)景的需求。

到此這篇關(guān)于C#通過(guò)實(shí)現(xiàn)winmm枚舉音頻設(shè)備的文章就介紹到這了,更多相關(guān)C# winmm枚舉音頻設(shè)備內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論