Advertisement
JNET

Arduino Beatbox Main Code

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