larryfraz 9 Posted September 22, 2013 Share Posted September 22, 2013 A very simple, probability table ascending melodic line CV generator #include <msp430g2553.h> /* output arpeggio of notes to a randomized beat pattern gate turns off for last 1/4 of duration of note beat is fixed at 120 ToDo: add midi in for clock redo rnd() with seed value& algorithm, not just a table */ #define CLOCKHZ 16000000 #define nNotes 24 #define BUTTON BIT3 #define BPM 120 #define TICKS_PER_BAR 32 #define BEAT_PER_SECOND BPM/60 #define MAX_MIDI_CHANNELS 16 #define MAX_POLYPHONY 8 unsigned char notes[MAX_POLYPHONY] = {0}; unsigned char note_index; static const int period = 128; // period of ccro = period for midi 0-127 const long cycles_per_second = CLOCKHZ/128; const int ticks_per_second = BEAT_PER_SECOND*TICKS_PER_BAR; unsigned char midi_off =0; unsigned char curr_note; static const unsigned int durProb[] = {1,1,3,3,4,4,8,8}; static const unsigned int durTable[] = {32,16,8,6,4,3,2,1}; static const int int_prob[] = {3,1,4,4,4,6,4,6}; static const int intervals[] = {1,2,3,4,5,7,10,12}; unsigned char midi_fifo[32]; unsigned char midi_fifoIn=0; unsigned char midi_fifoOut=0; /* * main.c */ static const unsigned int randVals[32] ={ 0xFF, 0x68, 0xF9, 0xB8, 0x10, 0xA1, 0xB6, 0x65, 0xBF, 0x6E, 0x32, 0x2C, 0x95, 0x09, 0xDC, 0x0D, 0xA7, 0x86, 0x00, 0x93, 0xC7, 0x5F, 0x95, 0xA9, 0x5E, 0xFB, 0xC7, 0x22, 0x09, 0xC1, 0xC7, 0xA9, }; unsigned int rnd(); unsigned int getInterval( ); unsigned int getDuration(); void shiftLeft(unsigned char c); void update_state(); void note_on(unsigned char note); void note_off(unsigned char note); unsigned int X = 1; //const int M = 256; //const int a = 65; //const int c = 27; int ptrRnd = 0; int offVal = 0; const unsigned int num_steps = 32; int index, cycles=0; unsigned int z=1; unsigned int counter; const int tableSize = 8; const unsigned int pattern[16]= {4,2,4, 8,6,1,2,3,2, 1, 4,2, 1,2,6,8}; char patternPtr=0; //unsigned char midi_note_num, midi_done, midi_note_vel, midi_rec_state, midi_note_chan, midi_cc_chan=0; void main(void) { DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 |= DIVS_1; // SMCLK = MCLK/2 =8MHZ WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1DIR = BIT7 | BIT6 | BIT5 | BIT4 | BIT2 | BIT0; // Direction P1SEL = BIT6 | BIT4 | BIT1; // Select Timer A output, SMCLK output, UART Rx P1SEL2 |= BIT1; P1REN = BIT2 + BIT5; P1OUT = BIT2;//BIT2 + BIT6; TACCR0 = period; // Setup Timer A for 32768 Hz period TACCR1 = TA0CCR0/2; // Setup Timer A compare to midpoint TACCTL1 = OUTMOD_7; // Setup Timer A reset/set output mode TACTL = TASSEL_2 | MC_1; // Timer A config: SMCLK, count up TACCTL0 |= CCIE; // Enable period interrupt //USCI init UCA0CTL1 |= UCSWRST; // UCB0CTL1 |= UCSWRST; //UCA0CTL0 = UCMODE_3; UCA0CTL1 = UCSSEL_2 + UCSWRST; UCA0BR0 = 8; // DIVIDES SMCLK = 31250 = MIDI SPEC w/UCOS16 oversample UCA0BR1 = 0; // UCA0MCTL |= UCOS16; // 16x oversample IE2 |= UCA0RXIE; // Enable USCI_A0 RX interrupt _BIS_SR(GIE); // // _enable_interrupts(); // Enable interrupts // #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A0 (void){ int cycles_per_tick = cycles_per_second/ticks_per_second; P1OUT |= BIT5; TA0CCR0 = period; TA0CCR1 = z ; if(counter>0){ counter--; if(counter < offVal) P1OUT &= ~BIT5;// turn off for last quarter of duration } else { counter=cycles_per_tick*pattern[patternPtr++];//cycles_per_tick*getDuration(); if (patternPtr>=16) patternPtr = 0; if(rnd()<32) offVal = counter; else offVal = counter>>2; z=z + getInterval(); if(z>= period) z-=period; } } unsigned int rnd(){ if(ptrRnd>=32) ptrRnd = 0; X = randVals[ptrRnd++];// X=(a * X + c) % M ;// 0 to 255 return X; } unsigned int getInterval( ){ unsigned int random = 0; unsigned int counter = 0;//lastIndex; unsigned int sum = 0; //tally of probabilty vals random = rnd(); while(sum<=random){ sum += int_prob[counter++ ]; if (counter>= tableSize) counter = 0; } return intervals[counter]; } unsigned int getDuration() { unsigned int random =0; unsigned int counter = 0; unsigned int sum = 0; random = rnd() ; while ( sum < random){ sum = sum+ durProb[counter++]; if (counter>= 8) counter = 0; P1OUT ^= BIT0; } //add up to random probability, then get the actual duration return durTable[counter];//it wont execute this command!?! } bluehash 1 Quote Link to post Share on other sites
bluehash 1,581 Posted September 22, 2013 Share Posted September 22, 2013 Thanks! Do you have a vid of it running? Quote Link to post Share on other sites
larryfraz 9 Posted September 22, 2013 Author Share Posted September 22, 2013 No,but here's a link. It's doing the fast line that comes in 30 seconds or so in.-- http://t.co/BkjF98sMcS Also here, with other synths. Its driving a Korg Monotron in both. --- https://soundcloud.com/zadok-strawberry/fauxtrane-et-al-1 bluehash 1 Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.