我一直使用waveInGetDevCaps获取waveIn设备的名称,但WAVEINCAPS结构只支持31个字符加上null,这意味着在我的计算机上,我得到的设备名称被截断:
Microphone / Line In (SigmaTel
Microphone Array (SigmaTel High,
我确信必须有一种获取完整设备名称的方法,但有人知道那是什么吗?
答案 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();