C# 读取系统音频输出流

C# 读取系统音频输出流,c#,winapi,audio,.net-4.0,xna,C#,Winapi,Audio,.net 4.0,Xna,我目前正在为XNA制作示波器组件,需要一些帮助。我想从系统音频输出流中获取音频信息,但是我发现这样做非常困难。我已经找到了一些资源,但没有任何东西可以一直帮助我,或者在某种程度上帮助我无法掌握。以下是我迄今为止找到的以下资源 由于我无法完全掌握该做什么,我谦恭地向您寻求帮助,非常感谢您的帮助。DirectSound有很多细微差别,可能会使您难以使用。如果您愿意使用一些第三方选项,那么有一些免费选项可以抽象DirectSound的技术细节,使这个问题更容易解决。我个人推荐BASS.NET——

我目前正在为XNA制作示波器组件,需要一些帮助。我想从系统音频输出流中获取音频信息,但是我发现这样做非常困难。我已经找到了一些资源,但没有任何东西可以一直帮助我,或者在某种程度上帮助我无法掌握。以下是我迄今为止找到的以下资源


由于我无法完全掌握该做什么,我谦恭地向您寻求帮助,非常感谢您的帮助。

DirectSound有很多细微差别,可能会使您难以使用。如果您愿意使用一些第三方选项,那么有一些免费选项可以抽象DirectSound的技术细节,使这个问题更容易解决。我个人推荐BASS.NET——如果您对完全管理的解决方案更感兴趣,NAudio是个不错的选择

在BASS.NET中,您的代码如下所示:

private RECORDPROC _myRecProc; // make it global, so that the Garbage Collector can not remove it
...
Bass.BASS_RecordInit(-1);
_myRecProc = new RECORDPROC(MyRecording);
// start recording paused
int settings = 0;
int inputSource = 0;
while (settings != -1)
{
  // get the settings of that input
  settings = Bass.BASS_RecordGetInput(inputSource, ref vol);
  if ( Bass.BASS_RecordGetInputName(inputSource) == "What U Hear" ||
       Bass.BASS_RecordGetInputName(inputSource) == "Stereo Mix")
  { 
    break;
  }
  inputSource++;
}    

Bass.BASS_RecordSetInput(inputSource, BASSInput.BASS_INPUT_ON, 0.5F)

int recChannel = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, 50, _myRecProc, IntPtr.Zero);
...
// really start recording
Bass.BASS_ChannelPlay(recChannel, false);
...
// the recording callback
private bool MyRecording(int handle, IntPtr buffer, int length, IntPtr user)
{
  return true;
}
基本上,您正在初始化BASS。然后你在所有可能的输入源中循环搜索“What U Hearn”或“Stereo Mix”。声道的名称是所有扬声器输出的组合,因声卡而异,因此你必须获得一个常见名称列表。找到合适的频道后,您将开始录制。MyRecording方法将有一个缓冲区供您分析


这只是一种方法,只有一个库。环顾四周,看看哪个库以您想要的格式为您提供数据。

XNA包括一个MediaPlayer类,您可以通过该类访问一些“可视化数据”(频率及其音量的采样)。看看教程。

这个问题比听起来更具挑战性。DirectSound中有很多细微的行为。我发现有一些很好的第三方解决方案确实有助于抽象这一点。您是否愿意使用免费的外部库?我个人推荐BASS.NET,如果你想要一个完全管理的解决方案,NAudio是个不错的选择。@JacobJ谢谢你的反馈,我将研究这两个问题,并将结果发回。JacobJ,你介意把你的评论作为一个答案,这样我们就可以这样对待它了吗?嘿,我正计划自己解决它,但非常感谢你,我也会很积极地加上你对这个项目的感谢^_^