about summary refs log tree commit diff
diff options
context:
space:
mode:
authorZach DeCook <zachdecook@librem.one>2023-09-18 10:57:23 -0400
committerZach DeCook <zachdecook@librem.one>2023-09-18 10:57:23 -0400
commitaec787a79191085f04c1c7ef83dabf152709487d (patch)
tree55b140b59d4855cb2dc707a35699e1294497c92e
parent0e39f9ce1641e9b5d9118c97b6118c8a6b555e6f (diff)
downloadHexBoard-aec787a79191085f04c1c7ef83dabf152709487d.tar.gz
Microtones: Add 31-TET, and add script for calculating pitches in hertz
-rw-r--r--HexBoard_V1.1.ino41
-rwxr-xr-xmakePitches.py18
2 files changed, 47 insertions, 12 deletions
diff --git a/HexBoard_V1.1.ino b/HexBoard_V1.1.ino
index 9b76fe5..b0f31f3 100644
--- a/HexBoard_V1.1.ino
+++ b/HexBoard_V1.1.ino
@@ -221,6 +221,7 @@ const byte ezMajorLayout[elementCount] = { //Testing layout viability - probably
 const byte* currentLayout = wickiHaydenLayout;
 
 // These are for standard tuning only
+// We start an octave above standard midi because integer hertz only have so much resolution.
 const unsigned int pitches[128] = {
   16, 17, 18, 19, 21, 22, 23, 25, 26, 28, 29, 31,                                  // Octave 0
   33, 35, 37, 39, 41, 44, 46, 49, 52, 55, 58, 62,                                  // Octave 1
@@ -240,32 +241,45 @@ const unsigned int pitches[128] = {
   22350,                                                                           // F10
   23680                                                                            // F#10
 };
+// ./makePitches.py 220 19 -14
 const unsigned int pitches19[128] = {
-// start close to C
-264, 274, 284, 295, 306, 317, 329, 341, 354, 367, 380, 394, 409, 424,
+// start close to C3
+                         132, 137, 142, 147, 153, 158, 164, 170, 177, 183, 190, 197, 205, 212,
+220, 228, 237, 245, 255, 264, 274, 284, 295, 306, 317, 329, 341, 354, 367, 380, 394, 409, 424,
 // Octave starting at A=440
 440, 456, 473, 491, 509, 528, 548, 568, 589, 611, 634, 657, 682, 707, 733, 761, 789, 818, 848,
 880, 913, 947, 982, 1018, 1056, 1095, 1136, 1178, 1222, 1267, 1315, 1363, 1414, 1467, 1521, 1578, 1636, 1697,
 1760, 1825, 1893, 1964, 2037, 2112, 2191, 2272, 2356, 2444, 2535, 2629, 2727, 2828, 2933, 3042, 3155, 3272, 3394,
 3520, 3651, 3786, 3927, 4073, 4224, 4381, 4544, 4713, 4888, 5070, 5258, 5453, 5656, 5866, 6084, 6310, 6545, 6788,
-7040, 7302, 7573, 7854, 8146, 8449, 8763, 9088, 9426, 9776, 10139, 10516, 10907, 11312, 11732, 12168, 12620, 13089, 13576,
-14080, 14603, 15146, 15708, 16292, 16897, 17525, 18176, 18852, 19552, 20279, 21032, 21814, 22624, 23465, 24336, 25241, 26179, 27151
+7040, 7302, 7573, 7854, 8146, 8449, 8763, 9088, 9426, 9776, 10139, 10516, 10907, 11312, 11732, 12168, 12620, 13089, 13576
 };
+// ./makePitches.py 220 24 -18
 const unsigned int pitches24[128] = {
-// start close to C
-262, 269, 277, 285, 294, 302, 311, 320, 330, 339, 349, 359, 370, 381, 392, 403, 415, 427,
+// start close to C3
+                              131, 135, 139, 143, 147, 151, 156, 160, 165, 170, 175, 180, 185, 190, 196, 202, 208, 214,
+220, 226, 233, 240, 247, 254, 262, 269, 277, 285, 294, 302, 311, 320, 330, 339, 349, 359, 370, 381, 392, 403, 415, 427,
 // Octave starting at A=440
 440, 453, 466, 480, 494, 508, 523, 539, 554, 571, 587, 605, 622, 640, 659, 679, 698, 719, 740, 762, 784, 807, 831, 855,
 880, 906, 932, 960, 988, 1017, 1047, 1077, 1109, 1141, 1175, 1209, 1245, 1281, 1319, 1357, 1397, 1438, 1480, 1523, 1568, 1614, 1661, 1710,
 1760, 1812, 1865, 1919, 1976, 2033, 2093, 2154, 2217, 2282, 2349, 2418, 2489, 2562, 2637, 2714, 2794, 2876, 2960, 3047, 3136, 3228, 3322, 3420,
-3520, 3623, 3729, 3839, 3951, 4067, 4186, 4309, 4435, 4565, 4699, 4836, 4978, 5124, 5274, 5429, 5588, 5751, 5920, 6093, 6272, 6456, 6645, 6840,
-7040, 7246, 7459, 7677, 7902, 8134, 8372, 8617, 8870, 9130, 9397, 9673, 9956, 10248
+3520, 3623, 3729, 3839, 3951, 4067, 4186, 4309, 4435, 4565, 4699, 4836, 4978, 5124
 };
+// ./makePitches.py 220 31 -23
+const unsigned int pitches31[128] = {
+// Start close to C
+                                        132, 135, 138, 141, 144, 147, 150, 154, 157, 161, 165, 168, 172, 176, 180, 184, 188, 192, 197, 201, 206, 210, 215,
+220, 225, 230, 235, 241, 246, 252, 257, 263, 269, 275, 281, 288, 294, 301, 308, 315, 322, 329, 336, 344, 352, 360, 368, 376, 385, 393, 402, 411, 421, 430,
+440, 450, 460, 471, 481, 492, 503, 515, 526, 538, 550, 563, 575, 588, 602, 615, 629, 643, 658, 673, 688, 704, 720, 736, 753, 770, 787, 805, 823, 842, 861,
+880, 900, 920, 941, 962, 984, 1006, 1029, 1052, 1076, 1100, 1125, 1151, 1177, 1203, 1231, 1258, 1287, 1316, 1346, 1376, 1407, 1439, 1472, 1505, 1539, 1574, 1609, 1646, 1683, 1721,
+1760, 1800, 1840, 1882, 1925, 1968, 2013, 2058, 2105, 2152, 2201, 2251
+};
+
 // 41-TET 41 equal temperament
+// ./makePitches.py 220 41 +10
 const unsigned int pitches41[128] = {
-// Start close to C
+// Start close to C4
 261, 265, 269, 274, 279, 284, 288, 293, 298, 303, 309, 314, 319, 325, 330, 336, 341, 347, 353, 359, 365, 372, 378, 384, 391, 398, 404, 411, 418, 425, 433,
-// Octave
+// Octave starting at A=440
 440, 448, 455, 463, 471, 479, 487, 495, 504, 512, 521, 530, 539, 548, 557, 567, 577, 587, 597, 607, 617, 628, 638, 649, 660, 671, 683, 695, 706, 718, 731, 743, 756, 769, 782, 795, 809, 822, 836, 851, 865,
 880, 895, 910, 926, 942, 958, 974, 991, 1007, 1025, 1042, 1060, 1078, 1096, 1115, 1134, 1153, 1173, 1193, 1213, 1234, 1255, 1276, 1298, 1320, 1343, 1366, 1389, 1413, 1437, 1461, 1486, 1512, 1537, 1564, 1590, 1617, 1645, 1673, 1701, 1730,
 1760, 1790, 1821, 1852, 1883, 1915, 1948, 1981, 2015, 2049, 2084, 2120, 2156, 2193, 2230
@@ -450,7 +464,7 @@ void sequencerSetup();  //Forward declaration
 GEMItem menuItemSequencer("Sequencer:", sequencerMode, sequencerSetup);
 
 int tones = 12; // Experimental microtonal support
-SelectOptionInt selectTonesOptions[] = {{"12", 12}, {"19", 19}, {"24", 24}, {"41", 41}};
+SelectOptionInt selectTonesOptions[] = {{"12", 12}, {"19", 19}, {"24", 24}, {"31", 31}, {"41", 41}};
 GEMSelect selectTones(sizeof(selectTonesOptions)/sizeof(SelectOptionInt), selectTonesOptions);
 GEMItem menuItemTones("Tones:", tones, selectTones);
 
@@ -908,7 +922,8 @@ void reactiveLighting() {
 }
 
 int keyColor(byte note) {
-    return ((note - key + transpose) % tones) * ((5006*12)/tones);
+    // 60072
+    return ((note - key + transpose) % tones) * ((65536)/tones);
 }
 
 void buttonPattern(int i) {
@@ -1151,6 +1166,8 @@ void do_tone(byte pitch) {
         tone(TONEPIN, pitches[pitch]);
     } else if (tones == 19) {
         tone(TONEPIN, pitches19[pitch]);
+    } else if (tones == 31) {
+        tone(TONEPIN, pitches31[pitch]);
     } else if (tones == 24) {
         tone(TONEPIN, pitches24[pitch]);
     } else if (tones == 41) {
diff --git a/makePitches.py b/makePitches.py
new file mode 100755
index 0000000..7829e52
--- /dev/null
+++ b/makePitches.py
@@ -0,0 +1,18 @@
+#!/usr/bin/env python3
+import sys
+
+pitches=128
+
+# calculate integer values in hertz for equal-temperament scales
+def makePitches(root, tones, offset):
+    a = []
+    for index in range(offset, pitches+offset):
+        a.append(round(root*(2**(index/tones))))
+    return a
+
+if __name__ == '__main__':
+    offset = 0
+    if len(sys.argv) > 3:
+        offset = int(sys.argv[3])
+    pitches = makePitches(float(sys.argv[1]), int(sys.argv[2]), offset)
+    print(pitches)