获取waveIn设备的全名

时间:2009-09-19 18:22:52

标签: winapi audio

我一直使用waveInGetDevCaps获取waveIn设备的名称,但WAVEINCAPS结构只支持31个字符加上null,这意味着在我的计算机上,我得到的设备名称被截断:

Microphone / Line In (SigmaTel 
Microphone Array (SigmaTel High, 

我确信必须有一种获取完整设备名称的方法,但有人知道那是什么吗?

7 个答案:

答案 0 :(得分:7)

是的,有一个解决方法。我已经在运输代码中多次解决了这个问题。

使用DirectSoundCapture枚举音频捕获设备。 API是DirectSoundCaptureEnumerate。它将返回设备的全长名称。

当然,您可能正在考虑“这很好,但我的其余代码设置为使用Wave API,而不是DirectSound。我不想将其全部切换。所以我该如何映射GUID DirectSoundCaptureEnumerate返回的ID是否为WaveIn API使用的整数ID?“

解决方案是针对DirectSoundPrivate对象的CoCreateInstance(或直接从dsound.dll调用GetClassObject)以获取指向IKsPropertySet接口的指针。在此界面中,您可以获取DSound GUID到Wave ID映射。有关详细信息,请参阅此网页:

http://msdn.microsoft.com/en-us/library/bb206182(VS.85).aspx

您想使用上面列出的网页上所述的DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING。

答案 1 :(得分:5)

我完成了waveIn设备的名称,探索了从MMDeviceEnumerator返回的名称。对于每个waveIn设备,当未完成的名称是EnumerateAudioEndPoints之一的全名的一部分时,我使用此全名以与waveIn设备相同的顺序填充组合框。

VisualBasic .NET:

   Dim wain = New WaveIn()
    Dim DeviceInfoI As WaveInCapabilities
    Dim nomedevice As String
    For de = 0 To wain.DeviceCount - 1
        DeviceInfoI = wain.GetCapabilities(de)
        nomedevice = DeviceInfoI.ProductName
        For deg = 0 To devices.Count - 1
            If InStr(devices.Item(deg).FriendlyName, nomedevice) Then
                nomedevice = devices.Item(deg).FriendlyName
                Exit For
            End If
        Next
        cmbMessaggiVocaliMIC.Items.Add(nomedevice)
    Next
    cmbMessaggiVocaliMIC.SelectedIndex = 0
    waveIn.DeviceNumber = cmbMessaggiVocaliMIC.SelectedIndex

答案 2 :(得分:5)

基于@Andrea Bertucelli回答的改进/完整C#WPF代码

library(shiny)

data <- read.csv2("data.csv")
input <- as.list(data$v1)

checkboxGroupInput("input",
                   label = "input",
                   choices = input,
                   selected = input)

答案 3 :(得分:3)

看起来DirectSoundPrivate存在一些问题。我试图从一个空项目访问它,它工作正常。但是,当我尝试从COM DLL或DLL线程访问它时,它会从E_NOTIMPL返回IKsPropertySet::Get错误。

但我想出了另一个技巧。似乎DirectSound以wave id顺序枚举捕获和呈现设备(不包括第一个默认值)。

我们仍然需要与旧的Wave API进行交互,但仍然缺乏正确的方法。 DirectShow提供基于WaveIn的音频输入设备,我需要获得相应的WASAPI ID,反之亦然。

答案 4 :(得分:3)

有一种涉及注册表的方法比使用DirectSound更简单。如果使用WAVEINCAPS2结构,它的名称GUID引用HKLM \ System \ CurrentControlSet \ Control \ MediaCategories下的键。如果密钥不存在,则只需在结构中使用该名称。这在http://msdn.microsoft.com/en-us/library/windows/hardware/ff536382%28v=vs.85%29.aspx上有记录。这是一个例子:

public static ICollection<AudioInputDevice> GetDevices()
{
  RegistryKey namesKey = Registry.LocalMachine.OpenSubKey(@"System\CurrentControlSet\Control\MediaCategories");

  List<AudioInputDevice> devices = new List<AudioInputDevice>();
  for(int i=0, deviceCount=waveInGetNumDevs(); i<deviceCount; i++)
  {
    WAVEINCAPS2 caps;
    if(waveInGetDevCaps(new IntPtr(i), out caps, Marshal.SizeOf(typeof(WAVEINCAPS2))) == 0 && caps.Formats != 0)
    {
      string name = null;
      if(namesKey != null)
      {
        RegistryKey nameKey = namesKey.OpenSubKey(caps.NameGuid.ToString("B"));
        if(nameKey != null) name = nameKey.GetValue("Name") as string;
      }
      devices.Add(new AudioInputDevice(name ?? caps.Name, caps.ProductGuid));
    }
  }
  return devices;
}

struct WAVEINCAPS2
{
  public short ManufacturerId, ProductId;
  public uint DriverVersion;
  [MarshalAs(UnmanagedType.ByValTStr, SizeConst=32)] public string Name;
  public uint Formats;
  public short Channels;
  ushort Reserved;
  public Guid ManufacturerGuid, ProductGuid, NameGuid;
}

[DllImport("winmm.dll")]
static extern int waveInGetDevCaps(IntPtr deviceId, out WAVEINCAPS2 caps, int capsSize);

[DllImport("winmm.dll", ExactSpelling=true)]
static extern int waveInGetNumDevs();

答案 5 :(得分:0)

我发现了使用注册表查找音频设备的全名(输入和输出)的另一种方法。

在Windows 7和Windows 10上工作。

此方法首先尝试亚当·M(Adam M.)的方法。他的方法对我不起作用,但以防万一,我添加为首选方法。

<html>
<head></head>
<body>
    <form action='#' method="post">
        <input type="text" name="name">
        <input type="submit" name="submit">  
    </form>

      <?php
         $name = name
         echo $name; 
      ?>
   </form>
</body>
</html>

答案 6 :(得分:0)

使用NAudio,我使用此代码获取完整的设备名称...

using NAudio.CoreAudioApi;
using NAudio.Wave;

要获取所有记录设备:

//create enumerator
var enumerator = new MMDeviceEnumerator();
//cycle through all audio devices
for (int i = 0; i < WaveIn.DeviceCount; i++)
    Console.WriteLine(enumerator.EnumerateAudioEndPoints(DataFlow.Capture, DeviceState.Active)[i]);
//clean up
enumerator.Dispose();

要获取所有捕获设备:

//create enumerator
var enumerator = new MMDeviceEnumerator();
//cyckle trough all audio devices
for (int i = 0; i < WaveOut.DeviceCount; i++)
    Console.WriteLine(enumerator.EnumerateAudioEndPoints(DataFlow.Render, DeviceState.Active)[i]);
//clean up
enumerator.Dispose();