Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // BeatBox -- Simple Arduino rhythm player
- //
- // Author: P.J. Drongowski
- // Date: 15 July 2016
- // Copyright (c) 2016 Paul J. Drongowski
- #include <avr/pgmspace.h>
- #include <avr/interrupt.h>
- #include "waveforms.h"
- #include "kits.h"
- #include "patterns.h"
- #include "LedControl.h"
- #include "binary.h"
- /*
- * Now we create a new LedControl.
- * We use pins 12,11 and 10 on the Arduino for the SPI interface
- * Pin 2 is connected to the DATA IN-pin of the first MAX7221
- * Pin 3 is connected to the CLK-pin of the first MAX7221
- * Pin 4 is connected to the LOAD(/CS)-pin of the first MAX7221
- * There will only be a single MAX7221 attached to the arduino
- */
- LedControl lc=LedControl(2,3,4,1);
- byte b[8]= {B00111100,B00100100,B00100100,B00111000,B00111000,B00100100,B00100100,B00111100};
- byte e[8]= {B11111111,B11111111,B11000000,B11111100,B11111100,B11000000,B11111111,B11111111};
- byte a[8]= {B01111110,B01000010,B01000010,B01111110,B01000010,B01000010,B01000010,B01000010};
- byte t[8]= {B11111111,B11111111,B00011000,B00011000,B00011000,B00011000,B00011000,B00011000};
- // Define input pins
- int ResetButton = 0 ; // Unused (digital)
- int tempoInputPin = 0 ; // Set BPM (analog)
- int patternInputPin = 1 ; // Choose pattern and kit (analog)
- // Define output pins
- int gatePin = 1 ; // Unused
- int blahPin = 5 ; // Unused
- int pwmPin = 9; // PWM (DAC) output
- // Rhythm instrument control variables
- #define INSTRUMENTS 8
- const int8_t* sampleArrays[INSTRUMENTS] ;
- int16_t sampleSizes[INSTRUMENTS] ;
- int sampleCounts[INSTRUMENTS] ;
- int sampleIndices[INSTRUMENTS] ;
- // Tempo control variables
- int tempo = 120 ;
- int delayValue = 125 ;
- // Pattern and pattern control variables
- int patternId = 0 ;
- int kitId = 0 ;
- int patternLength = 16 ;
- int patternIndex = 0 ;
- uint8_t pattern[64] ;
- //
- // TIMER1 PWM. Single PWM, phase correct, 22050KHz.
- // PWM_FREQ = 16,000,000 / 22,050 = 726 = 0x2D5
- // PWM_FREQ = 16,000,000 / 11,025 = 1451 = 0x5AB
- //
- #define PWM_FREQ 363
- void PwmSetup() {
- // Clear OC1 on compare match, 8-bit PWM
- //TCCR1A = _BV(COM1A1) | _BV(WGM10) ;
- TCCR1A = _BV(COM1A1) ;
- // PWM TOP is OCR1A, No prescaler
- TCCR1B = _BV(WGM13) | _BV(CS10) ;
- // Generate interrupt on input capture
- TIMSK1 = _BV(ICIE1) ;
- // Set input capture register to sampling frequency
- ICR1H = (PWM_FREQ >> 8) ;
- ICR1L = (PWM_FREQ & 0xff) ;
- // Turn on the output pin D9
- DDRB |= _BV(5) ;
- sei() ;
- }
- void DisableInterrupts() {
- cli() ;
- TIMSK1 &= ~_BV(OCIE1A) ; // Disable DAC interrupts
- sei() ;
- }
- void EnableInterrupts() {
- cli();
- TIMSK1 |= _BV(OCIE1A) ; // Enable DAC interrupts
- sei();
- }
- //
- // Interrupt service routine (ISR)
- //
- ISR(TIMER1_CAPT_vect) {
- register int16_t dacValue = 0 ;
- register int16_t sample = 0 ;
- if (sampleCounts[0] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[0]+sampleIndices[0]) ;
- dacValue += sample ;
- sampleIndices[0]++ ;
- sampleCounts[0]-- ;
- }
- if (sampleCounts[1] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[1]+sampleIndices[1]) ;
- dacValue += sample ;
- sampleIndices[1]++ ;
- sampleCounts[1]-- ;
- }
- if (sampleCounts[2] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[2]+sampleIndices[2]) ;
- dacValue += sample ;
- sampleIndices[2]++ ;
- sampleCounts[2]-- ;
- }
- if (sampleCounts[3] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[3]+sampleIndices[3]) ;
- dacValue += sample ;
- sampleIndices[3]++ ;
- sampleCounts[3]-- ;
- }
- if (sampleCounts[4] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[4]+sampleIndices[4]) ;
- dacValue += sample ;
- sampleIndices[4]++ ;
- sampleCounts[4]-- ;
- }
- if (sampleCounts[5] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[5]+sampleIndices[5]) ;
- dacValue += sample ;
- sampleIndices[5]++ ;
- sampleCounts[5]-- ;
- }
- if (sampleCounts[6] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[6]+sampleIndices[6]) ;
- dacValue += sample ;
- sampleIndices[6]++ ;
- sampleCounts[6]-- ;
- }
- if (sampleCounts[7] > 0) {
- sample = (int8_t)pgm_read_byte_near(
- sampleArrays[7]+sampleIndices[7]) ;
- dacValue += sample ;
- sampleIndices[7]++ ;
- sampleCounts[7]-- ;
- }
- // Output through OC1A
- dacValue += 127 ;
- OCR1AH = (uint8_t) (dacValue >> 8) & 0xFF ;
- OCR1AL = (uint8_t) dacValue & 0xFF ;
- //Serial.println(dacValue);
- }
- #define SHKIT 0
- #define CTKIT 1
- #define ADKIT 2
- #define VRKIT 3
- void loadKit(int kitId) {
- register int i ;
- register int8_t** samples ;
- register int16_t** sizes ;
- switch(kitId) {
- case SHKIT:
- default: {
- // SH kit
- samples = (int8_t**)shWaveforms ;
- sizes = (int16_t**)shWaveformSizes ;
- break ;
- }
- case CTKIT: {
- // CT kit
- samples = (int8_t**)ctWaveforms ;
- sizes = (int16_t**)ctWaveformSizes ;
- break ;
- }
- case ADKIT: {
- // AD kit
- samples = (int8_t**)adWaveforms ;
- sizes = (int16_t**)adWaveformSizes ;
- break ;
- }
- case VRKIT: {
- // VR kit
- samples = (int8_t**)vrWaveforms ;
- sizes = (int16_t**)vrWaveformSizes ;
- break ;
- }
- }
- for (i = 0 ; i < 8 ; i++) {
- sampleArrays[i] = (int8_t*)pgm_read_word_near(samples+i) ;
- sampleSizes[i] = (int16_t)pgm_read_word_near(sizes+i) ;
- }
- }
- void changePatternAndKit(int patternInput) {
- register int i ;
- register int kit ;
- register uint8_t* newpattern ;
- if (patternInput < 6) {
- // healingA pattern
- patternLength = HEALINGASIZE ;
- newpattern = (uint8_t*)healingA ;
- kit = SHKIT ;
- } else if (patternInput < 12) {
- // cybotranA pattern
- patternLength = CYBOTRONASIZE ;
- newpattern = (uint8_t*)cybotronA ;
- kit = CTKIT ;
- } else if (patternInput < 18) {
- // planetA pattern
- patternLength = PLANETASIZE ;
- newpattern = (uint8_t*)planetA ;
- kit = CTKIT ;
- } else if (patternInput < 24) {
- // adonisA pattern
- patternLength = ADONISASIZE ;
- newpattern = (uint8_t*)adonisA ;
- kit = ADKIT ;
- } else {
- // voodoo pattern
- patternLength = VOODOOSIZE ;
- newpattern = (uint8_t*)voodoo ;
- kit = VRKIT ;
- }
- loadKit(kit) ;
- if (patternLength > 64) patternLength = 64 ;
- for (i = 0 ; i < patternLength ; i++) {
- pattern[i] = (uint8_t)pgm_read_byte_near(newpattern+i) ;
- }
- }
- void setup() {
- lc.shutdown(0,false);
- // Set brightness to a medium value
- lc.setIntensity(0,8);
- // Clear the display
- lc.clearDisplay(0);
- register int i ;
- // Initialize the serial port (only for debugging)
- Serial.begin(9600) ;
- // Set up pin modes
- pinMode(ResetButton, INPUT_PULLUP) ;
- //pinMode(gatePin, OUTPUT) ;
- // Initialize pin values
- //digitalWrite(gatePin, LOW) ;
- pinMode(pwmPin,OUTPUT);
- changePatternAndKit(analogRead(patternInputPin) >> 5) ;
- tempo = 120 ;
- delayValue = (60000 / tempo) / 4 ;
- patternIndex = 0 ;
- for (i = 0 ; i < INSTRUMENTS ; i++) sampleCounts[i] = 0 ;
- PwmSetup() ;
- }
- void beat(int count)
- {
- if (count == 0) {
- lc.setRow(0,0,b[0]);
- lc.setRow(0,1,b[1]);
- lc.setRow(0,2,b[2]);
- lc.setRow(0,3,b[3]);
- lc.setRow(0,4,b[4]);
- lc.setRow(0,5,b[5]);
- lc.setRow(0,6,b[6]);
- lc.setRow(0,7,b[7]);
- }
- if (count == 1) {
- lc.setRow(0,0,e[0]);
- lc.setRow(0,1,e[1]);
- lc.setRow(0,2,e[2]);
- lc.setRow(0,3,e[3]);
- lc.setRow(0,4,e[4]);
- lc.setRow(0,5,e[5]);
- lc.setRow(0,6,e[6]);
- lc.setRow(0,7,e[7]);
- }
- if (count == 2) {
- lc.setRow(0,0,a[0]);
- lc.setRow(0,1,a[1]);
- lc.setRow(0,2,a[2]);
- lc.setRow(0,3,a[3]);
- lc.setRow(0,4,a[4]);
- lc.setRow(0,5,a[5]);
- lc.setRow(0,6,a[6]);
- lc.setRow(0,7,a[7]);
- }
- if (count == 3) {
- lc.setRow(0,0,t[0]);
- lc.setRow(0,1,t[1]);
- lc.setRow(0,2,t[2]);
- lc.setRow(0,3,t[3]);
- lc.setRow(0,4,t[4]);
- lc.setRow(0,5,t[5]);
- lc.setRow(0,6,t[6]);
- lc.setRow(0,7,t[7]);
- }
- }
- void loop() {
- register uint8_t pbits ;
- register int difference ;
- static int oldTempoInput = 0 ;
- static int tempoInput = 0 ;
- static int oldPatternInput = 0 ;
- static int patternInput = 0 ;
- static int bpmCount = 3 ;
- // Turn TXLED on during the first eighth note of every beat
- //if (bpmCount & 0x0002) {
- // TXLED1;
- //} else {
- // TXLED0 ;
- //}
- //Serial.println(bpmCount);
- if (bpmCount == 0)
- bpmCount = 3; else bpmCount-- ;
- beat(bpmCount);
- // Change tempo if necessary
- // Dimmer connected to pin A0 sweeps tempo from 60 to 188 BPM
- tempoInput = analogRead(tempoInputPin) >> 3 ;
- difference = abs(tempoInput - oldTempoInput) ;
- if (difference > 0) {
- // Change the tempo
- tempo = 60 + tempoInput ;
- delayValue = (60000 / tempo) / 4 ;
- oldTempoInput = tempoInput ;
- }
- // Change pattern/kit if necessary
- // Dimmer connected to pin A1 selects one of 5 patterns
- patternInput = analogRead(patternInputPin) >> 5 ;
- difference = abs(patternInput - oldPatternInput) ;
- if (difference > 0) {
- // Change the pattern and its associated kit
- changePatternAndKit(patternInput) ;
- oldPatternInput = patternInput ;
- //add the symbol for change of kit based on patternInput
- }
- // Delay for the equivalent of one sixteenth note
- delay(delayValue) ;
- // Wrap around the pattern index if necessary and
- // get the bit pattern for the current step
- if (patternIndex >= patternLength) patternIndex = 0 ;
- pbits = pattern[patternIndex] ;
- for (int i = 0 ; i < 8 ; i++) {
- if (pbits & 0x01) {
- sampleCounts[i] = sampleSizes[i] ;
- sampleIndices[i] = 0 ;
- }
- pbits = pbits >> 1 ;
- }
- patternIndex++ ;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement