awesome
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sketch_zx.ino 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. "Tri-Shape", a wave shaping oscilatorfor Ginkosynthese's "grains" module.
  3. By Kassen Oud
  4. LICENSE:
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. DESCRIPION;
  16. A triangle-based osclitator with wave-folding and hard-clipping features.
  17. MANUAL;
  18. Knob 1 / mod 1; Wave folding
  19. Amplifies the base triangle wave, then once it hits the limits of the
  20. range "folds" it back in the opposite direction. With enough
  21. amplification this will happen again at the other side, creating a
  22. rich spectrum.
  23. Knob 2/ mod 2; Hard Cliping
  24. Amplifies the signal (after the folding) and clips the result. This is
  25. done asymetrically for a "deeper" and more "balsy" sound. Thanks to
  26. Rob Bothof for that trick.
  27. Knob 3: Base Tuning.
  28. Sets the base pitch.
  29. Mod 3; Pitch Modulation
  30. This CV gets added to the value set by Knob 3.
  31. */
  32. //the libraries we use
  33. #include <avr/io.h>
  34. #include <avr/interrupt.h>
  35. #include <avr/pgmspace.h>
  36. //variables
  37. uint16_t phase_accumulator; //keeps track of the phase
  38. uint16_t phase_inc; //phase increase per sample
  39. bool flip = false; //keeps track of the output's polarity
  40. uint16_t wrap = 1; // amount of wave-folding
  41. uint16_t drive = 32; //amount of clipping for positive signal
  42. uint16_t top_drive = 32; //same for negative signal
  43. uint16_t output = 127; //the value we write out
  44. uint16_t last_out = 127; //last value we wrote out
  45. // Map inputs
  46. #define DRIVE_CONTROL (A1)
  47. #define WRAP_CONTROL (A2)
  48. #define PITCH_KNOB (A0)
  49. #define PITCH_CV (A3)
  50. // Changing these will also requires rewriting setup()
  51. // Output is on pin 11
  52. #define PWM_PIN 11
  53. #define PWM_VALUE OCR2A
  54. #define LED_PORT PORTB
  55. #define LED_BIT 5
  56. #define PWM_INTERRUPT TIMER2_OVF_vect
  57. //maps cv to samples of phase increase each time we output a new value
  58. //this might need tuning in the future
  59. const uint16_t freqTable[] PROGMEM = {
  60. 69, 69, 69, 69, 70, 70, 70, 70, 70, 71, // 0 to 9
  61. 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, //
  62. 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, //
  63. 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, //
  64. 78, 79, 79, 79, 79, 80, 80, 80, 81, 81, //
  65. 81, 81, 82, 82, 82, 82, 83, 83, 83, 84, //
  66. 84, 84, 84, 85, 85, 85, 86, 86, 86, 86, //
  67. 87, 87, 87, 88, 88, 88, 88, 89, 89, 89, //
  68. 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, //
  69. 93, 93, 93, 94, 94, 94, 95, 95, 95, 96, //
  70. 96, 96, 97, 97, 97, 97, 98, 98, 98, 99, // 100 to 109
  71. 99, 99, 100, 100, 100, 101, 101, 101, 102, 102, //
  72. 102, 103, 103, 104, 104, 104, 105, 105, 105, 106, //
  73. 106, 106, 107, 107, 107, 108, 108, 109, 109, 109, //
  74. 110, 110, 110, 111, 111, 111, 112, 112, 113, 113, //
  75. 113, 114, 114, 114, 115, 115, 116, 116, 116, 117, //
  76. 117, 118, 118, 118, 119, 119, 120, 120, 120, 121, //
  77. 121, 122, 122, 122, 123, 123, 124, 124, 124, 125, //
  78. 125, 126, 126, 127, 127, 127, 128, 128, 129, 129, //
  79. 130, 130, 130, 131, 131, 132, 132, 133, 133, 134, //
  80. 134, 134, 135, 135, 136, 136, 137, 137, 138, 138, // 200 to 209
  81. 139, 139, 139, 140, 140, 141, 141, 142, 142, 143, //
  82. 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, //
  83. 148, 149, 149, 150, 150, 151, 151, 152, 152, 153, //
  84. 153, 154, 154, 155, 155, 156, 156, 157, 157, 158, //
  85. 158, 159, 159, 160, 161, 161, 162, 162, 163, 163, //
  86. 164, 164, 165, 165, 166, 167, 167, 168, 168, 169, //
  87. 169, 170, 171, 171, 172, 172, 173, 173, 174, 175, //
  88. 175, 176, 176, 177, 178, 178, 179, 179, 180, 181, //
  89. 181, 182, 182, 183, 184, 184, 185, 185, 186, 187, //
  90. 187, 188, 189, 189, 190, 190, 191, 192, 192, 193, // 300 to 309
  91. 194, 194, 195, 196, 196, 197, 198, 198, 199, 200, //
  92. 200, 201, 202, 202, 203, 204, 204, 205, 206, 206, //
  93. 207, 208, 208, 209, 210, 211, 211, 212, 213, 213, //
  94. 214, 215, 216, 216, 217, 218, 218, 219, 220, 221, //
  95. 221, 222, 223, 224, 224, 225, 226, 227, 227, 228, //
  96. 229, 230, 231, 231, 232, 233, 234, 234, 235, 236, //
  97. 237, 238, 238, 239, 240, 241, 242, 242, 243, 244, //
  98. 245, 246, 246, 247, 248, 249, 250, 251, 251, 252, //
  99. 253, 254, 255, 256, 257, 257, 258, 259, 260, 261, //
  100. 262, 263, 264, 264, 265, 266, 267, 268, 269, 270, // 400 to 409
  101. 271, 272, 273, 273, 274, 275, 276, 277, 278, 279, //
  102. 280, 281, 282, 283, 284, 285, 286, 287, 288, 288, //
  103. 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, //
  104. 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, //
  105. 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, //
  106. 320, 321, 322, 323, 324, 325, 327, 328, 329, 330, //
  107. 331, 332, 333, 334, 335, 337, 338, 339, 340, 341, //
  108. 342, 343, 345, 346, 347, 348, 349, 350, 352, 353, //
  109. 354, 355, 356, 357, 359, 360, 361, 362, 363, 365, //
  110. 366, 367, 368, 370, 371, 372, 373, 375, 376, 377, // 500 to 509
  111. 378, 380, 381, 382, 383, 385, 386, 387, 389, 390, //
  112. 391, 393, 394, 395, 397, 398, 399, 401, 402, 403, //
  113. 405, 406, 407, 409, 410, 411, 413, 414, 416, 417, //
  114. 418, 420, 421, 423, 424, 425, 427, 428, 430, 431, //
  115. 433, 434, 436, 437, 438, 440, 441, 443, 444, 446, //
  116. 447, 449, 450, 452, 453, 455, 456, 458, 460, 461, //
  117. 463, 464, 466, 467, 469, 470, 472, 474, 475, 477, //
  118. 478, 480, 482, 483, 485, 486, 488, 490, 491, 493, //
  119. 495, 496, 498, 500, 501, 503, 505, 506, 508, 510, //
  120. 511, 513, 515, 517, 518, 520, 522, 524, 525, 527, // 600 to 609
  121. 529, 531, 532, 534, 536, 538, 540, 541, 543, 545, //
  122. 547, 549, 551, 552, 554, 556, 558, 560, 562, 564, //
  123. 566, 567, 569, 571, 573, 575, 577, 579, 581, 583, //
  124. 585, 587, 589, 591, 593, 595, 597, 599, 601, 603, //
  125. 605, 607, 609, 611, 613, 615, 617, 619, 621, 623, //
  126. 625, 627, 630, 632, 634, 636, 638, 640, 642, 644, //
  127. 647, 649, 651, 653, 655, 658, 660, 662, 664, 666, //
  128. 669, 671, 673, 675, 678, 680, 682, 685, 687, 689, //
  129. 691, 694, 696, 698, 701, 703, 705, 708, 710, 713, //
  130. 715, 717, 720, 722, 725, 727, 729, 732, 734, 737, // 700 to 709
  131. 739, 742, 744, 747, 749, 752, 754, 757, 759, 762, //
  132. 764, 767, 770, 772, 775, 777, 780, 783, 785, 788, //
  133. 791, 793, 796, 799, 801, 804, 807, 809, 812, 815, //
  134. 817, 820, 823, 826, 828, 831, 834, 837, 840, 842, //
  135. 845, 848, 851, 854, 857, 860, 862, 865, 868, 871, //
  136. 874, 877, 880, 883, 886, 889, 892, 895, 898, 901, //
  137. 904, 907, 910, 913, 916, 919, 922, 925, 928, 932, //
  138. 935, 938, 941, 944, 947, 950, 954, 957, 960, 963, //
  139. 966, 970, 973, 976, 979, 983, 986, 989, 993, 996, //
  140. 999,1003,1006,1009,1013,1016,1020,1023,1027,1030, // 800 to 809
  141. 1033,1037,1040,1044,1047,1051,1054,1058,1061,1065, //
  142. 1069,1072,1076,1079,1083,1087,1090,1094,1098,1101, //
  143. 1105,1109,1112,1116,1120,1124,1127,1131,1135,1139, //
  144. 1143,1146,1150,1154,1158,1162,1166,1170,1174,1178, //
  145. 1182,1186,1189,1193,1197,1201,1206,1210,1214,1218, //
  146. 1222,1226,1230,1234,1238,1242,1247,1251,1255,1259, //
  147. 1263,1268,1272,1276,1280,1285,1289,1293,1298,1302, //
  148. 1306,1311,1315,1320,1324,1328,1333,1337,1342,1346, //
  149. 1351,1355,1360,1365,1369,1374,1378,1383,1388,1392, //
  150. 1397,1402,1406,1411,1416,1421,1425,1430,1435,1440, // 900 to 909
  151. 1444,1449,1454,1459,1464,1469,1474,1479,1484,1489, //
  152. 1494,1499,1504,1509,1514,1519,1524,1529,1534,1539, //
  153. 1545,1550,1555,1560,1565,1571,1576,1581,1587,1592, //
  154. 1597,1603,1608,1613,1619,1624,1630,1635,1641,1646, //
  155. 1652,1657,1663,1668,1674,1679,1685,1691,1696,1702, //
  156. 1708,1714,1719,1725,1731,1737,1742,1748,1754,1760, //
  157. 1766,1772,1778,1784,1790,1796,1802,1808,1814,1820, //
  158. 1826,1832,1838,1845,1851,1857,1863,1869,1876,1882, //
  159. 1888,1895,1901,1907,1914,1920,1927,1933,1940,1946, //
  160. 1953,1959,1966,1972,1979,1986,1992,1999,2006,2012, // 1000 to 1009
  161. 2019,2026,2033,2040,2046,2053,2060,2067,2074,2081, // 1010 to 1019
  162. 2088,2095,2102,2109 , // 1020 to 1023
  163. };
  164. uint16_t mapFreq(uint16_t input)
  165. {
  166. return pgm_read_word_near(freqTable + input);
  167. }
  168. //sets up pins and configures the samplerate and frequency of the PWM output
  169. void setup()
  170. {
  171. TCCR2A = _BV(COM2A1) | _BV(WGM20);
  172. TCCR2B = _BV(CS20);
  173. TIMSK2 = _BV(TOIE2);
  174. pinMode(PWM_PIN,OUTPUT);
  175. PWM_VALUE = 127;
  176. }
  177. //reads modulation inputs
  178. void loop()
  179. {
  180. //calculate the pitch
  181. int pwmv = min( 1023, analogRead(PITCH_CV) + analogRead(PITCH_KNOB));
  182. //look up the phase increase per sample
  183. phase_inc = mapFreq(pwmv);
  184. //read the control for wave-folding
  185. wrap = min( 64 + (analogRead(WRAP_CONTROL) >> 1), 511);
  186. //read the control for clipping and calculate the two amounts of overdrive
  187. drive = min( 32 + (analogRead(DRIVE_CONTROL) >> 1), 511);
  188. top_drive = max( 32, drive >>1);
  189. }
  190. //Actual sound generation happens here.
  191. //This involves rather a lot of bitwise operations, if you're looking to get
  192. //into writing code for the Grains I'd suggest not starting here; "PWM-Saw" is
  193. //far more "friendly". That's a nice way of saying "Here be Dragons".
  194. //I'm writing numbers out as literal trains of 0's and 1's because we make fair
  195. //ampount of use of those. Also note that a lot of the structure for this is
  196. //caused by avoiding signed integers, while we do want a symetrical signal.
  197. //Hence; we treat it as a unipolar signal, keep track of the polarity it should
  198. //be and apply that at the end.
  199. //I drew the process out on graph paper using multicoloured fineliner.
  200. //If you're serious about following all of this that might help.
  201. SIGNAL(PWM_INTERRUPT)
  202. {
  203. //increase the phase
  204. phase_accumulator += phase_inc;
  205. //2nd half of the phase will be the negative part of the cycle
  206. flip = phase_accumulator & 0b1000000000000000;
  207. //turn the phase acumulator into 4 up-ramps
  208. output = (phase_accumulator & 0b0011111111111111);
  209. //get these into 7 bit range. "flip" will be the 8th bit of the output
  210. output = output >> 7;
  211. //invert the 2nd and 4th of our 4 up-ramps to create our triangle wave
  212. if (phase_accumulator & 0b0100000000000000) output = (uint16_t)127 - output;
  213. //amplify the signal for the wave-wrapping
  214. output *= wrap;
  215. output = output >> 6;
  216. //detect whether folding will be more involved than inverting the range
  217. //from 128 to 254
  218. if (output & 0b1111111100000000)
  219. {
  220. //values between 255 and 511 fold back past the "0" line
  221. if (output & 0b0000000100000000) flip = !flip;
  222. //mask out bits beyond which the process just repeats
  223. output &= 0b0000000011111111;
  224. }
  225. //actual folding
  226. if (output > (uint16_t)127)
  227. {
  228. output = 127 - (output & 0b0000000001111111);
  229. }
  230. //apply the signal gain for asymetrical clipping
  231. output *= flip?drive:top_drive;
  232. output = output >> 5;
  233. //clip
  234. if (output > (uint16_t)127) output = (uint16_t)127;
  235. //turn our 7bit unipolar value into a 8bit bipolar one
  236. if ( flip ) output = (uint16_t)127 - output;
  237. else output += (uint16_t)127;
  238. //slight amount of smoothing
  239. output = (output + last_out) >> 1;
  240. last_out = output;
  241. //write out the output
  242. PWM_VALUE = output;
  243. }