在调整频率时,是否可以在C#中生成恒定声音?

时间:2011-09-30 22:53:55

标签: c# .net winforms audio

是否有可能在C#中产生一个恒定的声音并随着它的频率操纵它的频率?

我试过这样的事情:

for (int i = 500; i < 15000; i += 1)
{
    Console.Beep(i, 500));
}

但是同步,循环等待每个蜂鸣声完成。所以我尝试了这个:

for (int i = 500; i < 15000; i += 1)
{
    new Thread(x => Console.Beep(i, 500)).Start();
}

我认为这将是产生频率不断增加的恒定声音的开始。然而,它仍然口吃。有没有办法实现这一点但更顺利?

2 个答案:

答案 0 :(得分:7)

如果你想实时做到这一点(即根据用户输入动态改变频率),这将非常困难,并且需要你编写一个软件合成器。在这种情况下,您可能想尝试使用像NAudio这样的库(虽然我不是100%肯定NAudio会进行实时合成)。

另一方面,如果你只想预先生成一个连续升序的WAV文件然后播放它,这非常容易。

编辑:第三种方法是播放MIDI声音,并将控制变更信息发送到MIDI设备,逐步将portmanteau应用于播放音符。这也很容易,但缺点是你无法确定它在其他人的电脑上的确切声音。

答案 1 :(得分:2)

generate sine wave以下的代码。您可以更改频率和其他参数

    private void TestSine()
    {
        IntPtr format;
        byte[] data;
        GetSineWave(1000, 100, 44100, -1, out format, out data);
        WaveWriter ww = new WaveWriter(File.Create(@"d:\work\sine.wav"),
            AudioCompressionManager.FormatBytes(format));
        ww.WriteData(data);
        ww.Close();
    }

    private void GetSineWave(double freq, int durationMs, int sampleRate, short decibel, out IntPtr format, out byte[] data)
    {
        short max = dB2Short(decibel);//short.MaxValue
        double fs = sampleRate; // sample freq
        int len = sampleRate * durationMs / 1000;
        short[] data16Bit = new short[len];
        for (int i = 0; i < len; i++)
        {
            double t = (double)i / fs; // current time
            data16Bit[i] = (short)(Math.Sin(2 * Math.PI * t * freq) * max);
        }
        IntPtr format1 = AudioCompressionManager.GetPcmFormat(1, 16, (int)fs);
        byte[] data1 = new byte[data16Bit.Length * 2];
        Buffer.BlockCopy(data16Bit, 0, data1, 0, data1.Length);
        format = format1;
        data = data1;
    }

    private static short dB2Short(double dB)
    {
        double times = Math.Pow(10, dB / 10);
        return (short)(short.MaxValue * times);
    }