c# - 您将如何编写钢琴 Octave 音程?

标签 c# algorithm f#

如果没有涵盖所有可能的音符,我想编写一个算法,在给定的 Octave 音阶中构建规则的 3 键钢琴和弦进行,然后转移到下一个 Octave 音阶。例如:

Cmaj 键会给出其进程中的所有音符/和弦,因为起始音符是 Octave 音阶的开始,它将在下一个 C 处终止。但是如果我从同一个 Octave 音阶的 B 音符开始,它将结束下一个也是B。

我想为大调和小调构建它,并能够在未来将其扩展为 7 和 9 型和弦。

这不是作业,我想用c#然后用f#重写,多学一点语言。

编辑:

我的问题是: 我应该为 Octave 音程(C 到 C)使用什么数据结构:LinkedList List 或者这可能需要完全不同的结构?

编辑2: 因此,如果我们像这样索引注释,我不确定这是否是一种正确的方法: 0 1 2 3 4 5 6 7 8 9 10 11 12

输入:音符 = C (0),音阶 = Maj 输出:0 4 7、2 5 9、4 7 12 等

最佳答案

或许,对此建模的最简单方法是使用 midi note mapping 的概念,因为键被枚举并且来自给定根的第一个反转三元组将是

root, root + 4, root + 7

下一个反转是

root + 4, root + 7, root + 12

下一个反转是

root + 7, root + 12, root + 16

其中 root 是根音的 MIDI 音符编号。

事实上,给定第一个转位的和弦,通过删除第一个条目,将其放在最后并添加 12 来生成所有其他转位是微不足道的。所以你的和弦真的开始看起来像这样:

public int GetChord(ChordName chord)
{
    switch (chord) {
    case ChordName.Major: return new int[] { 0, 4, 7 };
    case ChordName.Minor: return new int[] { 0, 3, 7 };
    case ChordName.Augmented: return new int[] { 0, 4, 8 };
    case ChordName.Dominant7: return new int[] { 0, 4, 7, 10 };
    case ChordName.Maj7: return new int[] { 0, 4, 7, 11 };
    // etc
 }

然后无论从此处返回什么(并且可能使用 List 会更好),您都可以编写一个返回每个反转的 IEnumerable。然后你将根的值添加到输出和 ta-da!你有了自己的和弦,现在非常容易输出为 midi。

public int[] InvertChord(int[] chord)
{
    int[] inversion = new int[chord.Length];
    for (int i = 1; i < chord.Length; i++) {
        inversion[i-1] = chord[i];
    }
    inversion[inversion.Length-1] = chord[0] + 12;
    return inversion;
}

public int[][] ChordAndAllInversions(int[] chord)
{
    int[][] inversions = new int[chord.Length][];
    inversions[0] = chord;
    for (int i=1; i < chord.Length; i++) {
        inversions[i] = InvertChord(inversions[i - 1]);
    }
    return inversions;
}

关于c# - 您将如何编写钢琴 Octave 音程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4454728/

相关文章:

c# - xamarin android 应用程序 : how to get the Resources folder of my project

c++ - std::sort 将元素与 null 进行比较

f# - 如何避免更改参数顺序

algorithm - 如何在订单行上按比例分配折扣?

c# - 修剪 float

c# - 自动完成案例问题

c# - 如何在 jQuery DataTables 中添加静态列

algorithm - 在两个给定的有理数之间找到最简单的有理数

C++图形构建问题

f# - 如何在 F# 中导出记录类型?