c# - 合成器从一个频率滑到另一个频率

标签 c# audio synthesizer

我正在使用 NAudio 在 C# 中编写一个合成器。我试图让它在频率之间平滑滑动。但是我有一种感觉,我对所涉及的数学不了解。在切换到正确的下一个音高之前,它会以高音疯狂地滑动。

从一个音高滑到另一个音高的数学正确方法是什么?

代码如下:

public override int Read(float[] buffer, int offset, int sampleCount) { int sampleRate = WaveFormat.SampleRate;

        for (int n = 0; n < sampleCount; n++)
        {
            if (nextFrequencyQueue.Count > 0)
            {                    
                nextFrequency = nextFrequencyQueue.Dequeue();
            }

            if (nextFrequency > 0 && Frequency != nextFrequency)
            {
                if (Frequency == 0) //special case for first note
                {
                    Frequency = nextFrequency;
                }
                else //slide up or down to next frequency
                {
                    if (Frequency < nextFrequency)
                    {
                        Frequency = Clamp(Frequency + frequencyStep, nextFrequency, Frequency);
                    }
                    if (Frequency > nextFrequency)
                    {
                        Frequency = Clamp(Frequency - frequencyStep, Frequency, nextFrequency);
                    }
                }
            }

            buffer[n + offset] = (float)(Amplitude * Math.Sin(2 * Math.PI * time * Frequency));
            try
            {
                time += (double)1 / (double)sampleRate;
            }
            catch
            {
                time = 0;
            }
        }
        return sampleCount;
    }

最佳答案

您使用绝对时间来确定波函数,因此当您稍微改变频率时,下一个样本就是您以新频率开始运行时的样本。

我不知道已建立的最佳方法,但一个可能足够好的简单方法是计算相位 (φ = t mod 1/fold) 并调整 t 以保持相位在新的频率下 (t = φ/fnew).

更平滑的方法是保留一阶导数。这更困难,因为与波本身不同,一阶导数的振幅随频率变化,这意味着仅保留相位是不够的。无论如何,考虑到您平滑地改变频率,这种增加的复杂性几乎肯定是矫枉过正。

关于c# - 合成器从一个频率滑到另一个频率,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14035906/

相关文章:

c# - 当我在 .net 框架中将源代码编译为 exe 文件时会发生什么

c# - 播放背景音乐地铁应用

audio - 我想做一个关于声音编程的项目,但我不知道从哪里开始

javascript - riffwave.js 公式中的 (128 + 127 *) 部分是什么?

c# - 构建 Office 加载项时程序集绑定(bind)错误 : "FindRibbons" task failed unexpectedly

c# - 在测试方法中从 JSON 文件中删除元素

audio - FFmpeg:atrim = a: b 和 aselect = 'between (t, a, b)' 之间的区别

java - 通过两个不同的按钮播放两个不同的声音文件?

.net - Azure 文本到语音将 SpeakTextAsync 转换为有效的 NAudio 波流

c# - 程序集命名约定