PCM Digital Synthesizer

Dependencies:   LCD mbed

/media/uploads/p_igmon/img_1731-w480.jpg

envelope_work.cpp

Committer:
p_igmon
Date:
2016-09-02
Revision:
0:ad6637c36dc7

File content as of revision 0:ad6637c36dc7:

#include "synthesizer.h"

extern GENERATOR sgen[];
extern GENERATOR dgen[];
extern GENERATOR_TEMP dgen_temp[];
extern GENERATOR *gen ;// = &sgen[PresetVoiceNum - 1] set by Menu PresetVoice
extern GENERATOR *pgen;// = &dgen[0]; 
extern GENERATOR_TEMP *pgen_temp;//  = &dgen_temp[0]; 
extern PresetVoiceDef PresetVoice[];
extern STR_VOICE voice[];

extern int gen_encount;
extern U8 PresetVoiceNum;
extern U8 MidiChannel;

extern S16 MasterVolume;
extern volatile S16 mvoldiv;

void envelope_work(void)
{
    U8 i;
    U16 temp;
    U8 temp1,temp2;
    S16 *lfo1wave;
    GENERATOR *gena;
    GENERATOR_TEMP *gena_temp;
    STR_VOICE *voicea;
    gena = pgen;// 螳滉ス薙・縺サ縺・〒
    gena_temp = pgen_temp;// 螳滉ス薙・縺サ縺・〒
    voicea = &voice[0]; 
    PresetVoiceDef *voice_ptr = (PresetVoiceDef *)&PresetVoice[PresetVoiceNum- 1];
    MasterVolume += mvoldiv;
    if(MasterVolume >(127<<8)){
        MasterVolume = 127<<8;
        mvoldiv = 0;
    }else if(MasterVolume < 0){
        MasterVolume = 0;
        mvoldiv = 0;
    }
    
    for (i =0;i<GENMAX;i++){
        if(gena_temp->status == GEN_IDLE){
//          gena_temp->voltemp = 0;
            gena_temp->lfo1delaycount = gena->lfo1delaytime;
            gena_temp->lfo2delaycount = gena->lfo2delaytime;
#ifdef DCF
            voicea->enable &= ~(1<<(i & (PRGGENMAX - 1)));// 1,2,4,8
#endif            
        }else{
            if(gena_temp->status == GEN_NOTEOFF){
                /* Function Release */
                gena_temp->voltemp = (gena_temp->voltemp>>16) * releasetime_table[gena->releasetime];
                if(gena_temp->voltemp == 0){
                    gena_temp->zerocount++;
                }else{
                    gena_temp->zerocount = 0;
                }                   
                if(gena_temp->zerocount > 10){
                    gena_temp->status = GEN_IDLE;
                    gena_temp->eg_status = EG_IDLE;
#ifdef DCF
                    voicea->enable &= ~(1<<(i & (PRGGENMAX - 1)));// 1,2,4,8
#endif
                    gen_encount--;
                    //ledgreen_off();
                }else{
                    gena_temp->eg_status = EG_RELEASE;
                    //ledred_off();
                }
                
            }else{ // NOTE ON
                if(gena_temp->eg_status == EG_IDLE){
                    gena_temp->voltemp += gena_temp->voltemp1;
                    //ledred_on();
                    if(gena_temp->voltemp > gena->volume <<16){
                        gena_temp->voltemp = gena->volume <<16;
                        gena_temp->voltemp1 = ((gena->volume<<16) /100 * (100 - gena->sustainlevel))/(gena->decaytime);
                        gena_temp->eg_status = EG_DECAY;
                    }else{
                        gena_temp->eg_status = EG_ATTACK;
                    }
                }else if(gena_temp->eg_status == EG_ATTACK){
                    gena_temp->voltemp += gena_temp->voltemp1;
                    //ledred_on();
                    if(gena_temp->voltemp > gena->volume <<16){
                        gena_temp->voltemp = gena->volume <<16;
                        gena_temp->voltemp1 = ((gena->volume<<16) /100 * (100 - gena->sustainlevel))/(gena->decaytime);
                        gena_temp->eg_status = EG_DECAY;
                    }
                }else if(gena_temp->eg_status == EG_DECAY){
                    gena_temp->voltemp -= gena_temp->voltemp1;
                    if(gena_temp->voltemp < gena_temp->voltemp2){
                        gena_temp->voltemp = gena_temp->voltemp2;
                        gena_temp->eg_status = EG_SUSTAIN;

                        //ledgreen_on();
                    }

                }

            }
            /* Note On/Off蜈ア騾壹・蜃ヲ逅・*/
            if (gena_temp->dpf != 0){ // 110812
                gena_temp->df += (S32)gena_temp->dpf;//
            }

            /* PitchBend 120617 */
//          gena->bendvalue = ((((ADC.ADDRA.WORD>>6) - adc0bias) * gena->benddepth) >>10);// ADDR 縺ョ繝薙ャ繝・5・・縺後ョ繝シ繧ソ
//          gena->bendvalue = ((gena->df>>26) * gena->bendvalue )>>2;

#ifdef BEND
            gena_temp->xx = (((U32)gena_temp->df>>16) + (S16)gena->detune + gena->lfo1value + gena->bendvalue);
#else
            gena_temp->xx = (((U32)gena_temp->df>>16) + (S32)gena->detune + gena_temp->lfo1value);
#endif

#if 1
            /* Function LFO1 */
            if(gena_temp->lfo1delaycount > 0){
                gena_temp->lfo1delaycount--;    
            }else{
                /* lof1speed 3e.5f */
                gena_temp->lfo1count += (U8)gena->lfo1speed ;
                if (gena_temp->lfo1count >= (256<<5)) gena_temp->lfo1count -=(256<<5);
//              gena_temp->lfo1value = ((S16)sin_table[(gena_temp->lfo1count>>5)] * (U16)gena->lfo1depth) >>20;
                switch(gena->lfo1type){
                    case 0:
                        lfo1wave = sin_table;
                        break;        
                    case 1:
                        lfo1wave = saw1_table;
                        break;        
                    case 2:
                        lfo1wave = saw2_table;
                        break;        
                    case 3:
                        lfo1wave = tri_table;
                        break;        
                    case 4:
                        lfo1wave = square_table;
                        break;        
                }
              
//                gena_temp->lfo1value = ((S16)lfo1wave[(gena_temp->lfo1count>>5)] * (U16)gena->lfo1depth) >>20;
//                gena_temp->lfo1value = ((gena_temp->df>>26) * gena_temp->lfo1value)<<4;// 140614
                gena_temp->lfo1value = ((S16)lfo1wave[(gena_temp->lfo1count>>5)] * (U16)gena->lfo1depth) >>10;//140617
                gena_temp->lfo1value = ((gena_temp->df>>16) * (gena_temp->lfo1value>>4))>>12;// 140617
            }
#endif
            gena_temp->voltempL = (((U32)gena_temp->voltemp>>7) * (U8)gena_temp->velocity) >>16;
#if 1
            /* Function LFO2 */
            if(gena_temp->lfo2delaycount > 0){
                gena_temp->lfo2delaycount--;    
            }else{
                /* lof2speed 3e.5f */
                gena_temp->lfo2count += (U8)gena->lfo2speed ;
                if (gena_temp->lfo2count >= (256<<5)) gena_temp->lfo2count -=(256<<5);
//                temp = (U16)(( (U16)sin_table2[((U16)gena_temp->lfo2count>>5)] * (U16)gena->lfo2depth) >>16);
//                gena_temp->voltempL += (gena_temp->voltempL * temp) >>15;
                temp = (U16)(( (U16)sin_table2[((U16)gena_temp->lfo2count>>5)] * (U16)gena->lfo2depth) >>10);// 140618
                gena_temp->voltempL += (gena_temp->voltempL * temp) >>11;// 140618

            }   
#endif
        /* GEN_NOTEONOFF END */
        }
#ifdef DCF
        /* Voice Process */
        if ((i & (PRGGENMAX - 1)) == 0){

            temp1 = voice_ptr->dcf_freq +((30 - voice_ptr->dcf_freq)*((S16)gena_temp->voltempL * (voice_ptr->dcf_freqsence))>>16);
            if (temp1 > 30) temp1 = 30;     
            temp2 = voice_ptr->dcf_q +((10 - voice_ptr->dcf_q)*((S16)gena_temp->voltempL * (voice_ptr->dcf_qsence))>>16);
            if (temp2 > 10) temp2 = 10;      

            voicea->dcf_param = (S32 *)&dcf_table[temp1 * 11 + temp2][0];

        }   
#endif
        gena++;
        gena_temp++;
#ifdef DCF
        if ((i & (PRGGENMAX - 1))== (PRGGENMAX - 1)) voicea++;
#endif
    }
}