- Appendix with cost details with all part numbers and their price. This cost will include components as described in the Budget Considerations section. 
 
         
          
        Appendix I - Cost 
        
          
            | Item | 
            Quantity | 
            Cost | 
             | 
           
          
            | Mega32 | 
            1 | 
            $0.00  | 
            donated by Marcelo Garza(last semester project) | 
           
          
            | custom PC board | 
            1 | 
            $5  | 
             | 
           
          
            | 6N138 optoisolator | 
            1 | 
            $1  | 
            digikey | 
           
          
            | 10KOhm Potentiometers | 
            4 | 
            $1.00  | 
            allelectronics | 
           
          
            | LCD | 
            1 | 
            $8.00  | 
            lab | 
           
          
            | 3904 npn BJT | 
            1 | 
            $0.00  | 
            lab | 
           
          
            | project box | 
            1 | 
            $0.00  | 
            previous year box | 
           
          
            | audio out jack | 
            1 | 
            $0.00  | 
            previous year box | 
           
          
            | midi Din-5 connector | 
            1 | 
            $0.00  | 
            previous year box | 
           
          
            | assorted resistors | 
            10+ | 
            $0.00  | 
            lab | 
           
          
            | assorted capacitors | 
            2+  | 
            $0.00  | 
            lab | 
           
          
            | midi keyboard | 
            1 | 
            $0  | 
            Donated by TA(Idan) | 
           
          
            | speaker | 
            1 | 
            $0  | 
            Previously Owned | 
           
          
            | push buttons | 
            3 | 
            $0  | 
            Previously year box  | 
           
          
            | Total | 
             | 
            $15  | 
             | 
           
         
          
        Appendix II - Logic Diagram  
          
      Appendix III - Schematic  
                 
        
      Appendix IV - Division of Task 
      Min:  
      DDS Code 
  Main State machines 
  Filtering 
  Waveform Creation/operation 
  H halftone coding 
  Demo Songs coding 
      Franco: 
      Midi Keyboard to MPU interface 
  Midi signal Decoding algorithm 
  Box/Board/Potentiometers/Push button creation.  
  LCD interface 
      Appendix V - Code  
       #include <Mega32.h> 
        #include <delay.h>  
        #include <stdio.h> 
        #include <stdlib.h> 
        #include <math.h> // for sine 
      //I like these definitions 
        #define begin { 
        #define end } 
        #define countMS 8 //ticks/mSec 
        #define IncAdjust 8.3886 
        #define oscNUM 8 
        #define keysize 49 
       
      #define A 440 
        #define Asharp 466.1637 
        #define B 493.8833 
        #define C 523.2511 
        #define Csharp 554.3652 
        #define D 587.3295 
        #define Dsharp 622.2540 
        #define E 659.2551 
        #define F 698.4565 
        #define Fsharp 739.9888 
        #define G 783.9909 
        #define Gsharp 830.6094 
      //Notes State Machine 
        //#define wait 0 
        //#define playnote 1 
       
      //Settings State Machine 
        //settingstate 
      #define ADSR 0 
        #define osc1 1 
        #define osc2 2 
        #define operator 3 
        #define special 4 
      //Operator State 
        #define off 0 
        #define add 1 
        #define subtract 2 
        #define multiply 3 
       
      //Wavestate 
        //#define off 0 
        #define sinewave 1 
        #define triwave 2 
        #define squarewave 3 
        #define sawwave 4 
       
      //SpecialState 
        #define demo 0 
        #define freqshift 1  
        #define filter 2 
       
      //filterstate 
        //#define off 
        #define highpass 1 
        #define lowpass 2 
       
      //Envelope State Machine 
        #define getAttack 0 
        #define getDecay 1 
        #define getSustain 2 
        #define getRelease 3 
      //which byte is being read in from uart 
        //midi sends 3 bytes per message, status byte, note byte, velocity byte 
        #define status_byte 0 
        #define note_byte 1 
        #define vel_byte 2 
      //fixedpoint math 
        #define float2fix(a) ((int)((a)*256.0))  
        #define fix2float(a) ((float)(a)/256.0) 
        #define int2fix(a) (((int)(a))<<8) //Convert char to fix. a is a char 
        #define fix2int(a) ((signed char)((a)>>8)) //Convert fix to char. a is an int 
      //initialize LCD 
        #asm 
  .equ __lcd_port=0x15 
  #endasm 
  #include <lcd.h> // LCD driver routine 
   
  char lcd_buffer[17]; // LCD display buffer 
   
  //IIR stuff 
  #pragma regalloc- 
  int alpha, yn_1 ; 
  #pragma regalloc+ 
       #pragma regalloc- 
  int b1,a2,a3,xn, xn_1, xn_2, yn, yn_2 ; 
  #pragma regalloc+ 
  // int Butter2low(int); 
  int Butter2high(int); 
  void PrintSpecialType(char); 
  void PrintOperatorType(char);//Print Operator to LCD 
  void PrintWaveType(char);//Print Wave type to LCD 
  void updatewave(void); 
  int multfix(int,int); //fast fixpoint mult 
  void initialize(void); //all the usual mcu stuff 
  void setting_state_machine(void); //notes state machine 
  void envelope_state_machine(void); //envelope state machine 
  int OnePoleLow(int); 
      unsigned int attack, decay, release; 
        unsigned int attack_old, decay_old, release_old, sustain_old; 
        unsigned int time[8], sustain[8], increment[8]; 
        unsigned char sustain_flag ; 
        int sustainamp_fix; 
        float sustainamp_float; 
        int amp[8]; 
      flash float keyboard[keysize] = {C/8,Csharp/8,D/8,Dsharp/8,E/8,F/8,Fsharp/8,G/8,Gsharp/8,A/4,Asharp/4,B/4, 
  C/4,Csharp/4,D/4,Dsharp/4,E/4,F/4,Fsharp/4,G/4,Gsharp/4,A/2,Asharp/2,B/2, 
  C/2,Csharp/2,D/2,Dsharp/2,E/2,F/2,Fsharp/2,G/2,Gsharp/2,A,Asharp,B, 
  C,Csharp,D,Dsharp,E,F,Fsharp,G,Gsharp,A*2,Asharp*2,B*2, C*2}; 
      //general counters 
        unsigned int i, ii , j; 
      //Oscillator Variables 
        unsigned char count, oscReady, oscCounter; 
        int songcounter, songtimer; 
        unsigned char restcounter; 
        int hitamp[8]; 
        unsigned char Held[keysize]; 
        
      //envelope state machine variables 
        unsigned char envelopestate_timer; 
        unsigned char envelopestate; 
       
      //filter variables 
        unsigned char filterflag; 
        int yn_temp[8]; 
      //Setting State Machine Variables 
        unsigned char settingstate, ADSRdisplay, operatorstate, specialstate, demostate, filterstate; 
        signed char freqshiftstate;  
        unsigned char oscstate[2]; 
        unsigned char settingstate_timer; 
        unsigned char debounce0, debounce1, debounce2; 
       
      //buffers and temps 
        signed int wavebuffer; 
        signed int tempwave[2]; 
      //Midi decoder Variables 
        unsigned char velocity_array[keysize]; 
        unsigned char status,note; //the 3 bytes of a midi message 
        unsigned char current_byte; //byte currently being read in the rxc interrupt 
      //floating point shortcuts  
        int amp_temp; 
        int pointone_fix = float2fix(.1); 
        int sustainamp_ten_int; 
        unsigned int accumulator[8] @0x5f0; 
        unsigned char highbyte[16] @0x5f0; 
        /* 
        unsigned char highbyte0 @0x5f1; //the HIGH byte of the accumulator variable 
        unsigned char highbyte1 @0x5f3; //the HIGH byte of the accumulator variable 
        unsigned char highbyte2 @0x5f5; //the HIGH byte of the accumulator variable 
        unsigned char highbyte3 @0x5f7; //the HIGH byte of the accumulator variable 
        unsigned char highbyte4 @0x5f9; //the HIGH byte of the accumulator variable 
        unsigned char highbyte5 @0x5fb; //the HIGH byte of the accumulator variable 
        unsigned char highbyte6 @0x5fd; //the HIGH byte of the accumulator variable 
        unsigned char highbyte7 @0x5ff; //the HIGH byte of the accumulator variable 
        */ 
        signed int finalwave[256] @0x600; //need loc to avoid glitch 
        eeprom signed int sineTable[256] = {0}; 
        //eeprom int squareTable[256] = {0}; 
        //eeprom signed int triTable[256] = {0}; 
        //mary had a little lamb 
        //float song[] = {E,D,C,D,E,E,E,D,D,D,E,G,G,E,D,C,D,E,E,E,D,D,E,D,C}; 
      //twinkle twinkle little start 
        //float song[] = {C,C,G,G,A*2,A*2,G, 0,F,F,E,E,D,D,C,0,G,G,F,F,E,E,D,0,G,G,F,F,E,E,D,0,C,C,G,G,A*2,A*2,G,0,F,F,E,E,D,D,C,0}; 
      //canon 
        flash float canon[] = {A*2,0, Fsharp, G, A*2,0,Fsharp, G, A*2,A,B,Csharp,D,E,Fsharp,G,Fsharp,0,D,E,Fsharp,0,Fsharp/2,G/2,A,B,A,G/2,A,Fsharp/2,G/2,A,G/2,0,B,A,G/2,0,Fsharp/2,E/2,Fsharp/2,E/2,D/2,E/2,Fsharp/2,G/2,A,B,A,0,B,A,B,0,Csharp,D,A,B,Csharp,D,E,Fsharp,G,A*2,Fsharp,0,D,E,Fsharp,0,E,D,E,Csharp,D,E,Fsharp,E,D,Csharp,D,0,B,Csharp,D,0,D/2,E/2,Fsharp/2,G/2,Fsharp/2,E/2,Fsharp/2,D,Csharp,D,B,0,D,Csharp,B,0,A,G/2,A,G/2,Fsharp/2,G/2,A,B,Csharp,D,B,0,D,Csharp,D,0,Csharp,B,Csharp,D,E,D,Csharp,D,B,Csharp,64000}; 
      //mario 
        //float canon[] = {E,E,0,E,0,C,E,0,G,0,0,0,G/2,0,0,0,C,0,G/2,0,E/2,0,A,0,B,0,Asharp,A,0,G/2,E,G,A*2,0,F,G,0,E,0,C,D,B, 64000}; 
      //row row row your boat round 
        flash float row1[] ={0,C,0,0,C,0,0,C,0,D,E,0,0,E,0,D,E,0,F,G,0,0,0,0,0,C*2,C*2,C*2,G,G,G,E,E,E,C,C,C,G,0,F,E,0,D,C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64000}; 
        flash float row2[] ={0,0,0,0,0,0,0,0,0,0,0,0,0,C,0,0,C,0,0,C,0,D,E,0,0,E,0,D,E,0,F,G,0,0,0,0,0,C*2,C*2,C*2,G,G,G,E,E,E,C,C,C,G,0,F,E,0,D,C,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64000}; 
        flash float row3[] ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,C,0,0,C,0,0,C,0,D,E,0,0,E,0,D,E,0,F,G,0,0,0,0,0,C*2,C*2,C*2,G,G,G,E,E,E,C,C,C,G,0,F,E,0,D,C,0,0,0,0,0,64000}; 
      //multi notes 
        //flash float poly1[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Fsharp,0,E,0,D,0,Csharp,0,B,0,A,0,B,0,Csharp,0,D,0,Csharp,0,B,0,A,0,G/2,0,Fsharp/2,0,G/2,0,E/2,0, D/2,Fsharp/2,A,G/2,Fsharp/2,D/2,Fsharp/2,E/2,D/2,B/2,D/2, A,G/2, B,A,G/2,Fsharp/2,D/2,E/2,Csharp,D,Fsharp, A*2,A,64000}; 
        //flash float poly2[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,Fsharp,0,E,0,D,0,Csharp,0,B,0,A,0,B,0,Csharp,0,D,0,Csharp,0,B,0,A,0,G/2,0,Fsharp/2,0,G/2,0,E/2,0, D/2,Fsharp/2,A,G/2,Fsharp/2,D/2,Fsharp/2,E/2,64000}; 
        //flash float poly3[] = {B,0,Fsharp/2,0,G/2,0,D/2,0,E/2,0,B/2,0,E/2,0,Fsharp/2,0,B,0,Fsharp/2,0,G/2,0,D/2,0,E/2,0,B/2,0,E/2,0,Fsharp/2,0,B/2,0,Fsharp/2,0,G/2,0,D/2,0,E/2,0,B/2,0,E/2,0,Fsharp/2,0,B,0,E/2,0,G/2,0,D/2,0,E/2,0,B/2,0,E/2,0,Fsharp/2,0,B/2,0,Fsharp/2,0,G/2,0,D/2,0,64000}; 
        flash float poly1[] ={E, Dsharp, E, Dsharp, E, B, D, C, A, 0, 1, C/2, E/2, A, B, 0 , 1, E/2, Gsharp/2, B, C,0, 1, E/2, E, Dsharp, E, Dsharp,  
  E, B, D, C, A, 0, 1, C/2, E/2, A, B, 0 , 1, E/2, C, B, A,0, 0,0, E, Dsharp, E, Dsharp, E, B, D, C,  
  A, 0, 1, C/2, E/2, A, B, 0 , 1, E/2, Gsharp/2, B, C,0, 1, E/2, E, Dsharp, E, Dsharp, E, B, D, C, A, 0, 1, C/2, E/2, A,  
  B, 0 , 1, E/2, C, B, A,0, 1, B, C, D, 
  E, 0, 0 , G/2, F,E,D,0,0,F/2, E,D,C,0,0,E/2,D,C,B,0, 1, E/2, E, 1, 1, E, E*2,1, 1,1, Dsharp,0, E, 1,1, Dsharp, E, Dsharp, 
  E, Dsharp, E, B, D, C, A, 0, 1, C/2, E/2, A, B, 0, 1, E/2, Gsharp/2, B, C, 0, 1, E/2,E, Dsharp, E, Dsharp, E, B, D, C,  
  A, 0, 1, C/2, E/2, A, B, 0 , 1, E/2, C, B, A, 0 , 0, 0, 0 ,0,0,0,64000}; 
  flash float poly2[] ={1,1,1,1,1,1,1,1,A/4, E/4, A/2, 1, 1, 1, E/8, E/4, Gsharp/4, 1, 1, 1, A/4, E/4, A/2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  A/4, E/4, A/2, 1, 1, 1,E/8, E/4, Gsharp/4, 1, 1, 1, A/4, E/4, A/2, 1,1,1,1,1,1,1,1,1,A/4, E/4, A/2, 1, 1, 1, E/8, E/4, Gsharp/4, 1, 1, 1, A/4, E/4, A/2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
  A/4, E/4, A/2, 1, 1, 1,E/8, E/4, Gsharp/4, 1, 1, 1, A/4, E/4, A/2, 1, 1, 1, C/4, G/4,C/2, 1, 1, 1, 
  G/8, G/4, B/2, 1, 1, 1, A/4, E/4, A/2, 1, 1, 1, E/8, E/4, E/2, 1, 1, E/2, E, 1, 1, Dsharp, E,0, 1,1,1, Dsharp,E, 1, 1, 1, 1,  
  1, 1, 1, 1, 1, 1, A/4, E/4, A/2, 1, 1, 1, E/8, E/4, Gsharp/4, 1, 1, 1, A/4, E/4, A/2, 1, 1, 1, 1, 1, 1, 1, 1, 
  A/4, E/4, A/2, 1, 1, 1, E/8, E/4, Gsharp/4, 1, 1, 1, A/4, E/4, A/4, 0, 0, 0,0,0};  
  //flash float poly3[] ={0}; 
      //float song[3] = {Asharp, 440, 440}; 
      //frequencyshift table 
        flash float shift[25] ={.5, .529732, .561231, .594604, .629961, .66742, .707107, .749154, .793701, .840896, .890899, .943874, 1, //shiftdown (12-1)twelthroot(2) 
  1.05946, 1.12246, 1.18921, 1.25992, 1.33484, 1.41421, 1.49831, 1.5874, 1.68179, 1.7818, 1.88775, 2}; //shiftup (1-12)twelthroot(2) 
       
        
      //interrupt [TIM0_OVF] void sgen(void) 
        interrupt [TIM1_COMPA] void timer1_compareA(void) 
        begin 
         
         
  //the DDR code and scaling 
  wavebuffer = 0; 
   
      //update Accumulators  
    accumulator[0] = accumulator[0] + increment[0];  
    accumulator[1] = accumulator[1] + increment[1];  
    accumulator[2] = accumulator[2] + increment[2];  
    accumulator[3] = accumulator[3] + increment[3];  
    accumulator[4] = accumulator[4] + increment[4];  
    accumulator[5] = accumulator[5] + increment[5];  
    accumulator[6] = accumulator[6] + increment[6];  
    accumulator[7] = accumulator[7] + increment[7];  
    /*  
    if(increment[0]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[1]],amp[0]); 
    if(increment[1]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[3]],amp[1]); 
    if(increment[2]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[5]],amp[2]); 
    if(increment[3]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[7]],amp[3]); 
    if(increment[4]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[9]],amp[4]); 
    if(increment[5]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[11]],amp[5]); 
    if(increment[6]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[13]],amp[6]); 
    if(increment[7]) wavebuffer = wavebuffer + multfix(finalwave[highbyte[15]],amp[7]); 
    */ 
       
      //setup accumulators  
    if(increment[0]) 
    begin  
    switch(filterstate) 
    begin 
    case off: 
    wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[1]],amp[0]),hitamp[0]);  
    break; 
    case highpass: 
    break; 
    case lowpass: 
    yn_1 = yn_temp[0]; 
    wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[1]])>>(amp[0]))); 
    yn_temp[0] = yn_1; 
    break; 
    end  
    end  
    if(increment[1]) 
    begin  
    switch(filterstate) 
    begin 
    case off: 
    wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[3]],amp[1]),hitamp[1]);  
    break; 
    case highpass: 
    break; 
    case lowpass: 
    yn_1 = yn_temp[1]; 
    wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[3]])>>(amp[1]))); 
    yn_temp[1] = yn_1; 
    break; 
    end  
    end  
       if(increment[2]) 
  begin  
  switch(filterstate) 
  begin 
  case off: 
  wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[5]],amp[2]),hitamp[2]);  
  break; 
  case highpass: 
  break; 
  case lowpass: 
  yn_1 = yn_temp[2]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[5]])>>(amp[2]))); 
  yn_temp[2] = yn_1; 
  break; 
  end  
  end  
  if(increment[3]) 
  begin  
  switch(filterstate) 
  begin 
  case off: 
  wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[7]],amp[3]),hitamp[3]);  
  break; 
  case highpass: 
  break; 
  case lowpass: 
  yn_1 = yn_temp[3]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[7]])>>(amp[3]))); 
  yn_temp[3] = yn_1; 
  break; 
  end  
  end  
  if(increment[4]) 
  begin  
  switch(filterstate) 
  begin 
  case off: 
  wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[9]],amp[4]),hitamp[4]);  
  break; 
  case highpass: 
  break; 
  case lowpass: 
  yn_1 = yn_temp[4]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[9]])>>(amp[4]))); 
  yn_temp[4] = yn_1; 
  break; 
  end  
  end  
  if(increment[5]) 
  begin  
  switch(filterstate) 
  begin 
  case off: 
  wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[11]],amp[5]),hitamp[5]);  
  break; 
  case highpass: 
  break; 
  case lowpass: 
  yn_1 = yn_temp[5]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[11]])>>(amp[5]))); 
  yn_temp[5] = yn_1; 
  break; 
  end  
  end  
  if(increment[6]) 
  begin  
  switch(filterstate) 
  begin 
  case off: 
  wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[13]],amp[6]),hitamp[6]);  
  break; 
  case highpass: 
  break; 
  case lowpass: 
  yn_1 = yn_temp[6]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[13]])>>(amp[6]))); 
  yn_temp[6] = yn_1; 
  break; 
  end  
  end  
  if(increment[7]) 
  begin  
  switch(filterstate) 
  begin 
  case off: 
  wavebuffer = wavebuffer + multfix(multfix(finalwave[highbyte[15]],amp[7]),hitamp[7]);  
  break; 
  case highpass: 
  break; 
  case lowpass: 
  yn_1 = yn_temp[7]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[15]])>>(amp[7]))); 
  yn_temp[7] = yn_1; 
  break; 
  end  
  end  
       //output wave  
  OCR0 = (char)(fix2int(wavebuffer)) + 128; 
  /*  
  for (i = 0; i <8; i++) 
  begin 
  accumulator[i] = accumulator[i] + increment[i];  
  end 
       //finalamp = 0;  
           
  for (i = 0; i <8; i++) 
  begin  
  //accumulator[i] = accumulator[i] + increment[i];  
  if(increment[i]) 
  begin 
   
  wavebuffer = wavebuffer + ((finalwave[highbyte[i*2 + 1]]>>(amp[i]))); 
  finalamp++; 
  end 
  end 
   
  //Oscilators  
   
  if(filterflag) 
  begin 
  yn_1 = yn_temp[i]; 
  wavebuffer = wavebuffer + ((OnePoleLow(finalwave[highbyte[i*2 + 1]])>>(amp[i]))); 
  yn_temp[i] = yn_1; 
  end 
  else */ 
       
       //generate rising amplitude 
  // 8 counts is about 1 mSec 
  count--; 
  if (0 == count ) 
  begin 
  count=countMS; 
  for(i = 0; i < 8; i++) 
  begin 
  time[i]++;  
  // sustain[ii]++; 
  end 
  if (songtimer>0) --songtimer; 
  if (settingstate_timer>0) --settingstate_timer; 
  if (envelopestate_timer>0) --envelopestate_timer; 
  end 
  end  
  /***************************************** 
  Recieve Interrupt 
  Recieve Notes From Midi Controller 
  *****************************************/ 
  interrupt [USART_RXC] void uart_rec(void) 
  begin 
        
       //collect the proper byte of a midi message 
  switch (current_byte) 
  begin 
       case status_byte: 
  status = UDR; 
  if(((status & 0xF0) == 0x90)) //read the 1st byte of a message 
  begin 
  current_byte = note_byte; 
  //PORTC.1 = 1; 
  end 
  /* 
  else if( (status & 0xF0) != 0xE0) 
  begin 
  note = status; 
  current_byte = vel_byte; 
  //PORTC.1 = 1; 
  end 
  */  
  /* 
  else if( (status & 0xF0) == 0xE0) 
  begin 
  //PORTC.1 = 0; 
  end 
  */ 
  break; 
  case note_byte: //read the 2nd byte of a message 
  note = UDR; 
  if((note & 0xF0) == 0x90)current_byte = note_byte; 
  else if(note & 0x80) current_byte = status_byte; 
  else current_byte = vel_byte; 
   
  break; 
  case vel_byte: //read the 3rd byte of a message 
  //if(velocity_array[note - 36] == 0)  
  velocity_array[note - 36] = UDR; 
  //else velocity_array[note - 36] = 0; 
  // for(ii = 0; ii < keysize; ii++) 
  // begin 
  //ii = 24; 
  // if(~PINC & (0b00000001<<ii)) 
       //if(velocity_array[ii] != 0) 
      //find note         
        if(velocity_array[note - 36] != 0) 
        begin 
        if(Held[note - 36] == 9) 
        begin 
        time[oscCounter] = 0; 
        hitamp[oscCounter] = float2fix((float)velocity_array[note - 36]/127); 
        increment[oscCounter] = (int)((float)keyboard[note - 36]*IncAdjust); 
        sustain_flag = sustain_flag | (0b00000001 << oscCounter);//ready now 
        sustain[oscCounter] = 0; 
        Held[note - 36] = oscCounter; 
        oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
        while(~(oscReady | ~(0b00000001 << oscCounter))) 
        begin 
        oscCounter++; 
        if (oscCounter > 7) oscCounter = 0; 
        if (oscReady == 0) break; 
        end 
       if(freqshiftstate && oscReady) 
  begin 
   
  time[oscCounter] = 0; 
  hitamp[oscCounter] = float2fix((float)velocity_array[note - 36]/127); 
  increment[oscCounter] = (int)((float)keyboard[(signed int)(note - 36 + freqshiftstate)]*IncAdjust); 
  sustain_flag = sustain_flag | (0b00000001 << oscCounter);//ready now 
  sustain[oscCounter] = 0; 
  Held[(signed int)(note - 36 + freqshiftstate)] = oscCounter; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
  end 
  end 
  end 
  else  
  begin 
  sustain_flag = sustain_flag & ~(0b00000001 << Held[note-36]); 
  Held[note-36] = 9; 
  end 
  //end 
  current_byte = note_byte; 
  //PORTC = ~note; 
  break; 
       
       end 
       
      end 
        /***************************************** 
        Main Function 
        *****************************************/ 
        void main(void) 
        begin 
       
       initialize(); 
       while(1) 
  begin 
  if (settingstate_timer==0) setting_state_machine(); 
  if (envelopestate_timer==0) envelope_state_machine(); 
       
       // attack = 200 ; 
       
  // ii = 0; 
  // if((time[ii] == ((int)(10*fix2float(amp[ii])) + 1)*(attack/10)) && (amp[ii]<float2fix(1))) amp[ii]= amp[ii] + float2fix(.1);  
  /* if((time[ii] == (attack + (11 - (int)(10*fix2float(amp[ii])))*(decay/((int)(10*fix2float(float2fix(1) - sustainamp_fix)))))) && (amp[ii]>(sustainamp_fix))) amp[ii]= amp[ii] - float2fix(.1);  
  if((time[ii] == (attack + decay + sustain[ii] + ((int)(10*fix2float(sustainamp_fix - amp[ii])) + 1)*(release/((int)(10*fix2float(sustainamp_fix)))))) && (amp[ii]>float2fix(0))) amp[ii]= amp[ii] - float2fix(.1);  
  if(time[ii] >= (attack + decay + sustain[ii] + release))//end note 
  begin 
  increment[ii]= 0; 
  oscReady = oscReady | (0b00000001 << ii);//ready now 
  amp[ii] = float2fix(0); 
  end  
  */  
   
  //ii = 0; 
   
  //if (~(sustain_flag | ~(0b00000001 << ii)) == 0) sustain[ii]++; 
  // sustain[ii] = 1000; 
        
       for (ii = 0; ii <8; ii++)//check all 8 channels  
  begin 
       
       amp_temp = (int)(10*fix2float(amp[ii]));//fix2float(amp[ii]); 
       if(time[ii] <= attack)  
  begin 
  if((time[ii] >= (amp_temp + 1)*(attack/10))  
&& (time[ii] <= (amp_temp + 2)*(attack/10)) 
&& (amp[ii]<float2fix(1))) amp[ii]= amp[ii] + pointone_fix;  
  end 
  else if(time[ii] <= (attack + decay))  
  begin 
  if((time[ii] >= (attack + (11 - amp_temp)*(decay/(10 - sustainamp_ten_int))))  
&& (time[ii] <= (attack + (12 - amp_temp)*(decay/(10 - sustainamp_ten_int))))  
&& (amp[ii]>(sustainamp_fix))) amp[ii]= amp[ii] - pointone_fix;  
  end 
  else if(time[ii] <= (attack + decay + sustain[ii] + release)) 
  begin 
  if((time[ii] >= (attack + decay + sustain[ii] + (sustainamp_ten_int - amp_temp + 1)*(release/(sustainamp_ten_int))))  
&& (time[ii] <= (attack + decay + sustain[ii] + (sustainamp_ten_int - amp_temp + 2)*(release/(sustainamp_ten_int))))  
&& (amp[ii]>0)) amp[ii]= amp[ii] - pointone_fix;  
  end 
  else 
  // if(time[ii] >= (attack + decay + sustain[ii] + release)) 
  begin 
  increment[ii]= 0; 
  oscReady = oscReady | (0b00000001 << ii);//ready now 
  amp[ii] = float2fix(0); 
  hitamp[ii] = int2fix(1); 
  sustain[ii] = 0; 
  end  
   
  /* 
  amp_temp = fix2float(amp[ii]); 
  // if(time[ii] <= attack)  
  // begin 
  if((time[ii] == (amp_temp + 1)*(attack/10)) && (amp[ii]<float2fix(1))) amp[ii]= amp[ii] + pointone_fix;  
  // end 
  // else if(time[ii] <= (attack + decay))  
  // begin 
  if((time[ii] == (attack + (11 - amp_temp)*(decay/((int)(10*(1 - sustainamp_float)))))) && (amp[ii]>(sustainamp_fix))) amp[ii]= amp[ii] - pointone_fix;  
  // end 
  // else if(time[ii] <= (attack + decay + sustain[ii] + release)) 
  // begin 
  if((time[ii] == (attack + decay + sustain[ii] + ((int)(10*(sustainamp_float - amp_temp)) + 1)*(release/((int)(10*(sustainamp_float)))))) && (amp[ii]>0)) amp[ii]= amp[ii] - pointone_fix;  
  // end 
  // else 
  if(time[ii] >= (attack + decay + sustain[ii] + release)) 
  begin 
  increment[ii]= 0; 
  oscReady = oscReady | (0b00000001 << ii);//ready now 
  amp[ii] = float2fix(0); 
  end  
  */ 
       end 
           
           
  //Song Generator  
  if(songtimer == 0) 
  begin 
       switch(demostate) 
  begin 
   
  case 1://song 1  
  songtimer = 300; 
  increment[oscCounter] = (int)((float)(canon[songcounter])*IncAdjust); 
  while(canon[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
   
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(canon[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(canon[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end  
   
  songcounter++; 
  if (canon[songcounter] == 64000)songcounter = 0; 
  break; 
  case 2: //song 2  
  songtimer = 250; 
  increment[oscCounter] = (int)((float)(poly1[songcounter])*IncAdjust); 
  while(poly1[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(poly1[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(poly1[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end  
   
   
  increment[oscCounter] = (int)((float)(poly2[songcounter])*IncAdjust); 
  while(poly2[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0;  
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
   
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(poly2[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(poly2[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end  
   
  /* increment[oscCounter] = (int)((float)(poly3[songcounter])*IncAdjust); 
  while(poly3[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
        
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(poly3[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(poly3[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end  
  */ 
  songcounter++; 
  if (poly1[songcounter] == 64000)demostate = off;  
  break; 
  case 3://song 3  
  songtimer = 250; 
  increment[oscCounter] = (int)((float)(row1[songcounter]/2)*IncAdjust); 
  while(row1[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(row1[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(row1[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end 
   
  increment[oscCounter] = (int)((float)(row2[songcounter])*IncAdjust); 
  while(row2[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
   
   
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(row2[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(row2[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end  
   
  increment[oscCounter] = (int)((float)(row3[songcounter]*2)*IncAdjust); 
  while(row3[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end 
   
  if((freqshiftstate != 0) && oscReady) 
  begin  
  increment[oscCounter] = (int)((float)(row3[songcounter])*shift[(signed int)(12 + freqshiftstate)]*IncAdjust); 
  while(row3[songcounter+restcounter + 1] == 0 ) 
  begin 
  restcounter++; 
  end 
  sustain[oscCounter] = songtimer*restcounter; 
  restcounter = 0; 
  time[oscCounter] = 0; 
  oscReady = oscReady & ~(0b00000001 << oscCounter);//turn off 
  while(~(oscReady | ~(0b00000001 << oscCounter))) 
  begin 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  if (oscReady == 0) break; 
  end  
  end  
   
  songcounter++; 
  if(row1[songcounter] == 64000) demostate = off; 
  break; 
  end  
  // sustain[oscCounter] = 500; 
  // oscCounter++; 
  /*  
  if (oscCounter > 7) oscCounter = 0; 
  increment[oscCounter] = (int)((float)(song[songcounter])*IncAdjust); 
  time[oscCounter] = 0;//25; 
  // sustain[oscCounter] = 250; 
  oscCounter++; 
  if (oscCounter > 7) oscCounter = 0; 
  increment[oscCounter] = (int)((float)(song[songcounter]*2)*IncAdjust); 
  time[oscCounter] = 0; 
  sustain[oscCounter] = 0; 
  */  
   
  // increment[1] = (int)((float)(song2[songcounter])*IncAdjust); 
  //increment[2] = (int)((float)(song3[songcounter]*2)*IncAdjust); 
  // increment2 = (int)((float)(song[songcounter]*2)*IncAdjust); 
  // increment2 = (int)((float)(song[songcounter])*IncAdjust); 
  // increment3 = (int)((float)(song[songcounter])*IncAdjust); 
       
       end 
           
           
           
       
        
       // if (time==34) TCCR0=0b00000001 ; 
       end // end while 
        end //end main 
      //*************************************************** 
        //Fast fixed multiply 
        //*************************************************** 
        int multfix(int a,int b) 
        begin 
  #asm 
  ;****************************************************************************** 
  ;* 
  ;* FUNCTION 
  ;* muls16x16_24 
  ;* DECRIPTION 
  ;* Signed multiply of two 16bits numbers with 24bits result. 
  ;* USAGE 
  ;* r31:r30:rxx = r23:r22 * r21:r20 
      ;****************************************************************************** 
  push r20 
  push r21 
   
  LDD R22,Y+2 ;load a 
  LDD R23,Y+3  
   
  LD R20,Y ;load b 
  LDD R21,Y+1 
   
  muls r23, r21 ; (signed)ah * (signed)bh 
  mov r31, r0 ;r18, r0 
  mul r22, r20 ; al * bl 
  mov r30, r1 ;movw r17:r16, r1:r0 
  ;mov r16, r0 
  mulsu r23, r20 ; (signed)ah * bl 
  add r30, r0 ;r17, r0 
  adc r31, r1 ;r18, r1 
  mulsu r21, r22 ; (signed)bh * al 
  add r30, r0 ;r17, r0 
  adc r31, r1 ;r18, r1 
   
  pop r21 
  pop r20 
  #endasm 
  end 
  /***************************************** 
  One Pole Lowpass filter 
  *****************************************/ 
  int OnePoleLow(int xx) 
  // xx is the current input signal sample 
  // returns the current filtered output sample 
  begin 
  #asm 
  .macro mult_acc ;r31:r30:r24 += r23:r22 * r21:r20 
  muls r23, r21 ; (signed)ah * (signed)bh 
  add r31, r0 
  mul r22, r20 ; al * bl 
  add r24, r0 
  adc r30, r1 
  adc r31, r27 
  mulsu r23, r20 ; (signed)ah * bl 
  add r30, r0 
  adc r31, r1 
  mulsu r21, r22 ; (signed)bh * al 
  add r30, r0 
  adc r31, r1 
  .endm  
   
  push r20 ;save parameter regs 
  push r21 
   
  clr r27 ;permanent zero 
  clr r24 ;clear 24 bit result reg; msb to lsb => r31:r30:r24 
   
  ld R30, Y ;load input parameter xx from stack 
  ldd R31, Y+1 ; and put in result location 
   
  lds R20, _yn_1 ;load y(n-1) from RAM 
  lds R21, _yn_1+1 
  sub r20, r30 ;form y(n-1) - xx 
  sbc r21, r31  
  lds R22, _alpha ;load alpha from RAM 
  lds R23, _alpha+1  
  mult_acc ; alpha*(yn_1 - xx)) + xx 
   
  sts _yn_1, r30 ;store new output as y(n-1) to RAM 
  sts _yn_1+1, r31  
   
  pop r21 ;restore parameter regs 
  pop r20 
   
  #endasm  
   
  end  
  /***************************************** 
  Two Pole Highpass filter 
  *****************************************/ 
  int Butter2high(int xx) 
  // xx is the current input signal sample 
  // returns the current filtered output sample 
  begin 
  #asm 
  .macro mult_acc ;r31:r30:r24 += r23:r22 * r21:r20 
  muls r23, r21 ; (signed)ah * (signed)bh 
  add r31, r0 
  mul r22, r20 ; al * bl 
  add r24, r0 
  adc r30, r1 
  adc r31, r27 
  mulsu r23, r20 ; (signed)ah * bl 
  add r30, r0 
  adc r31, r1 
  mulsu r21, r22 ; (signed)bh * al 
  add r30, r0 
  adc r31, r1 
  .endm  
  push r20 ;save parameter regs 
  push r21 
   
  clr r27 ;permanent zero 
  clr r24 ;clear 24 bit result reg; msb to lsb => r31:r30:r24 
  clr r30  
  clr r31 
   
  lds R22, _xn_1 ;load x(n-1) from RAM 
  lds R23, _xn_1+1 
  lsl r22 ;mult by two 
  rol r23 
  ld R20, Y ;load input parameter xx from stack 
  ldd R21, Y+1 
  sub r20, r22 ;form xx-2x(n-1) 
  sbc r21, r23  
  lds R22, _xn_2 ;load x(n-2) from RAM 
  lds R23, _xn_2+1 
  add r20, r22 ;form xx-2x(n-1)+x(n-2) 
  adc r21, r23  
  lds R22, _b1 ;load b1 from RAM 
  lds R23, _b1+1  
  mult_acc ; b1*(xx-2*x(n-1)+x(n-2))  
   
  lds R22, _a2 ;load -a2 from RAM 
  lds R23, _a2+1  
  lds R20, _yn_1 ;load y(n-1) from RAM 
  lds R21, _yn_1+1 
  mult_acc ; -a2*y(n-1)  
   
  lds R22, _a3 ;load -a3 from RAM 
  lds R23, _a3+1  
  lds R20, _yn_2 ;load y(n-2) from RAM 
  lds R21, _yn_2+1 
  mult_acc ; -a3*y(n-2) 
   
  lds R20, _xn_1 ;load x(n-1) from RAM 
  lds R21, _xn_1+1 
  sts _xn_2, r20 ;store x(n-2) to RAM 
  sts _xn_2+1, R21  
  ld R20, Y ;load input parameter xx from stack 
  ldd R21, Y+1 
  sts _xn_1, r20 ;store x(n-1) to RAM 
  sts _xn_1+1, R21  
  lds R20, _yn_1 ;load y(n-1) from RAM 
  lds R21, _yn_1+1 
  sts _yn_2, R20 ;store y(n-2) to RAM 
  sts _yn_2+1, R21  
  sts _yn_1, r30 ;store new output as y(n-1) to RAM 
  sts _yn_1+1, r31  
   
  pop r21 ;restore parameter regs 
  pop r20 
   
  #endasm  
   
  end  
      /***************************************** 
        Setting State Machine 
        Determine what settings are being changed 
        *****************************************/ 
        void setting_state_machine(void) 
        begin 
  settingstate_timer = 30; 
   
  if(~PIND.6) debounce0 = 0; 
  if(PIND.5) debounce1 = 0; 
  if(PIND.4) debounce2 = 0; 
  // if(!debounce0 && (~PIND.4 || ~PIND.5 || ~PIND.6)) 
  // debounce0 = 1;  
  switch(settingstate) 
  begin 
  case ADSR://Get ADSR 
  if(ADSRdisplay & 0x01) 
  begin 
  sprintf(lcd_buffer,"A:%04d",attack);  
  lcd_gotoxy(0,0); 
  lcd_puts(lcd_buffer);  
  ADSRdisplay = ADSRdisplay & ~(0x01); 
  end 
  if(ADSRdisplay & 0x02) 
  begin 
  sprintf(lcd_buffer,"D:%04d",decay);  
  lcd_gotoxy(10,0); 
  lcd_puts(lcd_buffer); 
  ADSRdisplay = ADSRdisplay & ~(0x02); 
  end  
  if(ADSRdisplay & 0x04) 
  begin 
  sprintf(lcd_buffer,"S:.%01d",sustainamp_ten_int);  
  lcd_gotoxy(0,1); 
  lcd_puts(lcd_buffer); 
  ADSRdisplay = ADSRdisplay & ~(0x04); 
  end  
  if(ADSRdisplay & 0x08) 
  begin 
  sprintf(lcd_buffer,"R:%04d", release);  
  lcd_gotoxy(10,1); 
  lcd_puts(lcd_buffer); 
  ADSRdisplay = ADSRdisplay & ~(0x08);  
  end  
  //transition 
  if(!debounce0 && (PIND.6)) 
  begin 
  settingstate = osc1; 
  debounce0 = 1; 
  lcd_clear(); 
  lcd_gotoxy(0,0);  
  lcd_putsf("Oscillator 1:"); 
  PrintWaveType(oscstate[0]); 
  end 
  break; 
       case osc1: 
  if(!debounce1 && (~PIND.5)) 
  begin 
  debounce1 = 1; 
  switch(oscstate[0]) 
  begin 
  case off: 
  oscstate[0] = sinewave; 
  break; 
  case sinewave: 
  oscstate[0] = triwave; 
  break; 
  case triwave: 
  oscstate[0] = squarewave; 
  break; 
  case squarewave: 
  oscstate[0] = sawwave; 
  break; 
  case sawwave: 
  oscstate[0] = off; 
  break; 
  end 
  PrintWaveType(oscstate[0]); 
  updatewave(); 
  end 
  //transition  
  if(!debounce0 && (PIND.6)) 
  begin 
  settingstate = osc2; 
  debounce0 = 1; 
  lcd_clear(); 
  lcd_gotoxy(0,0);  
  lcd_putsf("Oscillator 2:"); 
  PrintWaveType(oscstate[1]); 
   
  end 
       break; 
  case osc2: 
  if(!debounce1 && (~PIND.5)) 
  begin 
  debounce1 = 1; 
  switch(oscstate[1]) 
  begin 
  case off: 
  oscstate[1] = sinewave; 
  break; 
  case sinewave: 
  oscstate[1] = triwave; 
  break; 
  case triwave: 
  oscstate[1] = squarewave; 
  break; 
  case squarewave: 
  oscstate[1] = sawwave; 
  break; 
  case sawwave: 
  oscstate[1] = off; 
  break; 
  end 
  PrintWaveType(oscstate[1]); 
  updatewave(); 
  end 
  //transition  
  if(!debounce0 && (PIND.6)) 
  begin 
  settingstate = operator; 
  debounce0 = 1; 
  lcd_clear(); 
  lcd_gotoxy(0,0);  
  lcd_putsf("Operator:"); 
  PrintOperatorType(operatorstate); 
  end 
  break; 
   
  case operator: 
  if(!debounce1 && (~PIND.5)) 
  begin 
  debounce1 = 1; 
  switch(operatorstate) 
  begin 
  case off: 
  operatorstate = add; 
  break; 
  case add: 
  operatorstate = subtract; 
  break; 
  case subtract: 
  operatorstate = multiply; 
  break; 
  case multiply: 
  operatorstate = off; 
  break; 
  end 
  PrintOperatorType(operatorstate); 
  updatewave(); 
  end 
  //transition  
  if(!debounce0 && (PIND.6)) 
  begin 
  settingstate = special; 
  debounce0 = 1; 
  lcd_clear(); 
  lcd_gotoxy(0,0);  
  lcd_putsf("Special Functs:"); 
  PrintSpecialType(specialstate); 
  end 
  break; 
  case special: 
       switch(specialstate) 
  begin 
  case demo: 
  if(!debounce2 && (~PIND.4)) 
  begin 
  debounce2 = 1; 
  demostate++; 
  songcounter = 0; 
  if (demostate>3) demostate = 0; 
  if(!demostate) 
  begin 
  lcd_gotoxy(10,1); 
  lcd_putsf("Off"); 
  end  
  else 
  begin 
  sprintf(lcd_buffer,"%d ",demostate);  
  lcd_gotoxy(10,1); 
  lcd_puts(lcd_buffer); 
  end  
  end 
       //transition  
  if(!debounce1 && (~PIND.5)) 
  begin 
  debounce1 = 1; 
  specialstate = freqshift; 
  PrintSpecialType(specialstate); 
  end 
  break; 
       case freqshift: 
  if(!debounce2 && (~PIND.4)) 
  begin 
  debounce2 = 1; 
  freqshiftstate++; 
  if (freqshiftstate>12) freqshiftstate = -12;  
  sprintf(lcd_buffer,"%d ",freqshiftstate);  
  lcd_gotoxy(11,1); 
  lcd_puts(lcd_buffer);  
  end 
  //transition 
  if(!debounce1 && (~PIND.5)) 
  begin 
  debounce1 = 1; 
  specialstate = filter; 
  PrintSpecialType(specialstate); 
  end 
  break; 
  case filter: 
  if(!debounce2 && (~PIND.4)) 
  begin 
  debounce2 = 1; 
  switch(filterstate) 
  begin 
  case off: 
  filterstate = highpass; 
  lcd_gotoxy(7,1);  
  lcd_putsf("High "); 
  break; 
  case highpass: 
  filterstate = lowpass; 
  lcd_gotoxy(7,1);  
  lcd_putsf("Low ");  
  break; 
  case lowpass: 
  filterstate = off; 
  lcd_gotoxy(7,1);  
  lcd_putsf("Off "); 
  break;  
  end 
  end 
  //transition 
  if(!debounce1 && (~PIND.5)) 
  begin 
  debounce1 = 1; 
  specialstate = demo; 
  PrintSpecialType(specialstate); 
  end 
  break; 
  end 
  //transition  
  if(!debounce0 && (PIND.6)) 
  begin 
  settingstate = ADSR; 
  debounce0 = 1; 
  ADSRdisplay = 0x0F; 
  lcd_clear(); 
  end 
       break; 
  end 
  end 
      /***************************************** 
        Wave State Machine 
        Determine the wave type used 
        *****************************************/ 
        /* 
        void wave_state_machine(void) 
        begin 
  wavestate_timer = 50; 
  switch(wavestate) 
  begin 
  case wait: 
  //if(~PINB.7) 
  if(0) 
  begin 
  wavetype[0]++; 
  if (wavetype[0] > 4) wavetype[0] = 0; 
  wavestate = updatewave; 
  end 
       // if(~PINB.6) 
  if(0) 
  begin 
  wavetype[1]++; 
  if (wavetype[1] > 4) wavetype[1] = 0; 
  wavestate = updatewave; 
  end 
       //if(~PINB.5) 
  if(0) 
   
  begin 
  operatortype++; 
  if (operatortype > 3) operatortype = 0; 
  wavestate = updatewave; 
  end 
   
  // if(~PINB.4) 
  if(0) 
   
  begin 
  if(filterflag) filterflag = 0; 
  else filterflag = 1; 
  wavestate = updatewave; 
  end 
   
  break; 
  case  
  */  
  void updatewave(void) 
  begin 
  for(ii = 0; ii<256; ii++) 
  begin 
  for (j = 0; j<2; j++) 
  begin 
  switch (oscstate[j]) 
  begin 
  case off: 
  tempwave[j] = 0; 
  break; 
  case sinewave: 
  tempwave[j] = sineTable[ii]; 
  break; 
  case triwave: 
  if(ii<128) 
  begin 
  tempwave[j] = float2fix((float)(2*ii-127)/8);//float2fix(2*(float)ii*(float)16/(float)255-16); 
  end 
  else 
  begin 
  tempwave[j] = float2fix((float)(384-2*ii-1)/8);//float2fix(48-2*(float)ii*(float)16/(float)255-1); 
  end 
  // tempwave[j] = triTable[ii]; 
  break; 
  case squarewave:  
  if(ii<128) 
  begin 
  tempwave[j] = int2fix(-16); 
  end 
  else 
  begin 
  tempwave[j] = int2fix(16);  
  end 
  //tempwave[j] = squareTable[ii]; 
  break; 
  case sawwave: 
  tempwave[j] = float2fix(32*(float)ii/255 - 16); 
  break;  
  end 
  end 
   
  switch(operatorstate) 
  begin 
  case off: 
  finalwave[ii]= tempwave[0]; 
  break; 
  case add: 
  finalwave[ii]= multfix((tempwave[0] + tempwave[1]),float2fix(.5)); 
  break; 
  case subtract: 
  finalwave[ii]= multfix((tempwave[0] - tempwave[1]),float2fix(.5)); 
  break; 
  case multiply: 
  finalwave[ii]= multfix((multfix(tempwave[0], tempwave[1])),float2fix(.1)); 
  break; 
  end 
  end 
       
      end 
      /***************************************** 
        PrintsSpecialType(char) 
        Prints out Special Func to LCD 
        *****************************************/ 
        void PrintSpecialType(char specialstate) 
        begin 
  switch(specialstate) 
  begin 
  case demo: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Song Demo: "); 
  if(!demostate) 
  begin 
  lcd_gotoxy(10,1); 
  lcd_putsf("Off"); 
  end  
  else 
  begin 
  sprintf(lcd_buffer,"%d ",demostate);  
  lcd_gotoxy(10,1); 
  lcd_puts(lcd_buffer); 
  end  
  break; 
  case freqshift: 
   
  sprintf(lcd_buffer,"Tone shift:%d ",freqshiftstate);  
  lcd_gotoxy(0,1);  
  lcd_puts(lcd_buffer); 
  break;  
  case filter: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Filter: "); 
  switch(filterstate) 
  begin 
  case off: 
  lcd_gotoxy(7,1);  
  lcd_putsf("Off "); 
  break; 
  case highpass: 
  lcd_gotoxy(7,1);  
  lcd_putsf("High "); 
  break; 
  case lowpass: 
  lcd_gotoxy(7,1);  
  lcd_putsf("Low "); 
  break;  
  end 
  break; 
  end 
  end 
  /***************************************** 
  PrintsWaveType(char) 
  Prints out Wave Type to LCD 
  *****************************************/ 
  void PrintWaveType(char oscstate) 
  begin 
  switch(oscstate) 
  begin 
  case off: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Off "); 
  break; 
  case sinewave: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Sine Wave "); 
  break;  
  case triwave: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Triangle Wave "); 
  break; 
  case squarewave: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Square Wave "); 
  break; 
  case sawwave: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Saw Tooth Wave"); 
  break; 
  end 
  end 
  /***************************************** 
  PrintsOperatorType(char) 
  Prints out Operator Type to LCD 
  *****************************************/ 
  void PrintOperatorType(char operatorstate) 
  begin 
  switch(operatorstate) 
  begin 
  case off: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Off "); 
  break; 
  case add: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Addition "); 
  break;  
  case subtract: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Subtraction "); 
  break; 
  case multiply: 
  lcd_gotoxy(0,1);  
  lcd_putsf("Multiplication"); 
  break; 
  end 
  end 
  /***************************************** 
  Envelope State Machine 
  Determine attack, decay, sustain and release time 
  *****************************************/ 
  void envelope_state_machine(void) 
  begin 
  envelopestate_timer = 50; 
  switch(envelopestate) 
  begin 
  case getAttack: 
  attack = (unsigned int)((float)ADCH*1000/255 + 10); 
  if(abs(attack_old - attack) > 8) ADSRdisplay = ADSRdisplay | 0x01; 
  attack_old = attack; 
  ADMUX = 0b01100001; 
  envelopestate = getDecay; 
  break; 
       case getDecay: 
  decay = (int)((float)ADCH*1000/255 + (10*(1 - sustainamp_float))); 
  if(abs(decay_old - decay) > 8 ) ADSRdisplay = ADSRdisplay | 0x02; 
  decay_old = decay; 
       ADMUX = 0b01100010; 
  envelopestate = getSustain; 
  break; 
  case getSustain: 
  sustainamp_ten_int = (unsigned int)(1 + (float)ADCH*8/255); 
  if(sustain_old != sustainamp_ten_int) ADSRdisplay = ADSRdisplay | 0x04; 
  sustain_old = sustainamp_ten_int; 
   
  sustainamp_fix = float2fix((float)(.1*((float)sustainamp_ten_int))); 
  sustainamp_float = .1*((float)sustainamp_ten_int); 
   
  ADMUX = 0b01100011; 
  envelopestate = getRelease; 
  break; 
  case getRelease: 
  release = (unsigned int)((float)ADCH*2000/255 + (float)(sustainamp_ten_int));  
  if(abs(release_old - release) > 8) ADSRdisplay = ADSRdisplay | 0x08; 
  release_old = release; 
       ADMUX = 0b01100000; 
  envelopestate = getAttack; 
  break; 
  end 
  ADCSR.6=1; 
  end 
      //********************************************************** 
        //initialization 
        void initialize(void) 
        begin 
  DDRB=0xff; 
       //init 
        // DDRB=0xff; //PORTB.0 
  // DDRC=0xff; // PORT C is an out for LCD 
  //DDRC=0x00; // PORT D is an input for switches 
  DDRC=0x00; // PORT C is an input for switches 
  //PORTC = 0x00; 
       
       //UART Recieve from midi keyboard 
  UCSRB = 0b10010000; 
  UBRRL = 31; 
       
       //fast PWM mode, full clock rate, toggle oc0 (pin B3) 
  //16 microsec per PWM cycle implies max freq for 16 samples of 
  // 1/(16e-6*16) = 3900 Hz. 
  //TCCR0 = 0b01101001 ; 
  //turn on timer 0 overflow ISR 
  TIMSK = 0b00010000 ; 
  OCR1A = 256; //set the compare re to 250 time ticks 
  //prescalar to 64 and turn on clear-on-match 
  TCCR0 = 0b01101001 ; 
  TCCR1A=0b00000000; 
  TCCR1B=0b00001010; 
       //init the A to D converter 
  //channel zero/ left adj /EXTERNAL Aref 
  //!!!CONNECT Aref jumper!!!! 
  ADMUX = 0b00100000; 
  //enable ADC and set prescaler to 1/128*16MHz=125,000 
  //and clear interupt enable 
  //and start a conversion 
  ADCSR = 0b11000111; 
       
       //init the wave tables 
  for (i=0; i<256; i++) 
  begin 
  sineTable[i] = float2fix((16.0 * sin(6.283*((float)i)/256.0))) ; 
  // finalwave[i] = (char)(32.0 * sin(6.283*((float)i)/256.0)) ; 
  /* 
  if(i<128) 
  begin 
  // squareTable[i] = -127; 
  //triTable[i] = 2*i-127; 
  end 
  else 
  begin 
  //squareTable[i] = 127; 
  //triTable[i] = 384-2*i-1; 
  end 
  */ 
  end 
        
  //init variables 
  //init the DDS phase increment and filter variables 
  for (i = 0; i < oscNUM; i++) 
  begin 
  accumulator[i]= 0; 
  increment[i] = 0; 
  time[i]=0; 
  yn_temp[i] = 0; 
  amp[i] = 0; 
  end 
  // increment[0] = (int)((float)song[songcounter]*IncAdjust); 
  // increment[1] = (int)((float)song2[songcounter]*IncAdjust); 
  // increment[2] = (int)((float)song3[songcounter]*IncAdjust); 
  // increment2 = (int)((float)song[songcounter]*2*IncAdjust); 
  // increment2 = (int)((float)(song2[songcounter])*IncAdjust); 
  // increment3 = (int)((float)(song3[songcounter])*IncAdjust); 
  //increment = (int)((float)C*IncAdjust); 
  //increment2 = (int)((float)E*IncAdjust); 
  //songcounter++; 
       //init notes and oscillator variables 
  for( ii = 0; ii<keysize; ii++) 
  begin 
  Held[ii] = 9; 
  end 
  oscstate[0] = 1; 
  oscCounter = 0; 
  oscReady = 0b11111111; 
  filterflag = 0; 
       //initial states  
  settingstate = ADSR; 
  envelopestate = getAttack; 
  ADSRdisplay = 0x0f; 
  demostate =0; 
  updatewave(); 
       //1-pole RC lowpass, cutoff=0.0424 (1/4 Nyquist freq), gain=1  
  alpha = float2fix(0.390) ; 
   
  //2-pole butterworth highpass, cutoff=0.25 
  b1 = float2fix(0.569) ;  
  a2 = float2fix(0.943) ; //note that sign is negated from design input 
  a3 = float2fix(-.333) ; //note that sign is negated from design input 
   
  //LCD init 
  lcd_init(16); 
  lcd_clear(); //clear the display 
       #asm 
  sei 
  #endasm 
      end 
     |