如何根据频率生成声音?

可能重复:
在C#中创建正弦波或方波

我想生成声音。 要么像:

MakeSound(frequency, duration); 

要么:

 MakeSound(MyArrayOfSamples); 

我发现了一些名为: Microsoft.Directx.DirectSound但已经读过它已经停止使用。 我无法在Visual Studio(2010)中找到它作为参考的选项。 根据我所读的内容,我发现这个链接应该包含它,但是因为它可能不再受支持而犹豫是否使用了2006年的内容。 而且这个说它是用于C / C ++(尽管也说:“托管代码”)并且我不想浪费几周试图理解如何将其包装到托管代码中,只是为了发现我做不到。 我发现最有希望的链接是WaveFormat,但我找不到如何使用它。

不是在问如何获得声波的数学表示。 我也不知道如何播放mp3文件等。 我也不是在寻找第三方软件或包装器。 仅针对特定目标的C#/ .net解决方案。

无论你是哪种方式,除非你想使用非托管代码,否则你将不得不构建一个WAV来播放它。 但是,下面是Eric Lippert博客的代码片段,它将向您展示如何使用频率滚动自己的WAV文件。

 namespace Wave { using System; using System.IO; class MainClass { public static void Main() { FileStream stream = new FileStream("test.wav", FileMode.Create); BinaryWriter writer = new BinaryWriter(stream); int RIFF = 0x46464952; int WAVE = 0x45564157; int formatChunkSize = 16; int headerSize = 8; int format = 0x20746D66; 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 data = 0x61746164; int samples = 88200 * 4; int dataChunkSize = samples * frameSize; int fileSize = waveSize + headerSize + formatChunkSize + headerSize + dataChunkSize; writer.Write(RIFF); writer.Write(fileSize); writer.Write(WAVE); writer.Write(format); writer.Write(formatChunkSize); writer.Write(formatType); writer.Write(tracks); writer.Write(samplesPerSecond); writer.Write(bytesPerSecond); writer.Write(frameSize); writer.Write(bitsPerSample); writer.Write(data); writer.Write(dataChunkSize); double aNatural = 220.0; double ampl = 10000; double perfect = 1.5; double concert = 1.498307077; double freq = aNatural * perfect; for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI))); writer.Write(s); } freq = aNatural * concert; for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI))); writer.Write(s); } for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI) + Math.Sin(t * freq * perfect * 2.0 * Math.PI))); writer.Write(s); } for (int i = 0; i < samples / 4; i++) { double t = (double)i / (double)samplesPerSecond; short s = (short)(ampl * (Math.Sin(t * freq * 2.0 * Math.PI) + Math.Sin(t * freq * concert * 2.0 * Math.PI))); writer.Write(s); } writer.Close(); stream.Close(); } } } 

根据您的需要将其分开,但请注意aNatural变量 - 它是一个频率 - 就像您正在寻找的那样。

现在,您可以将其放入MemoryStream ,然后根据需要使用SoundPlayer播放它。

这是内核中Beep函数的包装器,包含持续时间和频率。 现在Beep使用声卡; 在我的日子里,它使用了粘在主板上的一些压电设备。

 using System; using System.Runtime.InteropServices; class BeepSample { [DllImport("kernel32.dll", SetLastError=true)] static extern bool Beep(uint dwFreq, uint dwDuration); static void Main() { Console.WriteLine("Testing PC speaker..."); for (uint i = 100; i <= 20000; i++) { Beep(i, 5); } Console.WriteLine("Testing complete."); } } 

在我的Win10盒子上,我需要将持续时间(最后一个参数)设置为比这里的5毫秒大得多,最多可达50毫秒,但为了得到合理的东西,我必须让它达到100毫秒。

或者,如果您想采用简单的路线,请使用Console.Beep(Int32,Int32)方法。 该方法是在.Net 2.0中引入的。