Advertisement
Guest User

Generative Music for Arduino

a guest
Mar 31st, 2020
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.07 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <Wire.h>
  3. #include <Adafruit_GFX.h>
  4. #include <Adafruit_SSD1306.h>
  5. #include <PCM.h>
  6.  
  7. #define str(s) #s
  8. #define xstr(s) str(s)
  9.  
  10. //Music
  11. #define SAMPLE_RATE 8000
  12. #define NUMBER_OF_ALGORITHMS 22
  13. #define ALGO_01 t*((t>>12|t>>8)&63&t>>4)
  14. #define ALGO_02 (t*(t>>5|t>>8))>>(t>>16)
  15. #define ALGO_03 t*((t>>9|t>>13)&25&t>>6)
  16. #define ALGO_04 t*(t>>11&t>>8&123&t>>3)
  17. #define ALGO_05 t*(t>>8*(t>>15|t>>8)&(20|(t>>19)*5>>t|t>>3))
  18. #define ALGO_06 (int)(t/17*t*t+t)%127|t>>4|t>>5|t%127+(t>>16)|t
  19. #define ALGO_07 (t>>6|t|t>>(t>>16))*10+((t>>11)&7)
  20. #define ALGO_08 (t|(t>>9|t>>7))*t&(t>>11|t>>9)
  21. #define ALGO_09 t*5&(t>>7)|t*3&(t*4>>10)
  22. #define ALGO_10 (t>>7|t|t>>6)*10+4*(t&t>>13|t>>6)
  23. #define ALGO_11 ((t&4096)?((t*(t^t%255)|(t>>4))>>1):(t>>3)|((t&8192)?t<<2:t))
  24. #define ALGO_12 ((t*(t>>8|t>>9)&46&t>>8))^(t&t>>13|t>>6)
  25. #define ALGO_13 (t*5&t>>7)|(t*3&t>>10)
  26. #define ALGO_14 (int)(t/1e7*t*t+t)%127|t>>4|t>>5|t%127+(t>>16)|t
  27. #define ALGO_15 ((t/2*(15&(0x234568a0>>(t>>8&28))))|t/2>>(t>>11)^t>>12)+(t/16&t&24)
  28. #define ALGO_16 (t&t%255)-(t*3&t>>13&t>>6)
  29. #define ALGO_17 t>>4|t&(t>>5)/((t>>7-(t>>15)&-t>>7-(t>>15))!=0?(t>>7-(t>>15)&-t>>7-(t>>15)):1)
  30. #define ALGO_18 ((t*("36364689"[t>>13&7]&15))/12&128)+(((((t>>12)^(t>>12)-2)%11*t)/4|t>>13)&127)
  31. #define ALGO_19 (t*9&t>>4|t*5&t>>7|t*3&t/1024)-1
  32. #define ALGO_20 ((t*(t>>12)&(201*t/100)&(199*t/100))&(t*(t>>14)&(t*301/100)&(t*399/100)))+((t*(t>>16)&(t*202/100)&(t*198/100))-(t*(t>>17)&(t*302/100)&(t*298/100)))
  33. #define ALGO_21 t*(t^t+(t>>15|1)^(t-1280^t)>>10)
  34. //ALGO_22
  35.  
  36. //Set pin numbers
  37. const short speakerPin = 11;
  38. const short buttonPin = 1;
  39. const short encoderPinA = 2;
  40. const short encoderPinB = 3;
  41.  
  42. //Display settings
  43. #define OLED_RESET 4
  44. Adafruit_SSD1306 display(OLED_RESET);
  45. bool drawn = false;
  46. bool drawing = false;
  47.  
  48. //Encoder
  49. volatile unsigned int encoderPos = 0;
  50. unsigned int lastReportedPos = 1;
  51. static boolean rotating = false;
  52. bool aSet = false;
  53. bool bSet = false;
  54. bool pressed = false;
  55. int select = 1;
  56.  
  57. //Math
  58. short count = 0;
  59. unsigned long t = 0;
  60. int num = 4;
  61. uint8_t array[128];
  62.  
  63. void checkEncoder()
  64. {
  65.   rotating = true;  //reset debouncer
  66.  
  67.   if(lastReportedPos != encoderPos)
  68.   {
  69.     lastReportedPos = encoderPos;
  70.     //tone(speakerPin, 100, 25);
  71.   }
  72.  
  73.   if(digitalRead(buttonPin) == LOW)
  74.   {
  75.     pressed = true;
  76.     delay(500);
  77.   }
  78. }
  79.  
  80. void doEncoderA()
  81. {
  82.  
  83.   //debounce
  84.   if(rotating) delay(1);
  85.  
  86.   //test transition
  87.   if(digitalRead(encoderPinA) != aSet)
  88.   {
  89.     aSet = !aSet;
  90.  
  91.     if(aSet && !bSet)
  92.     {
  93.       encoderPos ++;
  94.       if(select<NUMBER_OF_ALGORITHMS)
  95.       {
  96.         select++;
  97.         t = 0;
  98.         drawn = false;
  99.       }
  100.     }
  101.  
  102.     rotating = false; //no more debouncing until loop repeats
  103.   }
  104. }
  105.  
  106. void doEncoderB()
  107. {
  108.  
  109.   if(rotating)
  110.     delay(1);
  111.   if(digitalRead(encoderPinB) != bSet)
  112.   {
  113.     bSet = !bSet;
  114.  
  115.     if(bSet && !aSet)
  116.     {
  117.       encoderPos--;
  118.       if(select>1)
  119.       {
  120.         select--;
  121.         t = 0;
  122.         drawn = false;
  123.       }
  124.     }
  125.  
  126.     rotating = false;
  127.   }
  128. }
  129.  
  130. void setup()
  131. {
  132.  
  133.   //Serial communication
  134.   //Serial.begin(9600);
  135.   SPI.setClockDivider(SPI_CLOCK_DIV2);
  136.  
  137.   //Display
  138.   display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  //Initialize with I2C addr 0x3C
  139.   display.clearDisplay();
  140.   display.display();
  141.  
  142.   //Set pin modes
  143.   pinMode(LED_BUILTIN, OUTPUT);
  144.   pinMode(speakerPin, OUTPUT);
  145.   pinMode(buttonPin, INPUT_PULLUP);
  146.   pinMode(encoderPinA, INPUT_PULLUP);
  147.   pinMode(encoderPinB, INPUT_PULLUP);
  148.  
  149.   //encoder interrupts
  150.   attachInterrupt(digitalPinToInterrupt(2), doEncoderA, CHANGE);
  151.   attachInterrupt(digitalPinToInterrupt(3), doEncoderB, CHANGE);
  152.  
  153.   //Sound setup
  154.   soundSetup();
  155.  
  156. }
  157.  
  158. void loop()
  159. {  
  160.   checkEncoder();
  161.  
  162.   if(!drawn)
  163.   {
  164.     display.clearDisplay();
  165.     showAlgorithm();
  166.     display.display();
  167.     drawn = true;
  168.   }
  169.  
  170.   if(count == 128)
  171.   {    
  172.     drawing = true;
  173.     //Serial.print("Drew dot ");
  174.     //Serial.println(t);
  175.     display.fillRect(0,16,128,48,0);
  176.     drawDot();
  177.     count = 0;
  178.     display.display();
  179.     drawing = false;
  180.   }
  181.  
  182.   /*if(pressed)
  183.   {
  184.     drawDisplay = !drawDisplay;
  185.     pressed = false;
  186.   }*/
  187. }
  188.  
  189. unsigned long doAlgorithm()
  190. {
  191.   unsigned long x, y = 0;
  192.   switch(select)
  193.   {
  194.     case 1:
  195.       return ALGO_01;
  196.     case 2:
  197.       return ALGO_02;
  198.     case 3:
  199.       return ALGO_03;
  200.     case 4:
  201.       return ALGO_04;
  202.     case 5:
  203.       return ALGO_05;
  204.     case 6:
  205.       return ALGO_06;
  206.     case 7:
  207.       return ALGO_07;
  208.     case 8:
  209.       return ALGO_08;
  210.     case 9:
  211.       return ALGO_09;
  212.     case 10:
  213.       return ALGO_10;
  214.     case 11:
  215.       return ALGO_11;
  216.     case 12:
  217.       return ALGO_12;
  218.     case 13:
  219.       return ALGO_13;
  220.     case 14:
  221.       return ALGO_14;
  222.     case 15:
  223.       return ALGO_15;
  224.     case 16:
  225.       return ALGO_16;
  226.     case 17:
  227.       return ALGO_17;
  228.     case 18:
  229.       return ALGO_18;
  230.     case 19:
  231.       return ALGO_19;
  232.     case 20:
  233.       return ALGO_20;
  234.     case 21:
  235.       return ALGO_21;
  236.     case 22:
  237.       y = t&16383;
  238.       x = t*"6689"[t>>16&3]/24&127;
  239.       return (((unsigned long)3e3/y)&1)*35+x*y/4e4+((t>>8^t>>10|t>>14|x)&63);
  240.     default:
  241.       break;
  242.   }
  243. }
  244.  
  245. ISR(TIMER1_COMPA_vect)
  246. {
  247.   OCR2A = doAlgorithm();
  248.   if(drawing == false && count < 128)
  249.   {
  250.     array[count] = doAlgorithm();
  251.     count++;
  252.   }
  253.   ++t;
  254. }
  255.  
  256. void showAlgorithm()
  257. {
  258.   display.setTextSize(1);
  259.   display.setTextColor(1);
  260.   display.setCursor(0,0);
  261.   display.print("Algorithm: ");
  262.   display.print(select);
  263. }
  264.  
  265. void drawDot()
  266. {
  267.   for(short i = 0; i < 128; ++i)
  268.   {
  269.     for(short j = 0; j < 8; ++j)
  270.     {
  271.       //display.drawPixel(i, 16 + (47 - ((array[i] / 255.0) * 47)), 1);
  272.       display.drawFastVLine(i, 16 + (47 - ((array[i] / 255.0) * 47)), 47, 1);
  273.     }
  274.   }
  275. }
  276.  
  277. void soundSetup()
  278. {
  279.   pinMode(speakerPin, OUTPUT);
  280.  
  281.   // Set up Timer 2 to do pulse width modulation on the speaker
  282.   // pin.
  283.   // Use internal clock (datasheet p.160)
  284.   ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  285.  
  286.   // Set fast PWM mode  (p.157)
  287.   TCCR2A |= _BV(WGM21) | _BV(WGM20);
  288.   TCCR2B &= ~_BV(WGM22);
  289.  
  290.   // Do non-inverting PWM on pin OC2A (p.155)
  291.   // On the Arduino this is pin 11.
  292.   TCCR2A = (TCCR2A | _BV(COM2A1)) & ~_BV(COM2A0);
  293.   TCCR2A &= ~(_BV(COM2B1) | _BV(COM2B0));
  294.  
  295.   // No prescaler (p.158)
  296.   TCCR2B = (TCCR2B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  297.  
  298.   // Set initial pulse width to the first sample.
  299.   OCR2A = B00000000;
  300.  
  301.   // Set up Timer 1 to send a sample every interrupt.
  302.   cli();
  303.  
  304.   // Set CTC mode (Clear Timer on Compare Match) (p.133)
  305.   // Have to set OCR1A *after*, otherwise it gets reset to 0!
  306.   TCCR1B = (TCCR1B & ~_BV(WGM13)) | _BV(WGM12);
  307.   TCCR1A = TCCR1A & ~(_BV(WGM11) | _BV(WGM10));
  308.  
  309.   // No prescaler (p.134)
  310.   TCCR1B = (TCCR1B & ~(_BV(CS12) | _BV(CS11))) | _BV(CS10);
  311.  
  312.   // Set the compare register (OCR1A).
  313.   // OCR1A is a 16-bit register, so we have to do this with
  314.   // interrupts disabled to be safe.
  315.   OCR1A = F_CPU / SAMPLE_RATE;    // 16e6 / 8000 = 2000
  316.  
  317.   // Enable interrupt when TCNT1 == OCR1A (p.136)
  318.   TIMSK1 |= _BV(OCIE1A);
  319.  
  320.   sei();
  321. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement