Firmware for HexBoard MIDI controller
Microtones: Add 31-TET, and add script for calculating pitches in hertz
| -rw-r--r-- | HexBoard_V1.1.ino | 41 | ||||
| -rwxr-xr-x | makePitches.py | 18 |
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) |