improviz

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

firmware.c (2861B)


      1 #define F_CPU 16000000UL
      2 #include <avr/io.h>
      3 #include <avr/interrupt.h>
      4 #include <avr/sleep.h>
      5 #include <util/delay.h>
      6 
      7 #define LENGTH(X) sizeof(X)/sizeof(*X)
      8 
      9 #define BLOCK 100
     10 #define BPS   62500
     11 
     12 enum state {
     13 	INACTIVE = 0,
     14 	ATTACK   = 1,
     15 	DECAY    = 2,
     16 	SUSTAIN  = 3,
     17 	RELEASE  = 4
     18 };
     19 
     20 struct voice {
     21 	enum state state;
     22 	unsigned int time;
     23 	unsigned int freq;
     24 	unsigned int phase;
     25 	unsigned int dV;
     26 };
     27 
     28 float
     29 tri(unsigned int ph)
     30 {
     31 	double p = (double)((ph%BPS)*2 - BPS);
     32 	return p < 0 ? -p/(double)BPS : p/(double)BPS;
     33 }
     34 
     35 float
     36 saw(unsigned int ph)
     37 {
     38 	return (float)ph/(float)BPS;
     39 }
     40 
     41 float
     42 sqr(unsigned int ph)
     43 {
     44 	return ph%BPS>BPS/2? 0.0 : 1.0;
     45 }
     46 
     47 float (*wave[])(unsigned int) = { &tri, &sqr, &saw};
     48 
     49 struct voice voices[1];
     50 unsigned int ADSR[4];
     51 unsigned int waveform = 1;
     52 unsigned int c = 0;
     53 
     54 unsigned int
     55 adsr(struct voice *v)
     56 {
     57 	unsigned int v1=0, v2=255, t, T;
     58 	switch (v->state){
     59 	case INACTIVE:
     60 		return 0;
     61 	case ATTACK:
     62 		break;
     63 	case DECAY:
     64 		v1 = 255;
     65 		v2 = ADSR[2];
     66 		break;
     67 	case SUSTAIN:
     68 		return ADSR[2];
     69 	case RELEASE:
     70 		v1 = ADSR[2];
     71 		v2 = 0;
     72 		break;
     73 	default:
     74 		break;
     75 	}
     76 	t = v->time;
     77 	T = ADSR[v->state-1];
     78 	return (v1*(T-t) + v2*t)/T;
     79 }
     80 
     81 void
     82 init_pwm()
     83 {
     84 	DDRD   |= _BV(PD6);
     85 	TCCR0A |= _BV(COM0A1) | _BV(WGM01) | _BV(WGM00);
     86 	TCCR0B |= _BV(CS00);
     87 }
     88 
     89 void
     90 init_interrupt()
     91 {
     92 	TIFR0 =_BV(TOV0);
     93 	TIMSK0=_BV(TOIE0);
     94 	sei();
     95 }
     96 
     97 void
     98 init()
     99 {
    100 	//TEMPORARY
    101 	ADSR[0] = 8;
    102 	ADSR[1] = 32;
    103 	ADSR[2] = 128;
    104 	voices[0].state = ATTACK;
    105 	voices[0].freq  = 440;
    106 	//voices[2].state = ATTACK;
    107 	//voices[2].freq  = 550;
    108 	//---------
    109 	set_sleep_mode(0);
    110 	init_pwm();
    111 	init_interrupt();
    112 }
    113 
    114 void
    115 scan_keys()
    116 {
    117 	int i,j;
    118 	int row = 1;
    119 	int col = 1;
    120 	for(i=0; i<7; ++i){
    121 		row = row << 1;
    122 		for(j=0; j<6; ++j){
    123 			col = col << 1;
    124 			//woop
    125 		}
    126 	}
    127 }
    128 
    129 void
    130 scan_knobs()
    131 {
    132 }
    133 
    134 void
    135 update_phase(struct voice *v)
    136 {
    137 	if (v->state == INACTIVE) return;
    138 	v->phase = (v->phase+(v->freq))%BPS;
    139 }
    140 
    141 void
    142 update_voice(struct voice *v)
    143 {
    144 	if (v->state == INACTIVE) return;
    145 	v->dV = adsr(v);
    146 	if (v->state == SUSTAIN) return;
    147 	v->time++;
    148 	if (v->time > ADSR[v->state-1]){
    149 		v->time = 0;
    150 		v->state = (v->state+1)%5;
    151 	}
    152 }
    153 
    154 void
    155 update_synth()
    156 {
    157 	int i;
    158 	for(i=0; i<LENGTH(voices); ++i) update_voice(&voices[i]);
    159 }
    160 
    161 unsigned int
    162 get_voice(struct voice *v)
    163 {
    164 	unsigned int amp;
    165 	if (v->state == INACTIVE) return 0;
    166 	amp = (*wave[waveform])(v->phase) * v->dV;
    167 	return amp;
    168 }
    169 
    170 void
    171 drive_pwm()
    172 {
    173 	unsigned int p = 0;
    174 	int i;
    175 	for (i=0; i<LENGTH(voices); ++i) {
    176 		update_phase(&voices[i]);
    177 		p += get_voice(&voices[i])/8;
    178 	}
    179 	OCR0A = p;
    180 }
    181 
    182 /*void
    183 loop()
    184 {
    185 	scan_keys();
    186 	scan_knobs();
    187 	update_synth();
    188 	int i;
    189 	for (i=0; i<BLOCK; ++i) {
    190 		drive_pwm();
    191 		_delay_us(1000000/BPS);
    192 	}
    193 }*/
    194 
    195 ISR(TIMER0_OVF_vect)
    196 {
    197 	c++;
    198 	drive_pwm();
    199 	if (c >= BLOCK) {
    200 		c = 0;
    201 		scan_keys();
    202 		scan_knobs();
    203 		update_synth();
    204 	}
    205 	
    206 }
    207 
    208 int
    209 main ()
    210 {
    211 	init();
    212 	for(;;) sleep_mode();
    213 	return 0;
    214 }
    215