使相邻音符之间的距离相同(Theremin 类似应用程序)

Ruu*_*uza 5 c# math audio frequency unity-game-engine

我正在 Unity (C#) 中制作一个类似 Theremin 的应用程序。

我有水平 X 轴,我可以在其上单击(用鼠标或用智能手机上的手指)。该 X 轴决定播放的频率。用户将指定板的频率范围(X 轴),假设从频率 261.63(注释 C4)到 523.25(注释 C5)。

我将计算x_position_ratio哪个是 0 到 1 之间的数字,确定用户在 X 轴上单击的位置(0 在最左边(在本例中注意 C4),1 在最右边(注意 C5))

由此,我将通过方程计算播放频率

float freqRange = maxFreq - minFreq;
float frequency = (x_position_ratio * freqRange) + minFreq;
Run Code Online (Sandbox Code Playgroud)

然后播放frequency. 它工作得很好。

如果我在黑板上(X 轴)绘制音符,我们可以看到,频率越高,两个音符之间的跳跃就越高。

// Drawing just note A4 to demonstrate the code
float a4 = 440.0f //frequency of note A4
float x_position = (a4 - minFreq) / freqRange;
Run Code Online (Sandbox Code Playgroud)

loc_x_position指示音符在 X 轴上的位置(0 到 1 之间)

输出

问题:

我想在两个音符之间进行同样的跳跃(如果你明白我的意思的话,让它呈线性而不是指数)。在维基百科上找到了Piano_key_frequencies等式,但它是针对琴键的。我希望它适用于每个频率,但我不知道如何在我发布的 2 个代码示例中实现它

Ruu*_*uza 1

我想到了。尝试将其绘制为对数以至少近似结果。

我受到这个答案的启发绘制对数图结果 证明这个解决方案有效

为了在 x 轴上绘制注释,我使用了以下命令:

minFreq = Mathf.Log10(minFreq);
maxFreq = Mathf.Log10(maxFreq);
float freqRange = maxFreq - minFreq;
x_position = (Mathf.Log10(frequencyOfNoteToPlot) - minFreq) / freqRange;
Run Code Online (Sandbox Code Playgroud)

为了计算频率,我刚刚从 x_position 的方程中导出了频率,并最终得到了这段代码:

frequency = Mathf.Pow(10, x_position * freqRange + minFreq);
Run Code Online (Sandbox Code Playgroud)

我仍然不明白的一件事是,为什么我使用对数的底数并不重要。是因为我总是得到比率(0 到 1 之间的值)吗?