XAudio2-更改频率的点击声音时播放生成的正弦 [英] XAudio2 - Play generated sine, when changing frequency clicking sound

查看:68
本文介绍了XAudio2-更改频率的点击声音时播放生成的正弦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想开发一个与您的耳鸣频率匹配的应用程序:播放一个频率,并且用户可以通过按加号或减号按钮来降低或提高频率.(请参阅部分代码,基于stackoverflow thx的一些编码:-))

I want to develop an app to match your tinnitus frequency : A frequency is played and the user decrease or increase the freqency by pressing a plus or minus button. (see part of the codes, based on some coding from stackoverflow thx :-))

   public static short[] BufferSamples = new short[44100 * 1 * 2];  

    private SourceVoice sourceVoice;
    private AudioBuffer buffer;
    private int Tfreq;

    public MatchTinn()
    {
        InitializeComponent();
        Loaded += MatchTinn_Loaded;
        TFreq = 5000;
    }

    private void MatchTinn_Loaded(object sender, RoutedEventArgs e)
    {
        var dataStream = DataStream.Create(BufferSamples, true, true);

        buffer = new AudioBuffer
        {
            LoopCount = AudioBuffer.LoopInfinite,
            Stream = dataStream,
            AudioBytes = (int)dataStream.Length,
            Flags = BufferFlags.EndOfStream
        };

        FillBuffer(BufferSamples, 44100, Tfreq);

        var waveFormat = new WaveFormat();

        XAudio2 xaudio = new XAudio2();
        MasteringVoice masteringVoice = new MasteringVoice(xaudio);

        sourceVoice = new SourceVoice(xaudio, waveFormat, true);

        // Submit the buffer
        sourceVoice.SubmitSourceBuffer(buffer, null);
    }

    private void FillBuffer(short[] buffer, int sampleRate, int frequency)
    {
        if (sourceVoice != null)
        {
            sourceVoice.FlushSourceBuffers();
        }

        double totalTime = 0;

        for (int i = 0; i < buffer.Length - 1; i += 2)
        {
            double time = (double)totalTime / (double)sampleRate;

            short currentSample = (short)(Math.Sin(2 * Math.PI * frequency * time) * (double)short.MaxValue);

            buffer[i] = currentSample;
            buffer[i + 1] = currentSample;

            totalTime++;
        }


    private void m1_OnTap(object sender, GestureEventArgs e)
    {
        Tfreq = Tfreq - 1;

        if (Tfreq < 0)
        {
            Tfreq = 0;
        }

        FillBuffer(BufferSamples, 44100, Tfreq);

    }

    private void p1_OnTap(object sender, GestureEventArgs e)
    {
        Tfreq = Tfreq + 1;

        if (Tfreq > 16000)
        {
            Tfreq = 16000;
        }

        FillBuffer(BufferSamples, 44100, Tfreq);
    }

播放频率很好,但是当用户按下您的按钮时,在更新频率时会发出喀哒声.您是否知道声音的产生原因以及如何消除声音?谢谢.

Playing the frequency is fine, but when the user presses a button you here a clicking sound when the frequency is updated. Do you have any idea what makes the sound and how i can get rid of it? Thanks.

推荐答案

更改频率会导致波形不连续,表现为咔嗒声.而不是根据绝对时间进行信号计算,您应该跟踪正弦计算的相位(例如,从0到2 * pi的值),并弄清楚需要增加多少相位(减去2 * pi)每次播放特定频率时,下一个样本每次超过2 * pi).这样,当您更改频率时,您作为 Math.Sin 的参数提供的相位不会突然改变,从而引起点击.

When you change the frequency, you're causing a discontinuity in the waveform that manifests as a click. Instead of making your signal calculations against absolute time, you should keep track of the phase of your sine calculation (e.g. a value from 0 to 2*pi), and figure out how much you need to add to your phase (subtracting 2*pi every time you exceed 2*pi) for the next sample when playing a specific frequency. This way, when you change frequency, the phase that you supply as a parameter to Math.Sin doesn't change abruptly causing a click.

这篇关于XAudio2-更改频率的点击声音时播放生成的正弦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆