Advertisement
JNET

Arduino Beatbox Code V.2

Feb 16th, 2017
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.69 KB | None | 0 0
  1.  
  2. //
  3. // BeatBox -- Simple Arduino rhythm player
  4. //
  5.  
  6. // Author: P.J. Drongowski
  7. // Date: 15 July 2016
  8. // Copyright (c) 2016 Paul J. Drongowski
  9.  
  10. #include <avr/pgmspace.h>
  11. #include <avr/interrupt.h>
  12.  
  13. #include "waveforms.h"
  14. #include "kits.h"
  15. #include "patterns.h"
  16. #include "LedControl.h"
  17. #include "binary.h"
  18.  
  19. /*
  20. * Now we create a new LedControl.
  21. * We use pins 12,11 and 10 on the Arduino for the SPI interface
  22. * Pin 2 is connected to the DATA IN-pin of the first MAX7221
  23. * Pin 3 is connected to the CLK-pin of the first MAX7221
  24. * Pin 4 is connected to the LOAD(/CS)-pin of the first MAX7221
  25. * There will only be a single MAX7221 attached to the arduino
  26. */
  27. LedControl lc=LedControl(2,3,4,1);
  28.  
  29. byte b[8]= {B00111100,B00100100,B00100100,B00111000,B00111000,B00100100,B00100100,B00111100};
  30. byte e[8]= {B11111111,B11111111,B11000000,B11111100,B11111100,B11000000,B11111111,B11111111};
  31. byte a[8]= {B01111110,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010,B01000010};
  32. byte t[8]= {B11111111,B11111111,B00011000,B00011000,B00011000,B00011000,B00011000,B00011000};
  33.  
  34. // Define input pins
  35. int ResetButton = 0 ; // Unused (digital)
  36. int tempoInputPin = 0 ; // Set BPM (analog)
  37. int patternInputPin = 1 ; // Choose pattern and kit (analog)
  38.  
  39. // Define output pins
  40. int gatePin = 1 ; // Unused
  41. int blahPin = 5 ; // Unused
  42. int pwmPin = 9; // PWM (DAC) output
  43.  
  44. // Rhythm instrument control variables
  45. #define INSTRUMENTS 8
  46. const int8_t* sampleArrays[INSTRUMENTS] ;
  47. int16_t sampleSizes[INSTRUMENTS] ;
  48. int sampleCounts[INSTRUMENTS] ;
  49. int sampleIndices[INSTRUMENTS] ;
  50.  
  51. // Tempo control variables
  52. int tempo = 120 ;
  53. int delayValue = 125 ;
  54.  
  55. // Pattern and pattern control variables
  56. int patternId = 0 ;
  57. int kitId = 0 ;
  58. int patternLength = 16 ;
  59. int patternIndex = 0 ;
  60. uint8_t pattern[64] ;
  61.  
  62. //
  63. // TIMER1 PWM. Single PWM, phase correct, 22050KHz.
  64. // PWM_FREQ = 16,000,000 / 22,050 = 726 = 0x2D5
  65. // PWM_FREQ = 16,000,000 / 11,025 = 1451 = 0x5AB
  66. //
  67. #define PWM_FREQ 363
  68.  
  69. void PwmSetup() {
  70. // Clear OC1 on compare match, 8-bit PWM
  71. //TCCR1A = _BV(COM1A1) | _BV(WGM10) ;
  72. TCCR1A = _BV(COM1A1) ;
  73. // PWM TOP is OCR1A, No prescaler
  74. TCCR1B = _BV(WGM13) | _BV(CS10) ;
  75. // Generate interrupt on input capture
  76. TIMSK1 = _BV(ICIE1) ;
  77. // Set input capture register to sampling frequency
  78. ICR1H = (PWM_FREQ >> 8) ;
  79. ICR1L = (PWM_FREQ & 0xff) ;
  80. // Turn on the output pin D9
  81. DDRB |= _BV(5) ;
  82. sei() ;
  83. }
  84.  
  85. void DisableInterrupts() {
  86. cli() ;
  87. TIMSK1 &= ~_BV(OCIE1A) ; // Disable DAC interrupts
  88. sei() ;
  89. }
  90.  
  91. void EnableInterrupts() {
  92. cli();
  93. TIMSK1 |= _BV(OCIE1A) ; // Enable DAC interrupts
  94. sei();
  95. }
  96.  
  97. //
  98. // Interrupt service routine (ISR)
  99. //
  100. ISR(TIMER1_CAPT_vect) {
  101. register int16_t dacValue = 0 ;
  102. register int16_t sample = 0 ;
  103. if (sampleCounts[0] > 0) {
  104. sample = (int8_t)pgm_read_byte_near(
  105. sampleArrays[0]+sampleIndices[0]) ;
  106. dacValue += sample ;
  107. sampleIndices[0]++ ;
  108. sampleCounts[0]-- ;
  109. }
  110. if (sampleCounts[1] > 0) {
  111. sample = (int8_t)pgm_read_byte_near(
  112. sampleArrays[1]+sampleIndices[1]) ;
  113. dacValue += sample ;
  114. sampleIndices[1]++ ;
  115. sampleCounts[1]-- ;
  116. }
  117. if (sampleCounts[2] > 0) {
  118. sample = (int8_t)pgm_read_byte_near(
  119. sampleArrays[2]+sampleIndices[2]) ;
  120. dacValue += sample ;
  121. sampleIndices[2]++ ;
  122. sampleCounts[2]-- ;
  123. }
  124. if (sampleCounts[3] > 0) {
  125. sample = (int8_t)pgm_read_byte_near(
  126. sampleArrays[3]+sampleIndices[3]) ;
  127. dacValue += sample ;
  128. sampleIndices[3]++ ;
  129. sampleCounts[3]-- ;
  130. }
  131. if (sampleCounts[4] > 0) {
  132. sample = (int8_t)pgm_read_byte_near(
  133. sampleArrays[4]+sampleIndices[4]) ;
  134. dacValue += sample ;
  135. sampleIndices[4]++ ;
  136. sampleCounts[4]-- ;
  137. }
  138. if (sampleCounts[5] > 0) {
  139. sample = (int8_t)pgm_read_byte_near(
  140. sampleArrays[5]+sampleIndices[5]) ;
  141. dacValue += sample ;
  142. sampleIndices[5]++ ;
  143. sampleCounts[5]-- ;
  144. }
  145. if (sampleCounts[6] > 0) {
  146. sample = (int8_t)pgm_read_byte_near(
  147. sampleArrays[6]+sampleIndices[6]) ;
  148. dacValue += sample ;
  149. sampleIndices[6]++ ;
  150. sampleCounts[6]-- ;
  151. }
  152. if (sampleCounts[7] > 0) {
  153. sample = (int8_t)pgm_read_byte_near(
  154. sampleArrays[7]+sampleIndices[7]) ;
  155. dacValue += sample ;
  156. sampleIndices[7]++ ;
  157. sampleCounts[7]-- ;
  158. }
  159.  
  160. // Output through OC1A
  161. dacValue += 127 ;
  162. OCR1AH = (uint8_t) (dacValue >> 8) & 0xFF ;
  163. OCR1AL = (uint8_t) dacValue & 0xFF ;
  164. //Serial.println(dacValue);
  165. }
  166.  
  167. #define SHKIT 0
  168. #define CTKIT 1
  169. #define ADKIT 2
  170. #define VRKIT 3
  171.  
  172. void loadKit(int kitId) {
  173. register int i ;
  174. register int8_t** samples ;
  175. register int16_t** sizes ;
  176.  
  177. switch(kitId) {
  178. case SHKIT:
  179. default: {
  180. // SH kit
  181. samples = (int8_t**)shWaveforms ;
  182. sizes = (int16_t**)shWaveformSizes ;
  183. break ;
  184. }
  185. case CTKIT: {
  186. // CT kit
  187. samples = (int8_t**)ctWaveforms ;
  188. sizes = (int16_t**)ctWaveformSizes ;
  189. break ;
  190. }
  191. case ADKIT: {
  192. // AD kit
  193. samples = (int8_t**)adWaveforms ;
  194. sizes = (int16_t**)adWaveformSizes ;
  195. break ;
  196. }
  197. case VRKIT: {
  198. // VR kit
  199. samples = (int8_t**)vrWaveforms ;
  200. sizes = (int16_t**)vrWaveformSizes ;
  201. break ;
  202. }
  203. }
  204. for (i = 0 ; i < 8 ; i++) {
  205. sampleArrays[i] = (int8_t*)pgm_read_word_near(samples+i) ;
  206. sampleSizes[i] = (int16_t)pgm_read_word_near(sizes+i) ;
  207. }
  208. }
  209.  
  210. void changePatternAndKit(int patternInput) {
  211. register int i ;
  212. register int kit ;
  213. register uint8_t* newpattern ;
  214.  
  215. if (patternInput < 6) {
  216. // healingA pattern
  217. patternLength = HEALINGASIZE ;
  218. newpattern = (uint8_t*)healingA ;
  219. kit = SHKIT ;
  220. } else if (patternInput < 12) {
  221. // cybotranA pattern
  222. patternLength = CYBOTRONASIZE ;
  223. newpattern = (uint8_t*)cybotronA ;
  224. kit = CTKIT ;
  225. } else if (patternInput < 18) {
  226. // planetA pattern
  227. patternLength = PLANETASIZE ;
  228. newpattern = (uint8_t*)planetA ;
  229. kit = CTKIT ;
  230. } else if (patternInput < 24) {
  231. // adonisA pattern
  232. patternLength = ADONISASIZE ;
  233. newpattern = (uint8_t*)adonisA ;
  234. kit = ADKIT ;
  235. } else {
  236. // voodoo pattern
  237. patternLength = VOODOOSIZE ;
  238. newpattern = (uint8_t*)voodoo ;
  239. kit = VRKIT ;
  240. }
  241. loadKit(kit) ;
  242. if (patternLength > 64) patternLength = 64 ;
  243. for (i = 0 ; i < patternLength ; i++) {
  244. pattern[i] = (uint8_t)pgm_read_byte_near(newpattern+i) ;
  245. }
  246. }
  247.  
  248. void setup() {
  249. lc.shutdown(0,false);
  250. // Set brightness to a medium value
  251. lc.setIntensity(0,8);
  252. // Clear the display
  253. lc.clearDisplay(0);
  254. register int i ;
  255. // Initialize the serial port (only for debugging)
  256. Serial.begin(9600) ;
  257. // Set up pin modes
  258. pinMode(ResetButton, INPUT_PULLUP) ;
  259. //pinMode(gatePin, OUTPUT) ;
  260. // Initialize pin values
  261. //digitalWrite(gatePin, LOW) ;
  262. pinMode(pwmPin,OUTPUT);
  263.  
  264. changePatternAndKit(analogRead(patternInputPin) >> 5) ;
  265.  
  266. tempo = 120 ;
  267. delayValue = (60000 / tempo) / 4 ;
  268.  
  269. patternIndex = 0 ;
  270. for (i = 0 ; i < INSTRUMENTS ; i++) sampleCounts[i] = 0 ;
  271.  
  272. PwmSetup() ;
  273. }
  274.  
  275.  
  276. void beat(int count)
  277. {
  278. if (count == 0) {
  279. lc.setRow(0,0,b[0]);
  280. lc.setRow(0,1,b[1]);
  281. lc.setRow(0,2,b[2]);
  282. lc.setRow(0,3,b[3]);
  283. lc.setRow(0,4,b[4]);
  284. lc.setRow(0,5,b[5]);
  285. lc.setRow(0,6,b[6]);
  286. lc.setRow(0,7,b[7]);
  287. }
  288. if (count == 1) {
  289. lc.setRow(0,0,e[0]);
  290. lc.setRow(0,1,e[1]);
  291. lc.setRow(0,2,e[2]);
  292. lc.setRow(0,3,e[3]);
  293. lc.setRow(0,4,e[4]);
  294. lc.setRow(0,5,e[5]);
  295. lc.setRow(0,6,e[6]);
  296. lc.setRow(0,7,e[7]);
  297. }
  298. if (count == 2) {
  299. lc.setRow(0,0,a[0]);
  300. lc.setRow(0,1,a[1]);
  301. lc.setRow(0,2,a[2]);
  302. lc.setRow(0,3,a[3]);
  303. lc.setRow(0,4,a[4]);
  304. lc.setRow(0,5,a[5]);
  305. lc.setRow(0,6,a[6]);
  306. lc.setRow(0,7,a[7]);
  307. }
  308.  
  309. if (count == 3) {
  310. lc.setRow(0,0,t[0]);
  311. lc.setRow(0,1,t[1]);
  312. lc.setRow(0,2,t[2]);
  313. lc.setRow(0,3,t[3]);
  314. lc.setRow(0,4,t[4]);
  315. lc.setRow(0,5,t[5]);
  316. lc.setRow(0,6,t[6]);
  317. lc.setRow(0,7,t[7]);
  318. }
  319. }
  320.  
  321. void loop() {
  322.  
  323. register uint8_t pbits ;
  324. register int difference ;
  325. static int oldTempoInput = 0 ;
  326. static int tempoInput = 0 ;
  327. static int oldPatternInput = 0 ;
  328. static int patternInput = 0 ;
  329. static int bpmCount = 3 ;
  330.  
  331. // Turn TXLED on during the first eighth note of every beat
  332. //if (bpmCount & 0x0002) {
  333. // TXLED1;
  334. //} else {
  335. // TXLED0 ;
  336. //}
  337. //Serial.println(bpmCount);
  338. if (bpmCount == 0)
  339. bpmCount = 3; else bpmCount-- ;
  340.  
  341. beat(bpmCount);
  342. // Change tempo if necessary
  343. // Dimmer connected to pin A0 sweeps tempo from 60 to 188 BPM
  344. tempoInput = analogRead(tempoInputPin) >> 3 ;
  345. difference = abs(tempoInput - oldTempoInput) ;
  346. if (difference > 0) {
  347. // Change the tempo
  348. tempo = 60 + tempoInput ;
  349. delayValue = (60000 / tempo) / 4 ;
  350. oldTempoInput = tempoInput ;
  351. }
  352.  
  353. // Change pattern/kit if necessary
  354. // Dimmer connected to pin A1 selects one of 5 patterns
  355. patternInput = analogRead(patternInputPin) >> 5 ;
  356. difference = abs(patternInput - oldPatternInput) ;
  357. if (difference > 0) {
  358. // Change the pattern and its associated kit
  359. changePatternAndKit(patternInput) ;
  360. oldPatternInput = patternInput ;
  361. //add the symbol for change of kit based on patternInput
  362. }
  363.  
  364. // Delay for the equivalent of one sixteenth note
  365. delay(delayValue) ;
  366.  
  367. // Wrap around the pattern index if necessary and
  368. // get the bit pattern for the current step
  369. if (patternIndex >= patternLength) patternIndex = 0 ;
  370. pbits = pattern[patternIndex] ;
  371.  
  372. for (int i = 0 ; i < 8 ; i++) {
  373. if (pbits & 0x01) {
  374. sampleCounts[i] = sampleSizes[i] ;
  375. sampleIndices[i] = 0 ;
  376. }
  377. pbits = pbits >> 1 ;
  378. }
  379.  
  380. patternIndex++ ;
  381. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement