2012-04-04 76 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