Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

c# - Reading The System Audio Output Stream

I am currently Making an Oscilloscope Component For XNA and need a bit of help. I would Like to get the Audio Information form The Systems Audio Output Stream, However i am finding it extremely hard to do so. i have found Some Resources but nothing that helps me all the way, or it helps in a way i am not able to grasp. Here are the Following Resources i have found so far.

How to programmatically get the current audio level?

http://msdn.microsoft.com/en-us/library/ms712636

http://social.msdn.microsoft.com/Forums/en/xnagamestudioexpress/thread/6a3ea3da-849b-475d-a2a4-7cf7c27347d5

As i am not Able to completely get a handle on what to do i have humbly come to you for your help Thank you Vary much.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

DirectSound has a lot of nuance to it that can make it difficult to work with. If you're open to using some third-party options, there are a few free ones available that abstract the technical details of DirectSound and make this problem much more approachable. I personally recommend BASS.NET - and NAudio is good if you're more interested in an entirely managed solution.

In BASS.NET, your code would look something like this:

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;
}

Basically, you're initializing BASS. Then you loop through all the possible input sources searching for "What U Hear" or "Stereo Mix." The name of the channel that is a combination of all your speaker output varies from soundcard to soundcard, so you'll have to get a list of the common names. After you've found an appropriate channel, you'll start recording. The MyRecording method will have a buffer for you to analyze.

This is just one way to do it, with one library. Take a look around and see which library provides you with data in a format you want it in.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...