PCM Digital Synthesizer

Dependencies:   LCD mbed

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

Revision:
0:ad6637c36dc7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/envelope_work.cpp	Fri Sep 02 13:24:16 2016 +0000
@@ -0,0 +1,188 @@
+#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
+    }
+}
+