2

耳鳴りの周波数に合わせたアプリを開発したい : 周波数が再生され、ユーザーがプラスまたはマイナスのボタンを押すことで周波数が増減します。(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);
    }

周波数の再生は問題ありませんが、ユーザーがボタンを押すと、周波数が更新されたときにクリック音が聞こえます。何が音を発しているのか、どうすればそれを取り除くことができるのか分かりますか? ありがとう。

4

3 に答える 3

2

周波数を変更すると、クリックとして現れる波形に不連続が生じます。絶対時間に対して信号計算を行う代わりに、正弦計算の位相を追跡し (例: 0 から 2*pi までの値)、位相にどれだけ追加する必要があるかを把握する必要があります (2*pi を引く)。特定の周波数を再生するときに、次のサンプルの 2*pi を超えるたびに)。このようにして、周波数を変更しても、パラメーターとして指定した位相がMath.Sin突然変化してクリック音が発生することはありません。

于 2015-01-18T20:14:52.023 に答える
0

@spender の回答を拡張すると (回答にコメントを追加するには 50 人の担当者が必要です)、で同様の問題が発生しました。正弦値の現在の符号と正弦値の前の符号を監視する 2 つの bool 値を追加することで、問題を解決できました。前の正弦が負で、現在の正弦が正の場合、正弦波の周波数を安全に調整できることがわかります。

            double sine = amplitude * Math.Sin(Math.PI * 2 * frequency * time);
            isPreviousSineWaveValPositive = isSineWaveValPositive;
            if (sine < 0)
            {
                isSineWaveValPositive = false;
            }
            else
            {
                isSineWaveValPositive = true;
            }

            // When the time is right, change the frequency
            if ( false == isPreviousSineWaveValPositive && true == isSineWaveValPositive )
            {
                time = 0.0;
                frequency = newFrequency;
            }
于 2015-07-16T16:38:27.003 に答える