├── MIDI_Synth_6.ino ├── README.md ├── fixedPoint.h └── osciGraphics.h /MIDI_Synth_6.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //starage for ADSR envelope 4 | char adsr[16][4]; 5 | //wave shape parameters 6 | char wavePar[8]; 7 | //interpolated signed wave samples 8 | char wave[256]; 9 | 10 | //!!!!! comment in next line for graphics on the oscilloscope 11 | //#define GRAPHICS 12 | 13 | #ifdef GRAPHICS 14 | #include "osciGraphics.h" 15 | #endif 16 | 17 | #include "fixedPoint.h" 18 | 19 | //this frequency table is for 44100Hz 20 | const unsigned long freqIncTab[] PROGMEM = {796254, 843601, 893765, 946911, 1003217, 1062871, 1126073, 1193033, 1263974, 1339134, 1418763, 1503127, 1592507, 1687203, 1787529, 1893821, 2006434, 2125742, 2252146, 2386065, 2527948, 2678268, 2837526, 3006254, 3185015, 3374406, 3575058, 3787642, 4012867, 4251485, 4504291, 4772130, 5055896, 5356535, 5675051, 6012507, 6370030, 6748811, 7150117, 7575285, 8025735, 8502970, 9008582, 9544261, 10111792, 10713070, 11350103, 12025015, 12740059, 13497623, 14300233, 15150569, 16051469, 17005939, 18017165, 19088521, 20223584, 21426141, 22700205, 24050030, 25480119, 26995246, 28600467, 30301139, 32102938, 34011878, 36034330, 38177043, 40447168, 42852281, 45400411, 48100060, 50960238, 53990491, 57200933, 60602278, 64205876, 68023757, 72068660, 76354085, 80894335, 85704563, 90800821, 96200119, 101920476, 107980983, 114401866, 121204555, 128411753, 136047513, 144137319, 152708170, 161788671, 171409126, 181601643, 192400238, 203840952, 215961966, 228803732, 242409110, 256823506, 272095026, 288274639, 305416341, 323577341, 342818251, 363203285, 384800477, 407681904, 431923931, 457607465, 484818220, 513647012, 544190053, 576549277, 610832681, 647154683, 685636503, 726406571, 769600953, 815363807, 863847862, 915214929, 969636441, 1027294024, 1088380105, 1153098554, 1221665363}; 21 | const unsigned char compressTab[] PROGMEM = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77, 78, 78, 78, 79, 79, 79, 80, 80, 80, 81, 81, 82, 82, 82, 83, 83, 83, 84, 84, 85, 85, 85, 86, 86, 87, 87, 87, 88, 88, 89, 89, 89, 90, 90, 91, 91, 92, 92, 92, 93, 93, 94, 94, 95, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125, 126, 126, 127, 127, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141, 142, 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149, 150, 150, 150, 151, 151, 152, 152, 153, 153, 154, 154, 155, 155, 156, 156, 157, 157, 157, 158, 158, 159, 159, 160, 160, 161, 161, 161, 162, 162, 163, 163, 164, 164, 164, 165, 165, 166, 166, 167, 167, 167, 168, 168, 169, 169, 169, 170, 170, 171, 171, 171, 172, 172, 173, 173, 173, 174, 174, 174, 175, 175, 176, 176, 176, 177, 177, 177, 178, 178, 178, 179, 179, 180, 180, 180, 181, 181, 181, 182, 182, 182, 183, 183, 183, 184, 184, 184, 185, 185, 185, 185, 186, 186, 186, 187, 187, 187, 188, 188, 188, 188, 189, 189, 189, 190, 190, 190, 191, 191, 191, 191, 192, 192, 192, 192, 193, 193, 193, 194, 194, 194, 194, 195, 195, 195, 195, 196, 196, 196, 196, 197, 197, 197, 197, 198, 198, 198, 198, 199, 199, 199, 199, 199, 200, 200, 200, 200, 201, 201, 201, 201, 201, 202, 202, 202, 202, 203, 203, 203, 203, 203, 204, 204, 204, 204, 204, 205, 205, 205, 205, 205, 206, 206, 206, 206, 206, 207, 207, 207, 207, 207, 207, 208, 208, 208, 208, 208, 209, 209, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 212, 212, 212, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 214, 214, 214, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 216, 216, 216, 216, 216, 216, 216, 216, 217, 217, 217, 217, 217, 217, 217, 218, 218, 218, 218, 218, 218, 218, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 222, 222, 222, 222, 222, 223, 223, 223, 223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 224, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 247, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 249, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}; 22 | //~reciprocal look up table 23 | const unsigned short rcp[] PROGMEM = {65535, 32767, 21844, 16383, 13106, 10922, 9361, 8191, 7281, 6553, 5957, 5460, 5040, 4680, 4368, 4095, 3854, 3640, 3448, 3276, 3120, 2978, 2848, 2730, 2620, 2520, 2426, 2340, 2259, 2184, 2113, 2047, 1985, 1927, 1871, 1819, 1770, 1724, 1679, 1637, 1597, 1559, 1523, 1488, 1455, 1424, 1393, 1364, 1336, 1310, 1284, 1259, 1236, 1213, 1191, 1169, 1149, 1129, 1110, 1091, 1073, 1056, 1039, 1023, 1007, 992, 977, 963, 949, 935, 922, 909, 897, 885, 873, 861, 850, 839, 829, 818, 808, 798, 789, 779, 770, 761, 752, 744, 735, 727, 719, 711, 704, 696, 689, 682, 675, 668, 661, 654, 648, 642, 635, 629, 623, 617, 611, 606, 600, 595, 589, 584, 579, 574, 569, 564, 559, 554, 550, 545, 541, 536, 532, 528, 523, 519, 515, 511}; 24 | 25 | char noteMap[16][128]; 26 | #define MAX_NOTES 8 27 | 28 | class Note 29 | { 30 | public: 31 | unsigned char channel; 32 | unsigned char note; 33 | char state; 34 | //fixed point precalculated parameters 35 | uf8p24 phase; 36 | uf8p24 freqInc; 37 | uf8p24 envelopePhase; 38 | uf0p16 envelopePhaseIncA; 39 | uf0p16 envelopePhaseIncD; 40 | uf0p16 envelopePhaseIncR; 41 | uf0p8 envelopeAmpS; 42 | uf0p8 envelopeAmpR; 43 | uf0p8 envelopeAmp; 44 | uf0p8 envelopeAmpDeltaS; 45 | uf0p8 envelopeAmpDeltaA; 46 | uf0p8 velocity; 47 | uf0p8 envelopeAmpA; 48 | 49 | Note() 50 | { 51 | state = -1; 52 | envelopeAmp = 0; 53 | } 54 | 55 | void setEnvelope(unsigned char v) 56 | { 57 | velocity = (v << 1) + 1; //scale velocity to [1 - 255] 58 | //precalculate values 59 | //each envelope phase counts for 65536 steps (16 bit). the actual time they take is resulting from the increment we count up to thes value 60 | //the upper 8 bits of the envelope phase indicate in which region of ADSR we are 61 | envelopePhase = 0; 62 | envelopePhaseIncA = pgm_read_word(&rcp[adsr[channel][0]]); // 1/A 63 | envelopePhaseIncD = pgm_read_word(&rcp[adsr[channel][1]]); // 1/D 64 | envelopePhaseIncR = pgm_read_word(&rcp[adsr[channel][3]]); // 1/R 65 | envelopeAmpS = mul_uf0p8_uf0p8_uf0p8(velocity, (adsr[channel][2] << 1) + 1); // S (scaled to 1 - 255) * velocity 66 | envelopeAmpDeltaS = velocity - envelopeAmpS; // delta between max amp 67 | envelopeAmpDeltaA = velocity - envelopeAmpA; //delta from 0 or last amplitude if note is replayed 68 | } 69 | 70 | void replay(unsigned char v) 71 | { 72 | cli(); //can't interrupt while parameters are changing 73 | envelopeAmpA = envelopeAmp; //start from current amplitude to avoid clicks 74 | setEnvelope(v); //write new parameters 75 | sei(); 76 | } 77 | 78 | void on(unsigned char ch, unsigned char n, unsigned char v) 79 | { 80 | //set note parameters 81 | channel = ch; 82 | note = n; 83 | phase = 0; 84 | freqInc = pgm_read_dword(&freqIncTab[n]); 85 | freqInc <<= 2; //have to quadruple the increment because of the we went down to a qarter of the frequency 86 | envelopeAmpA = 0; //no playing atm start attack from 0 87 | setEnvelope(v); 88 | state = 0; //set statte to plaing 89 | } 90 | 91 | void off() 92 | { 93 | cli(); //not want to interrupt 94 | envelopeAmpR = envelopeAmp; //save release amplitude 95 | if(envelopeAmpR) 96 | envelopePhase = 0x3000000; //goto release 97 | else 98 | envelopePhase = 0x4000000; //no relase phase 99 | sei(); 100 | } 101 | 102 | char mix() 103 | { 104 | switch(cast_uf8p24_uf8p0(envelopePhase)) //upper 8bits of envelope pahse are taking to identify the phase 105 | { 106 | case 0: 107 | envelopeAmp = envelopeAmpA + mul_uf0p8_uf0p8_uf0p8(cast_uf8p24_uf0p8(envelopePhase), envelopeAmpDeltaA); //ramping up during Attack pahse to velocity amp 108 | envelopePhase += envelopePhaseIncA; //adding the increment. the higher the inc the shorter the attack period 109 | break; 110 | case 1: 111 | envelopeAmp = velocity - mul_uf0p8_uf0p8_uf0p8(cast_uf8p24_uf0p8(envelopePhase), envelopeAmpDeltaS); //ramping decay down to sustain level 112 | envelopePhase += envelopePhaseIncD; //same procedure her as in attack 113 | break; 114 | case 2: 115 | if(!envelopeAmpS) //if sustain level is zerowe are done here, go to end 116 | { 117 | envelopePhase = 0x4000000; 118 | return 0; 119 | } 120 | envelopeAmp = envelopeAmpS; //set the amplitude to calculated value othervise 121 | break; 122 | case 3: 123 | envelopeAmp = envelopeAmpR - mul_uf0p8_uf0p8_uf0p8(cast_uf8p24_uf0p8(envelopePhase), envelopeAmpR); //ramp down the last aplitude we saved to zero during the relese pahse 124 | envelopePhase += envelopePhaseIncR; //same as above 125 | break; 126 | case 4: 127 | state = -1; //done with the note, clear the states 128 | noteMap[channel][note] = -1; 129 | return 0; 130 | } 131 | f8p0 s = 0; 132 | s = wave[cast_uf8p24_uf8p0(phase)]; //read the waveform from the table taking the high 8 bits of the time phase 133 | s = mul_f8p0_uf0p8_f8p0(s, envelopeAmp); //mutliplying the wave by the amplutide calculated from the ADSR and velocity above 134 | phase += freqInc; //increment the pahase of the wave freqency 135 | return s; 136 | } 137 | }; 138 | 139 | Note notes[MAX_NOTES]; 140 | 141 | void noteOff(byte ch, byte n, byte v) 142 | { 143 | if(noteMap[ch][n] >= 0) 144 | notes[noteMap[ch][n]].off(); 145 | } 146 | 147 | void noteOn(byte ch, byte n, byte v) 148 | { 149 | if(!v) 150 | noteOff(ch, n, 0); 151 | else 152 | if(noteMap[ch][n] >= 0) 153 | notes[noteMap[ch][n]].replay(v); 154 | else 155 | for(char i = 0; i < MAX_NOTES; i++) 156 | if(notes[i].state == -1) 157 | { 158 | notes[i].on(ch, n, v); 159 | noteMap[ch][n] = i; 160 | return; 161 | } 162 | } 163 | 164 | //calculates the wave samples from the parameters 165 | void generateWave() 166 | { 167 | for(unsigned int i = 0; i < 256; i++) 168 | { 169 | unsigned char par = i >> 5; 170 | unsigned char phase = i & 31; 171 | short swave = (wavePar[par] << 1) + (((wavePar[(par + 1) & 7] - wavePar[par]) * phase) >> 4); //linear interpoaltion using some fixed point between this control point and the next 172 | wave[i] = swave - 128; //store a signed sample 173 | } 174 | } 175 | 176 | void control(byte ch, byte c, byte v) 177 | { 178 | //knob controls to change ADSR (map other controls if you have another device) 179 | if(c >= 102 && c <= 105) 180 | { 181 | adsr[ch][c - 102] = v; 182 | if(eeprom_is_ready()) //also store to EEPROM 183 | eeprom_write_byte((uint8_t*)(ch * 4 + c - 102), v); 184 | 185 | #ifdef GRAPHICS 186 | setAdsrLines(); //generate new lines 187 | #endif 188 | } 189 | 190 | //Slider controls fore wave shape (map other controls if you have another device) 191 | if(c >= 110 && c <= 117) 192 | { 193 | wavePar[c - 110] = v; 194 | if(eeprom_is_ready()) //also store to EEPROM 195 | eeprom_write_byte((uint8_t*)(16 + c - 110), v); 196 | generateWave(); //interpolate the new wave form 197 | #ifdef GRAPHICS 198 | setWaveLines(); //generate new lines 199 | #endif 200 | } 201 | } 202 | 203 | void setup() 204 | { 205 | TIMSK0 = 0; //disable arduino timers 206 | Serial1.begin(31250); 207 | //Serial.begin(115200); //for printing debug to PC 208 | 209 | DDRC = 255; 210 | 211 | #ifdef GRAPHICS 212 | setupGraphics(); 213 | #endif 214 | 215 | TCCR5A = 0; 216 | TCCR5B = (1 << WGM52) | (1 << CS50); //clear timer on compare (CTC), no prescaling, reset timer after cycles 217 | OCR5A = 16000000L / 11025; 218 | TIMSK5 = (1 << OCIE5A); //enable interrupt on 219 | 220 | for(char j = 0; j < 16; j++) 221 | { 222 | for(char i = 0; i < 127; i++) 223 | noteMap[j][i] = -1; 224 | //read ADSR prameters from the EEPROM 225 | for(char i = 0; i < 4; i++) 226 | adsr[j][i] = eeprom_read_byte((uint8_t*)(j * 4 + i)); 227 | } 228 | #ifdef GRAPHICS 229 | setAdsrLines(); //calc the ADSR lines 230 | #endif 231 | for(char i = 0; i < 8; i++) //read the wave form parameters from the EEPROM 232 | wavePar[i] = eeprom_read_byte((uint8_t*)(16 + i)); 233 | generateWave(); //interpolate the wave samples from the parameters 234 | #ifdef GRAPHICS 235 | setWaveLines(); //set the lines to draw from the wave parameters 236 | #endif 237 | } 238 | 239 | ISR(TIMER5_COMPA_vect) 240 | { 241 | short s = 0; 242 | for(unsigned char i = 0; i < MAX_NOTES; i++) 243 | if(notes[i].state >= 0) 244 | { 245 | s += notes[i].mix(); 246 | } 247 | 248 | PORTC = pgm_read_byte(&compressTab[s + 2048]); 249 | 250 | //this part draws the lines. each pixel at a time 251 | #ifdef GRAPHICS 252 | if(!lineStep() && lineCount) //draw pixel and check if more 253 | { 254 | //precalculate parameters of next line in row 255 | calcLine(lines[currentLine][0], lines[currentLine][1], lines[currentLine][2], lines[currentLine][3]); 256 | currentLine++; 257 | //al lines drwan start from the beginning 258 | if(currentLine == lineCount) 259 | currentLine = 0; 260 | } 261 | #endif 262 | } 263 | 264 | unsigned char count; 265 | unsigned char command[2]; 266 | void loop() 267 | { 268 | while(Serial1.available()) 269 | { 270 | unsigned char a = Serial1.read(); 271 | //Serial.println(a); 272 | if(a > 127) 273 | count = 0; 274 | else 275 | { 276 | if(count == 2) 277 | { 278 | if((command[0] & 0xf0) == 0x90) 279 | noteOn(command[0] & 0xf, command[1], a); 280 | if((command[0] & 0xf0) == 0x80) 281 | noteOff(command[0] & 0xf, command[1], a); 282 | if((command[0] & 0xf0) == 0xb0) //control change message 283 | control(command[0] & 0xf, command[1], a); 284 | } 285 | } 286 | if(count < 2) 287 | command[count] = a; 288 | count++; 289 | } 290 | } 291 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | "# arduinoMIDISynth" 2 | -------------------------------------------------------------------------------- /fixedPoint.h: -------------------------------------------------------------------------------- 1 | //LITTLE ENDIAN ONLY 2 | //gcc still isn't intelligent enoug to discard unsuded bytes after casts and multiplications. 3 | //what a bummer wasting majority of the cpu cycles 4 | 5 | typedef unsigned char uf0p8; 6 | 7 | typedef char f8p0; 8 | typedef unsigned char uf8p0; 9 | 10 | typedef short f16p0; 11 | typedef unsigned short uf16p0; 12 | 13 | typedef unsigned short uf0p16; 14 | 15 | typedef long f32p0; 16 | typedef unsigned long uf32p0; 17 | 18 | typedef long f8p24; 19 | typedef long f16p16; 20 | typedef long f24p8; 21 | 22 | typedef unsigned long uf8p24; 23 | typedef unsigned long uf16p16; 24 | typedef unsigned long uf24p8; 25 | 26 | typedef unsigned long f8p8; 27 | typedef unsigned long uf8p8; 28 | 29 | #define f8p24_1 0x1000000 30 | #define f16p16_1 0x10000 31 | #define uf8p24_1 0x1000000 32 | #define uf16p16_1 0x10000 33 | #define f8p8_1 0x100 34 | #define uf8p8_1 0x100 35 | 36 | inline f8p0 cast_f8p24_f8p0(f8p24 a) 37 | { 38 | return ((f8p0*)&a)[3]; 39 | } 40 | 41 | inline uf8p0 cast_uf8p24_uf8p0(uf8p24 a) 42 | { 43 | return ((uf8p0*)&a)[3]; 44 | } 45 | 46 | inline f8p0 cast_uf8p0_f8p0(uf8p0 a) 47 | { 48 | return (f8p0)a; 49 | } 50 | 51 | inline uf8p0 cast_f8p0_uf8p0(f8p0 a) 52 | { 53 | return (uf8p0)a; 54 | } 55 | 56 | inline f8p8 cast_f8p24_f8p8(f24p8 a) 57 | { 58 | f8p8 c; 59 | ((char*)&c)[0] = ((char*)&a)[2]; 60 | ((char*)&c)[1] = ((char*)&a)[3]; 61 | return c; 62 | } 63 | 64 | inline uf8p8 cast_uf8p24_uf8p8(uf24p8 a) 65 | { 66 | uf8p8 c; 67 | ((char*)&c)[0] = ((char*)&a)[2]; 68 | ((char*)&c)[1] = ((char*)&a)[3]; 69 | return c; 70 | } 71 | 72 | inline f8p8 cast_f16p16_f8p8(f16p16 a) 73 | { 74 | f8p8 c; 75 | ((char*)&c)[0] = ((char*)&a)[1]; 76 | ((char*)&c)[1] = ((char*)&a)[2]; 77 | return c; 78 | } 79 | 80 | inline f8p0 cast_f24p8_f8p0(f8p24 a) 81 | { 82 | return ((f8p0*)&a)[3]; 83 | } 84 | 85 | inline f8p0 cast_f16p16_f8p0(f16p16 a) 86 | { 87 | return ((f8p0*)&a)[2]; 88 | } 89 | 90 | inline f8p8 mul_f8p8_uf0p8_f8p8(f8p8 a, uf0p8 b) 91 | { 92 | f16p16 c = a * b; 93 | return cast_f16p16_f8p8(c); 94 | } 95 | 96 | inline f8p0 mul_f8p8_uf0p8_f8p0(f8p8 a, uf0p8 b) 97 | { 98 | f16p16 c = a * b; 99 | return cast_f16p16_f8p0(c); 100 | } 101 | 102 | inline f8p0 mul_f8p8_uf0p16_f8p0(f8p8 a, uf0p16 b) 103 | { 104 | f8p24 c = a * b; 105 | return cast_f8p24_f8p0(c); 106 | } 107 | 108 | inline uf0p8 cast_uf8p24_uf0p8(uf8p24 a) 109 | { 110 | return ((uf0p8*)&a)[2]; 111 | } 112 | 113 | inline uf0p16 cast_f8p24_uf0p16(f8p24 a) 114 | { 115 | uf0p16 c; 116 | ((char*)&c)[0] = ((char*)&a)[1]; 117 | ((char*)&c)[1] = ((char*)&a)[2]; 118 | return c; 119 | } 120 | 121 | inline uf0p16 cast_uf8p24_uf0p16(uf8p24 a) 122 | { 123 | uf0p16 c; 124 | ((char*)&c)[0] = ((char*)&a)[1]; 125 | ((char*)&c)[1] = ((char*)&a)[2]; 126 | return c; 127 | } 128 | 129 | inline f8p0 cast_f8p8_f8p0(f8p8 a) 130 | { 131 | return ((f8p0*)&a)[1]; 132 | } 133 | 134 | inline uf0p8 cast_uf0p16_uf0p8(f8p8 a) 135 | { 136 | return ((uf0p8*)&a)[1]; 137 | } 138 | 139 | inline f8p0 mul_f8p0_uf0p8_f8p0(f8p0 a, uf0p8 b) 140 | { 141 | f8p8 c = a * b; 142 | return cast_f8p8_f8p0(c); 143 | } 144 | 145 | inline uf0p8 cast_uf0p16_uf0p8(uf0p16 a) 146 | { 147 | return ((uf0p8*)&a)[1]; 148 | } 149 | 150 | inline uf0p16 mul_uf0p16_uf0p8_uf0p16(uf0p16 a, uf0p8 b) 151 | { 152 | uf0p16 c1 = ((uf8p0*)&a)[0] * b; 153 | uf0p16 c2 = ((uf8p0*)&a)[1] * b + ((uf8p0*)&c1)[1]; 154 | return c2; 155 | } 156 | 157 | inline f8p0 mul_uf0p8_uf0p8_uf0p8(uf0p8 a, uf0p8 b) 158 | { 159 | uf0p16 c = a * b; 160 | return cast_uf0p16_uf0p8(c); 161 | } 162 | -------------------------------------------------------------------------------- /osciGraphics.h: -------------------------------------------------------------------------------- 1 | char lineCount = 16; 2 | char currentLine = 0; 3 | char lines[16][4]; 4 | 5 | void setAdsrLines() 6 | { 7 | lines[2][0] = 0; 8 | lines[2][1] = adsr[0][2]; 9 | lines[2][2] = lines[2][0] + 64; 10 | lines[2][3] = lines[2][1]; 11 | 12 | lines[1][0] = lines[2][0]; 13 | lines[1][1] = lines[2][1]; 14 | lines[1][2] = lines[1][0] - (adsr[0][1] >> 1); 15 | lines[1][3] = 127; 16 | 17 | lines[0][0] = lines[1][2]; 18 | lines[0][1] = 127; 19 | lines[0][2] = lines[0][0] - (adsr[0][0] >> 1); 20 | lines[0][3] = 0; 21 | 22 | lines[3][0] = lines[2][2]; 23 | lines[3][1] = lines[2][3]; 24 | lines[3][2] = lines[3][0] + (adsr[0][3] >> 1); 25 | lines[3][3] = 0; 26 | 27 | lines[4][0] = lines[2][2]; 28 | lines[4][1] = lines[2][3]; 29 | lines[4][2] = lines[4][0]; 30 | lines[4][3] = 0; 31 | 32 | lines[5][0] = lines[1][0]; 33 | lines[5][1] = lines[1][1]; 34 | lines[5][2] = lines[5][0]; 35 | lines[5][3] = 0; 36 | 37 | lines[6][0] = lines[0][0]; 38 | lines[6][1] = lines[0][1]; 39 | lines[6][2] = lines[6][0]; 40 | lines[6][3] = 0; 41 | } 42 | 43 | void setWaveLines() 44 | { 45 | lines[7][0] = 127; 46 | lines[7][1] = -64; 47 | lines[7][2] = -128; 48 | lines[7][3] = -64; 49 | for(char i = 0; i < 8; i++) 50 | { 51 | lines[8 + i][0] = i * 32 - 128; 52 | lines[8 + i][1] = (wavePar[i] >> 1) - 96; 53 | lines[8 + i][2] = i * 32 - 128 + 31; 54 | lines[8 + i][3] = (wavePar[(i + 1) & 7] >> 1) - 96; 55 | } 56 | } 57 | 58 | void setupGraphics() 59 | { 60 | DDRK = 255; 61 | DDRA = 255; 62 | } 63 | 64 | short lineDx; 65 | short lineDy; 66 | short lineSx; 67 | short lineSy; 68 | short lineX0; 69 | short lineY0; 70 | short lineX1; 71 | short lineY1; 72 | short lineErr; 73 | 74 | void calcLine(char x0, char y0, char x1, char y1) 75 | { 76 | lineDx = abs((short)x1 - x0); 77 | lineDy = abs((short)y1 - y0); 78 | lineSx = x0 < x1 ? 1 : -1; 79 | lineSy = y0 < y1 ? 1 : -1; 80 | lineErr = lineDx - lineDy; 81 | 82 | lineX0 = x0; 83 | lineY0 = y0; 84 | lineX1 = x1; 85 | lineY1 = y1; 86 | } 87 | 88 | boolean lineStep() 89 | { 90 | if(lineX0 == lineX1 && lineY0 == lineY1) 91 | return false; 92 | if(lineX0 >= -128 && lineX0 <= 127 && lineY0 >= -128 && lineY0 <= 127) 93 | { 94 | PORTK = lineX0 - 128; 95 | PORTA = lineY0 - 128; 96 | } 97 | short e2 = lineErr << 1; 98 | if(e2 > -lineDy) 99 | { 100 | lineErr -= lineDy; 101 | lineX0 += lineSx; 102 | } 103 | if(e2 < lineDx) 104 | { 105 | lineErr += lineDx; 106 | lineY0 += lineSy; 107 | } 108 | return true; 109 | } 110 | 111 | --------------------------------------------------------------------------------