2009-10-29 39 views
8

我需要創建包含許多不同頻率的音調的聲音。有沒有辦法在C#中做到這一點?是否有可能在C#中生成複雜的音調?

迄今爲止我所見過的唯一的音色生成方法涉及到console.beep,它可以工作,但只適用於純音調(單個頻率)。

+0

對於您的信息,使用電腦揚聲器(用於發出嗶嗶聲)通常不是一個好習慣。您應該使用默認的音頻輸出。 – decasteljau 2009-10-29 11:55:30

+0

我實際上更喜歡使用默認音頻輸出。最終它將*需要*通過耳機。 – 2009-10-29 11:57:15

+4

這是一個重要的觀點。忘掉嘟嘟聲。你想使用DirectSound或WaveOut。兩者都是非託管API,因此您必須使用PInvoke或切換到C++/CLI作爲您的語言。 – CannibalSmith 2009-10-29 12:36:16

回答

19

Audiere庫使這非常容易做到。這裏有一個幾乎完整的C#程序產生的「1」按鈕,雙音多頻:

AudioDevice device = new AudioDevice(); 
OutputStream tone1a = device.CreateTone(697); // part A of DTMF for "1" button 
OutputStream tone1b = device.CreateTone(1209); // part B 
tone1a.Volume = 0.25f; 
tone1b.Volume = 0.25f; 
tone1a.Play(); 
tone1b.Play(); 
Thread.Sleep(2000); 
// when tone1a stops, you can easily tell that the tone was indeed DTMF 
tone1a.Stop(); 

在C#中使用Audiere,最簡單的方法來啓動和運行是使用Harald Fielker's C# binding(他聲稱在Mono作品 VS;我可以確認它在VS2005的完整版本以及使用單獨的Express 2008版本的C#和VC++中都有效)。你需要下載Win32 Audiere DLL, lib, and header(它們都在同一個zip中),你需要使用VC++和C#從源代碼構建C#綁定。

使用Audiere的好處之一是呼叫是非阻塞的。在開始tone1b之前,您不必等待tone1a才能停止播放,這顯然是播放複雜音調的必要條件。我不知道有多少可同時使用的輸出流的硬限制,因此可能是您的硬件/操作系統支持。順便說一下,Audiere還可以播放某些音頻文件(MP3,WAV,AIFF,MOD,S3M,XM,IT本身; Ogg Vorbis,Flac,Speex和外部庫),而不僅僅是純音。

一個可能的缺點是,當您開始或停止單個音調時會有輕微的「喀噠」聲;如果您將一種音調添加到已播放的音調中,則不會引人注意。我發現的最簡單的解決方法是,在您打開或關閉音調時,分別緩慢地調高音調的音量。你可能不得不使用斜坡速度來讓它聽起來「恰到好處」。

請注意,Audiere是LGPL許可的,並且該綁定沒有附加許可證。如果你想在商業產品中使用他的約束力,你必須諮詢你的法律團隊或試圖獲得Harald的控制權;或者你可以做出自己的約束力,避免麻煩。


@Tom:由於Harald的圖書館沒有附加任何特定許可證,因此我不確定託管它會產生什麼樣的影響;不過,我相信我至少可以給你詳細介紹我的libaudieresharpglue項目的設置。

使用Visual C++ Express 2008,打開bindings/csharp/libaudieresharpglue/vc8.0/libaudieresharpglue.sln. VC++會自動將解決方案轉換爲VS9解決方案。

在另一個文件夾中,您應該擁有Sourceforge的Audiere包。在您的VC++項目屬性下,轉至配置屬性> C/C++>常規,並確保您的「其他包含目錄」中包含path/to/audiere-1.9.4-win32/include。然後,在同一窗口中,轉到鏈接器>常規,並確保在「其他庫目錄」中有/path/to/audiere-1.9.4-win32/lib。然後,您應該能夠在您的vc8.0/Release文件夾中構建項目(最好處於發佈模式)和此輸出libaudieresharpglue.dll

接下來,打開Visual C#Express 2008.打開bindings\csharp\test\vc8.0\AudiereCSharpTest.sln並讓它轉換解決方案。該項目應該建立好,但是當你運行它時你會得到一個錯誤。沒關係;在您的csharp/test/vc8.0/bin/Release文件夾中,您需要添加VC++解決方案中的libaudieresharpglue.dll和Sourceforge中包中的audiere.dll。

現在,您應該可以構建並運行AudiereCSharpTest。請注意,默認情況下,#define stream_test未在AudiereTest.cs的頂部註釋掉,並且會引用不在硬盤上的文件。您可以簡單地註釋掉#define並取消註釋noise_testsquare_test

這應該覆蓋它;如果我錯過了任何細節,希望它們足夠小,可以自己拿來:)

+0

這是一個很好看的圖書館,如果NAudio dosn't沒有爲我工作,可能會仔細看看。 – 2009-11-03 18:37:45

+0

我在編譯包裝器的「libaudieresharpglue.dll」部分時遇到了很大的問題。任何想法,我可以只抓住一個二進制文件? – 2009-11-06 12:38:38

+0

我接受了這個,因爲這顯然是我需要做的。儘管你的白癡證明解釋然而,我仍然無法得到「libaudieresharpglue.dll」編譯(停在100錯誤)。當我鏈接時,它告訴我它不能打開輸入文件'。\ Release \ audiere.obj' - 是否有一些我想念的小東西? – 2009-11-09 14:39:28

0

是的,這是可能的。

Here is a link在這個教程。但當然這也採用Console.Beep

+0

從我看到的那裏也一次只能生成單音。 – Joey 2009-10-29 11:53:24

4

你總是可以嘗試的DirectSound ...

+0

您是否有一個專門用DirectSound生成複雜音調的鏈接? – 2009-10-29 11:59:21

+2

簡而言之,您會將很多sin()調用的結果寫入波形緩衝區,然後讓它回放該緩衝區。 – Kylotan 2009-11-03 16:05:47

0

MSDN文檔清楚,如果Console.Beep是異步與否不做。如果是這樣,您可以快速連續發射儘可能多的電話,而且沒有人會更聰明。當然,你會想要使用頻率和持續時間的版本。

+0

它是同步的。 – Joey 2009-10-29 11:51:11

+0

我是C#的新手 - 同步調用可以使用線程分層嗎? – 2009-10-29 11:56:29

+1

您可以使用新線程調用Console.Beep,但您仍然無法一次播放多個聲音。 – twk 2009-10-29 12:34:34

3

我一直在尋找NAudio的目的是創建一個模擬反饋,同時播放支持音軌的程序。有一篇關於生成sine waves at specific frequencies的博客文章,我懷疑這可能適合做你正在尋找的東西。

+0

這是迄今爲止最有希望的,但我一直無法獲得超過一個頻率運行在一起。 – 2009-11-03 15:34:03

+0

您是否嘗試過使用多線程,文檔提到支持Windows混合設備。 – 2009-11-03 18:35:38

相關問題