2012-04-04 77 views
3

我有一个问题,它的表面看起来非常简单,但我有大量问题解决。从双列阵播放声音

我有2个双数组(左和右声道),包含由350kHz处的DAQ采样的数据,我已经下变频到44.1KHz。

我想要做的就是取这两个阵列并播放它们,但好像有很多选项可用于输出声音,例如directx,NAudio等,所以我希望可能有人在那里谁可以告诉我什么是做这件事的最佳方式,也许可以指引我走向正确的方向!

在此先感谢您的任何建议 - 将不胜感激。

戴夫

回答

3

n音讯是我听人提起过几次一个选项(像你一样太)。我知道这是一个开源的第三方库。你可能想看看。

不幸的是,从我的收集来看,在我看来,DirectX正在走出去,多年来MS已经改变了他们对几个不同的东西的推动,现在看来他们正在推动人们使用XNA实际上是一个完整的框架,当您在XNA中制作项目时,它可以在桌面环境或Xbox 360或Windows Phone上的Windows上运行。对我来说,Windows Phone并不是一件大事,因为它似乎并不是手机领域的大玩家,但在Xbox上运行的应用程序吸引了我。但是我在XNA框架/体系结构中看到了几个更好的功能,这些功能在常规的.NET框架中缺乏,包括视频播放和音频播放。由于我还没有跳入XNA的发展阶段,所以我不了解那些细节。

此外,您可能希望直接在.NET中使用System.Media.SoundPlayer播放它们,而无需任何第三方库。

我发现下面的代码播放简单的正弦波,使用它。它会生成声音样本,然后将其提供给使用SoundPlayer播放的MemoryStream。 SoundPlayer本身需要格式化为WAV格式的Stream,我知道它可以播放立体声,但我不需要立体声,所以我没有研究如何将其添加到WAV文件格式。我对此非常喜欢的是它不需要第三方DLL。如果此方法对你有用,那么这就是:

using System; 
using System.Collections.Generic; 
using System.IO; 
using System.Linq; 
using System.Windows.Forms; 

public static void PlayBeep(UInt16 frequency, int msDuration, UInt16 volume = 16383) 
{ 
    var mStrm = new MemoryStream(); 
    BinaryWriter writer = new BinaryWriter(mStrm); 

    const double TAU = 2 * Math.PI; 
    int formatChunkSize = 16; 
    int headerSize = 8; 
    short formatType = 1; 
    short tracks = 1; 
    int samplesPerSecond = 44100; 
    short bitsPerSample = 16; 
    short frameSize = (short)(tracks * ((bitsPerSample + 7)/8)); 
    int bytesPerSecond = samplesPerSecond * frameSize; 
    int waveSize = 4; 
    int samples = (int)((decimal)samplesPerSecond * msDuration/1000); 
    int dataChunkSize = samples * frameSize; 
    int fileSize = waveSize + headerSize + formatChunkSize + headerSize + dataChunkSize; 
    // var encoding = new System.Text.UTF8Encoding(); 
    writer.Write(0x46464952); // = encoding.GetBytes("RIFF") 
    writer.Write(fileSize); 
    writer.Write(0x45564157); // = encoding.GetBytes("WAVE") 
    writer.Write(0x20746D66); // = encoding.GetBytes("fmt ") 
    writer.Write(formatChunkSize); 
    writer.Write(formatType); 
    writer.Write(tracks); 
    writer.Write(samplesPerSecond); 
    writer.Write(bytesPerSecond); 
    writer.Write(frameSize); 
    writer.Write(bitsPerSample); 
    writer.Write(0x61746164); // = encoding.GetBytes("data") 
    writer.Write(dataChunkSize); 
    { 
     double theta = frequency * TAU/(double)samplesPerSecond; 
     // 'volume' is UInt16 with range 0 thru Uint16.MaxValue (= 65 535) 
     // we need 'amp' to have the range of 0 thru Int16.MaxValue (= 32 767) 
     double amp = volume >> 2; // so we simply set amp = volume/2 
     for (int step = 0; step < samples; step++) 
     { 
      short s = (short)(amp * Math.Sin(theta * (double)step)); 
      writer.Write(s); 
     } 
    } 

    mStrm.Seek(0, SeekOrigin.Begin); 
    new System.Media.SoundPlayer(mStrm).Play(); 
    writer.Close(); 
    mStrm.Close(); 
} // public static void PlayBeep(UInt16 frequency, int msDuration, UInt16 volume = 16383) 

当然,如果你使用这个最后的选择去,你需要弄清楚如何立体声格式转换成WAV格式,并期待成你自己(或询问)。快乐的编码!

+0

如果这对你有用,请投票。 (正如你所看到的,我的声望很低,我自己是StackOverflow的新手,所以我期望建立声望点,谢谢!) – Edward 2013-11-13 16:27:27

+0

我相信代码中的'track'变量是'channels'它的立体声效果是2。 http://www.sonicspot.com/guide/wavefiles.html是WAV文件格式信息的一个不错的页面。 – Edward 2013-11-13 16:34:12