开发者

Is it possible to generate a constant sound in C# while adjusting its frequency?

Is it possible to generate a constant sound in C# and manipulate its frequency as it goes?

I tried something like this:

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

But being synchronous, the loop waits for each beep to finish. So I tried this:

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

I w开发者_如何学JAVAould think this would be a start toward generating a constant sound that is ever increasing in frequency. However, it still stutters as it goes. Is there a way to accomplish this but more smoothly?


If you want to do this in real-time (i.e. change the frequency dynamically in response to user input), this would be incredibly difficult and would entail your writing a software synthesizer. In that case, you might want to try using a library like NAudio (although I'm not 100% sure NAudio does realtime synthesis).

On the other hand, if you just want to pre-generate a WAV file with a continuously ascending tone and then play it, that's incredibly easy.

Edit: a third alternative is to play a MIDI sound and send control change messages to the MIDI device to gradually apply portmanteau to a playing note. This is also easy, but has the disadvantage that you can't be sure exactly how it will sound on somebody else's computer.


Code below generate sine wave. You can to change frequency and other parameters

    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);
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜