c - 当以任意顺序给出三个音符时如何解析和弦。数学

标签 c

我有一个 arduino 连接到 Stradella 系统钢琴 Accordion 。我在左手和弦的 12 个音符中的每一个上都有光学传感器。当我弹奏和弦时,它会触发三个传感器。如果我想让合成器演奏和弦,那没关系,但有时我想让它只演奏根音;所以如果我演奏 C 大调,我希望它只演奏音符 C。

在下表中,您可以看到 C 大调和弦的触发传感器是传感器 0,4 和 7。但是因为它们都是同时触发的,所以它们可能不会按该顺序到达,即它们可能到达4、0、7 或任意组合。

C 大调的根音很容易,找到相差为 7 的两个音符,根音是两者中较小的一个。 D 和 E 大调等也是如此。但是像 F 大调这样的高音和弦有一个高音再次环绕到底部,所以数字差异不再是 7。

           0  1  2  3  4  5  6  7  8  9  10 11
C  Major   X           X        X 
C# Major      X           X        X
D  Major         X           X        X
D# Major            X           X        X
E  Major               X           X        X
F  Major   X              X           X      
F# Major      X              X           X     
G  Major         X              X           X  
G# Major   X        X              X             
A  Major      X        X              X             
A# Major         X        X              X           
B  Major            X        X              X 

有没有人知道我如何能够相当便宜地确定这些和弦的根音(它以每秒 600 次的速度循环运行,而 arduino 正在做很多其他事情)。

我完全被难住了,我已经尝试过逐步循环直到达到 11,然后从 0 重新开始,对每个和弦重复 3 次,但它看起来很乱。

我还希望能够解决 Accordion 上的其他两排按钮,占主导地位的和减少的第 7 位

这是 C 的四个形状,其他 11 个音符将是相同的形状,但向右移动,直到它再次回到 0。

          0 1 2 3 4 5 6 7 8 9 10 11
C Major   X       X     X
C Minor   X     X       X
C 7th     X       X           X
C Dim7th  X     X           X

非常感谢任何建议!

最佳答案

差异仍然是 7 - 您必须只对 12 取模进行所有计算。因此,对于 F 大调,您只有 5,9,12,而对 12 取模是 5,9,0。或者反过来:你有 5、9、0 并且没有差异 7,所以只需将 12 添加到最低的 (0) 得到 (12),然后基音为 5。

更简单的做法是,如果相差为 7,则采用较低的音符,但如果相差为 5,则采用较高的音符。

############# 编辑:

另一种方法是拥有一个 Map(Int, Chord) 或一个包含 1024 个元素的数组,您只需用所有已知的和弦填充即可。像上面一样,你已经完成了工作。这个想法是有 12 位数字,您只需将 1 多次移动到每个数字的 lft 即可获得 key 。

示例:

char * notes[1024];
// earlier, in initialization:
notes[0x221] = "F-Major";
notes[....]  = ....;   // do that for all chords you're interested in
// this are the numbers you get:
int a = 5, b= 9, c=0;    // F Major
int key = (1 << a) | (1 << b) | (1 << c);   // 0b10 0010 0001 = 0x221
char *chord = notes[key];

关于c - 当以任意顺序给出三个音符时如何解析和弦。数学,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20020081/

相关文章:

c - 为什么我的链表显示垃圾值

c - 如何检查变量是否包含字符串

c - 什么时候将项目拆分为多个 C 文件? (大型项目的良好实践)

c - 在 C 中扩展结构体字段

c - 将多维数组传递给c中的函数会导致堆栈溢出

c - Visual Studio 2010 C++ 意外的命令行参数

c - 使用 C 返回数组

c - 编译成c的高级系统语言?

c - 代码解释(链表C)

C:需要将二维数组的某些部分写入新的二维数组