PCM Digital Synthesizer

Dependencies:   LCD mbed

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

Committer:
p_igmon
Date:
Fri Sep 02 13:24:16 2016 +0000
Revision:
0:ad6637c36dc7
for Micro Gen4 Synthesizer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
p_igmon 0:ad6637c36dc7 1 /**********************************************************************
p_igmon 0:ad6637c36dc7 2
p_igmon 0:ad6637c36dc7 3
p_igmon 0:ad6637c36dc7 4 ***********************************************************************/
p_igmon 0:ad6637c36dc7 5
p_igmon 0:ad6637c36dc7 6 #include "synthesizer.h"
p_igmon 0:ad6637c36dc7 7
p_igmon 0:ad6637c36dc7 8 #ifdef DCF
p_igmon 0:ad6637c36dc7 9 __asm S16 dcf64(S32 *param ,S32 *signal){
p_igmon 0:ad6637c36dc7 10
p_igmon 0:ad6637c36dc7 11 PUSH {R4-R7}
p_igmon 0:ad6637c36dc7 12 LDR r2,[r0 , #0]; param a0
p_igmon 0:ad6637c36dc7 13 LDR r3,[r1 , #0]; signal 0
p_igmon 0:ad6637c36dc7 14 SMULL r4,r5,r2,r3
p_igmon 0:ad6637c36dc7 15
p_igmon 0:ad6637c36dc7 16 LDR r6,[r0 , #4]; a1
p_igmon 0:ad6637c36dc7 17 LDR r7,[r1 , #4]; x1
p_igmon 0:ad6637c36dc7 18 SMLAL r4,r5,r6,r7; Top r5 Bottom r4
p_igmon 0:ad6637c36dc7 19 LDR r2,[r0 , #8]; b0
p_igmon 0:ad6637c36dc7 20 LDR r3,[r1 , #8]; x2
p_igmon 0:ad6637c36dc7 21 SMLAL r4,r5,r2,r3
p_igmon 0:ad6637c36dc7 22 LDR r6,[r0 , #12]; b1
p_igmon 0:ad6637c36dc7 23 LDR r7,[r1 , #12]; y1
p_igmon 0:ad6637c36dc7 24 SMLAL r4,r5,r6,r7
p_igmon 0:ad6637c36dc7 25 LDR r2,[r0 , #16]; b2
p_igmon 0:ad6637c36dc7 26 LDR r3,[r1 , #16]; y2
p_igmon 0:ad6637c36dc7 27 SMLAL r4,r5,r2,r3
p_igmon 0:ad6637c36dc7 28
p_igmon 0:ad6637c36dc7 29 MOV r0,r1; r0 = r1 signal
p_igmon 0:ad6637c36dc7 30 ADDS r4 ,r4, r4 ; add the least significant words
p_igmon 0:ad6637c36dc7 31 ADCS r5 ,r5, r5 ; add the most significant words with carry
p_igmon 0:ad6637c36dc7 32 ADDS r4, r4, r4 ; add the least significant words
p_igmon 0:ad6637c36dc7 33 ADCS r5, r5, r5 ; add the most significant words with carry
p_igmon 0:ad6637c36dc7 34
p_igmon 0:ad6637c36dc7 35 LDR r6,[r1, #12]; dcf_y1
p_igmon 0:ad6637c36dc7 36 LDR r3,[r0, #4]; dcf_x1
p_igmon 0:ad6637c36dc7 37 STR r6,[r1, #16]; dcf_y2 = dcf_y1
p_igmon 0:ad6637c36dc7 38 STR r3,[r0, #8]; dcf_x2 = dcf_x1
p_igmon 0:ad6637c36dc7 39 LDR r4,[r1, #0]; sample
p_igmon 0:ad6637c36dc7 40 STR r5,[r0, #12]; dcf_y1 = result
p_igmon 0:ad6637c36dc7 41 STR r4,[r1 ,#4]; dcf_x1 = sample
p_igmon 0:ad6637c36dc7 42
p_igmon 0:ad6637c36dc7 43 ASR r0,r5,#16; r0 = r5 >>16
p_igmon 0:ad6637c36dc7 44 POP {R4-R7}
p_igmon 0:ad6637c36dc7 45 BX LR
p_igmon 0:ad6637c36dc7 46 ; ENDP
p_igmon 0:ad6637c36dc7 47
p_igmon 0:ad6637c36dc7 48 ALIGN
p_igmon 0:ad6637c36dc7 49 ; END
p_igmon 0:ad6637c36dc7 50 }
p_igmon 0:ad6637c36dc7 51 #endif
p_igmon 0:ad6637c36dc7 52
p_igmon 0:ad6637c36dc7 53 __asm S16 satAdd16(S16 val1 ,S16 val2){
p_igmon 0:ad6637c36dc7 54 QADD16 r0,r0,r1
p_igmon 0:ad6637c36dc7 55
p_igmon 0:ad6637c36dc7 56 BX LR
p_igmon 0:ad6637c36dc7 57 ; ENDP
p_igmon 0:ad6637c36dc7 58
p_igmon 0:ad6637c36dc7 59 ALIGN
p_igmon 0:ad6637c36dc7 60 ; END
p_igmon 0:ad6637c36dc7 61 }
p_igmon 0:ad6637c36dc7 62
p_igmon 0:ad6637c36dc7 63 __asm S32 satAdd32(S32 val1 ,S32 val2){
p_igmon 0:ad6637c36dc7 64 QADD r0,r0,r1
p_igmon 0:ad6637c36dc7 65
p_igmon 0:ad6637c36dc7 66 BX LR
p_igmon 0:ad6637c36dc7 67 ENDP
p_igmon 0:ad6637c36dc7 68
p_igmon 0:ad6637c36dc7 69 ALIGN
p_igmon 0:ad6637c36dc7 70 END
p_igmon 0:ad6637c36dc7 71 }
p_igmon 0:ad6637c36dc7 72
p_igmon 0:ad6637c36dc7 73 int gen_encount;
p_igmon 0:ad6637c36dc7 74
p_igmon 0:ad6637c36dc7 75 extern DigitalOut generating;
p_igmon 0:ad6637c36dc7 76 #define GENERATE_ON generating=1;
p_igmon 0:ad6637c36dc7 77 #define GENERATE_OFF generating=0;
p_igmon 0:ad6637c36dc7 78
p_igmon 0:ad6637c36dc7 79 S16 limit;
p_igmon 0:ad6637c36dc7 80
p_igmon 0:ad6637c36dc7 81 /* DMA WAVE BUFFER */
p_igmon 0:ad6637c36dc7 82 extern S16 DMA_Buffer[];
p_igmon 0:ad6637c36dc7 83 extern __IO BUFFER_StateTypeDef BufferOffset;
p_igmon 0:ad6637c36dc7 84
p_igmon 0:ad6637c36dc7 85 extern U8 midi_base_ch ;
p_igmon 0:ad6637c36dc7 86 volatile U8 midi_note_ch ;
p_igmon 0:ad6637c36dc7 87 volatile U8 midi_prog_ch ;
p_igmon 0:ad6637c36dc7 88
p_igmon 0:ad6637c36dc7 89 volatile U8 samplecount = 0;
p_igmon 0:ad6637c36dc7 90 extern S8 MasterTune;// -128 - +127
p_igmon 0:ad6637c36dc7 91 volatile int portament;
p_igmon 0:ad6637c36dc7 92 S16 MasterVolume = 127<<8;// max 127<<8
p_igmon 0:ad6637c36dc7 93 volatile S16 mvoldiv = 0;
p_igmon 0:ad6637c36dc7 94
p_igmon 0:ad6637c36dc7 95 extern STR_VOICE voice[];
p_igmon 0:ad6637c36dc7 96
p_igmon 0:ad6637c36dc7 97 //static _UWORD df_table[] ={24883,26363,27930,29591,31351,33215,35190,37282,39499,41848,44336,46973};// 44.1k 440Hz@A4 1404029
p_igmon 0:ad6637c36dc7 98 static U16 df_table[] ={24996,26482,28057,29725,31493,33366,35350,37452,39679,42038,44538,47186};// 44.1k 442Hz@A4
p_igmon 0:ad6637c36dc7 99
p_igmon 0:ad6637c36dc7 100 static U16 k[16] ={65535,61439,57343,53247,49151,45055,40959,36863,32767,28671,24575,20479,16383,12287,8191,4095};// 121009
p_igmon 0:ad6637c36dc7 101
p_igmon 0:ad6637c36dc7 102 #ifdef REVERVE16BIT
p_igmon 0:ad6637c36dc7 103 S16 reverve_buf[22000];
p_igmon 0:ad6637c36dc7 104 S16 *reverve_wtemp;
p_igmon 0:ad6637c36dc7 105 #else
p_igmon 0:ad6637c36dc7 106 S8 reverve_buf[44000];
p_igmon 0:ad6637c36dc7 107 S8 *reverve_wtemp;
p_igmon 0:ad6637c36dc7 108 #endif
p_igmon 0:ad6637c36dc7 109
p_igmon 0:ad6637c36dc7 110 extern volatile int TimerCount10mS ;
p_igmon 0:ad6637c36dc7 111 extern volatile int KeyValDiv;
p_igmon 0:ad6637c36dc7 112
p_igmon 0:ad6637c36dc7 113 extern GENERATOR sgen[];
p_igmon 0:ad6637c36dc7 114 extern GENERATOR dgen[];
p_igmon 0:ad6637c36dc7 115 extern GENERATOR_TEMP dgen_temp[];
p_igmon 0:ad6637c36dc7 116 extern GENERATOR *gen ;// = &sgen[(PresetVoiceNum - 1)*PRGGENMAX] set by Menu PresetVoice
p_igmon 0:ad6637c36dc7 117 extern GENERATOR *pgen;// = &dgen[0];
p_igmon 0:ad6637c36dc7 118 extern GENERATOR_TEMP *pgen_temp;// = &dgen_temp[0];
p_igmon 0:ad6637c36dc7 119 extern WaveDef Wave[];
p_igmon 0:ad6637c36dc7 120
p_igmon 0:ad6637c36dc7 121 extern U8 PresetVoiceNum;
p_igmon 0:ad6637c36dc7 122 extern U8 MidiChannel;;
p_igmon 0:ad6637c36dc7 123 extern S8 MasterTune;;
p_igmon 0:ad6637c36dc7 124 extern int rch_pol;
p_igmon 0:ad6637c36dc7 125
p_igmon 0:ad6637c36dc7 126 void init_voice(void){
p_igmon 0:ad6637c36dc7 127 #ifdef DCF
p_igmon 0:ad6637c36dc7 128 int i;
p_igmon 0:ad6637c36dc7 129 GENERATOR *gena;
p_igmon 0:ad6637c36dc7 130 GENERATOR_TEMP *gena_temp;
p_igmon 0:ad6637c36dc7 131 STR_VOICE *voicea;
p_igmon 0:ad6637c36dc7 132 gena = pgen;
p_igmon 0:ad6637c36dc7 133 gena_temp = pgen_temp;
p_igmon 0:ad6637c36dc7 134 voicea = &voice[0];
p_igmon 0:ad6637c36dc7 135 for (i=0;i<VOICEMAX;i++){
p_igmon 0:ad6637c36dc7 136 voicea->enable = 0;
p_igmon 0:ad6637c36dc7 137 voicea->signal[0] = voicea->signal[1] = voicea->signal[2] = voicea->signal[3] = voicea->signal[4] = voicea->signal[5] = 0;
p_igmon 0:ad6637c36dc7 138 voicea->gen = gena;
p_igmon 0:ad6637c36dc7 139 voicea->gen_temp = gena_temp;
p_igmon 0:ad6637c36dc7 140 gena += PRGGENMAX;
p_igmon 0:ad6637c36dc7 141 gena_temp += PRGGENMAX;
p_igmon 0:ad6637c36dc7 142 voicea++;
p_igmon 0:ad6637c36dc7 143 }
p_igmon 0:ad6637c36dc7 144 #endif
p_igmon 0:ad6637c36dc7 145 }
p_igmon 0:ad6637c36dc7 146
p_igmon 0:ad6637c36dc7 147 void gen_attack(GENERATOR *gena,GENERATOR_TEMP *gena_temp){
p_igmon 0:ad6637c36dc7 148 /* Generator Start */
p_igmon 0:ad6637c36dc7 149 gena_temp->lfo1value = 0;
p_igmon 0:ad6637c36dc7 150 gena_temp->lfo1count = 0;
p_igmon 0:ad6637c36dc7 151 gena_temp->lfo2count = 0;
p_igmon 0:ad6637c36dc7 152 gena_temp->lfo1delaycount = gena->lfo1delaytime;
p_igmon 0:ad6637c36dc7 153 gena_temp->lfo2delaycount = gena->lfo2delaytime;
p_igmon 0:ad6637c36dc7 154 gena_temp->x = 0;
p_igmon 0:ad6637c36dc7 155 gena_temp->startadr = (U8 *)Wave[gena->wave_num - 1].startaddr;
p_igmon 0:ad6637c36dc7 156 gena_temp->p1 = (U8 *)Wave[gena->wave_num - 1].p1;
p_igmon 0:ad6637c36dc7 157 gena_temp->p2 = (U8 *)Wave[gena->wave_num - 1].p2;
p_igmon 0:ad6637c36dc7 158 gena_temp->cycle = (U8 *)Wave[gena->wave_num - 1].cycle;
p_igmon 0:ad6637c36dc7 159 gena_temp->samplecountp1p2 = (U8 *)((uint8_t *)gena_temp->p2 - (uint8_t *)gena_temp->p1);
p_igmon 0:ad6637c36dc7 160 gena_temp->voltemp = 0;
p_igmon 0:ad6637c36dc7 161 gena_temp->voltemp1 = (gena->volume<<16) / gena->attacktime;
p_igmon 0:ad6637c36dc7 162 gena_temp->voltemp2 = ((gena->volume * gena->sustainlevel) /100) <<16;
p_igmon 0:ad6637c36dc7 163
p_igmon 0:ad6637c36dc7 164 gena_temp->status = GEN_NOTEON;
p_igmon 0:ad6637c36dc7 165 gena_temp->eg_status = EG_IDLE;
p_igmon 0:ad6637c36dc7 166 }
p_igmon 0:ad6637c36dc7 167
p_igmon 0:ad6637c36dc7 168 void init_sgen(void){
p_igmon 0:ad6637c36dc7 169 GENERATOR gena ={
p_igmon 0:ad6637c36dc7 170 1,// U8 sw;// 0,1
p_igmon 0:ad6637c36dc7 171 1,// U8 wave_num;// 1-128
p_igmon 0:ad6637c36dc7 172 0,// S8 notebias;// -128 - +127
p_igmon 0:ad6637c36dc7 173 31,// U8 pan;// 0-31
p_igmon 0:ad6637c36dc7 174 0,// S16 detune;// -512 - +511
p_igmon 0:ad6637c36dc7 175 32512,// U16 volume;// 0-127<<8
p_igmon 0:ad6637c36dc7 176 1,// U16 attacktime;//
p_igmon 0:ad6637c36dc7 177 100,// U16 decaytime;//
p_igmon 0:ad6637c36dc7 178 80,// U8 sustainlevel;//
p_igmon 0:ad6637c36dc7 179 0,// U16 releasetime;// 0-21
p_igmon 0:ad6637c36dc7 180 0,// U16 lfo1depth;
p_igmon 0:ad6637c36dc7 181 0,// U8 lfo1speed;
p_igmon 0:ad6637c36dc7 182 0,// U8 lfo1type;
p_igmon 0:ad6637c36dc7 183 0,// U16 lfo1delaytime;// 0-3000
p_igmon 0:ad6637c36dc7 184 0,// U16 lfo2depth;
p_igmon 0:ad6637c36dc7 185 0,// U8 lfo2speed;
p_igmon 0:ad6637c36dc7 186 0,// U8 lfo2type;
p_igmon 0:ad6637c36dc7 187 0,// U16 lfo2delaytime;// 0-3000
p_igmon 0:ad6637c36dc7 188 };
p_igmon 0:ad6637c36dc7 189
p_igmon 0:ad6637c36dc7 190 // for(int i=0;i<PRGGENMAX*128;i++){
p_igmon 0:ad6637c36dc7 191 for(int i=0;i<PRGGENMAX*64;i++){
p_igmon 0:ad6637c36dc7 192 memcpy (&sgen[i],&gena,sizeof(GENERATOR));
p_igmon 0:ad6637c36dc7 193 }
p_igmon 0:ad6637c36dc7 194 }
p_igmon 0:ad6637c36dc7 195
p_igmon 0:ad6637c36dc7 196
p_igmon 0:ad6637c36dc7 197 void notenum2df(GENERATOR *gen ,GENERATOR_TEMP *gen_temp){
p_igmon 0:ad6637c36dc7 198 U32 temp;
p_igmon 0:ad6637c36dc7 199 U8 octave ,notenum;
p_igmon 0:ad6637c36dc7 200 notenum = gen_temp->notenum + gen->notebias;
p_igmon 0:ad6637c36dc7 201 octave = notenum / 12;
p_igmon 0:ad6637c36dc7 202 /* Pitch Adjuster */
p_igmon 0:ad6637c36dc7 203
p_igmon 0:ad6637c36dc7 204 if (gen_temp->cycle == 0){
p_igmon 0:ad6637c36dc7 205 temp = df_table[(notenum % 12)] * (U32)((U8 *)gen_temp->samplecountp1p2);// 2^16 * 2^(7-8)
p_igmon 0:ad6637c36dc7 206 }else{
p_igmon 0:ad6637c36dc7 207 temp = df_table[(notenum % 12)] * (U32)((U8 *)gen_temp->cycle);
p_igmon 0:ad6637c36dc7 208 }
p_igmon 0:ad6637c36dc7 209 // temp += ((S32)(temp * MasterTune))>>12;// +32 縺ァ +1% ・・128 縺ァ +4%
p_igmon 0:ad6637c36dc7 210 // temp += ((S32)(temp * MasterTune))>>4;// +32 縺ァ +1% ・・128 縺ァ +4%
p_igmon 0:ad6637c36dc7 211 gen_temp->df = (temp << (1 + octave));
p_igmon 0:ad6637c36dc7 212 // gen_temp->df += (S32)((S32)((gen_temp->df>>19) * MasterTune)>>8);// 140617
p_igmon 0:ad6637c36dc7 213 gen_temp->df += (S32)((S32)((gen_temp->df>>8) * MasterTune)>>4);// 140618
p_igmon 0:ad6637c36dc7 214 }
p_igmon 0:ad6637c36dc7 215
p_igmon 0:ad6637c36dc7 216 void noteon(U8 notenum ,U8 velocity){
p_igmon 0:ad6637c36dc7 217 U8 i;
p_igmon 0:ad6637c36dc7 218 U8 gencount ,sgencount;
p_igmon 0:ad6637c36dc7 219 STR_VOICE *voicea;
p_igmon 0:ad6637c36dc7 220 GENERATOR *sgen;
p_igmon 0:ad6637c36dc7 221 GENERATOR *gena;
p_igmon 0:ad6637c36dc7 222 GENERATOR_TEMP *gena_temp;
p_igmon 0:ad6637c36dc7 223 voicea = &voice[0];
p_igmon 0:ad6637c36dc7 224 sgen = gen;// source
p_igmon 0:ad6637c36dc7 225 gena = pgen;// 螳滉ス薙・縺サ縺・〒
p_igmon 0:ad6637c36dc7 226 gena_temp = pgen_temp;// 螳滉ス薙・縺サ縺・〒
p_igmon 0:ad6637c36dc7 227 gencount = sgencount = 0;
p_igmon 0:ad6637c36dc7 228
p_igmon 0:ad6637c36dc7 229
p_igmon 0:ad6637c36dc7 230 if (portament){
p_igmon 0:ad6637c36dc7 231 while(sgencount < PRGGENMAX){// 騾壼クク・・
p_igmon 0:ad6637c36dc7 232 if(sgen->sw){ // 130302
p_igmon 0:ad6637c36dc7 233 while(gencount < GENMAX){
p_igmon 0:ad6637c36dc7 234 if(gena_temp->status == GEN_POROFF){
p_igmon 0:ad6637c36dc7 235 gena_temp->status = GEN_PORON;
p_igmon 0:ad6637c36dc7 236 gena_temp->notenum = notenum;
p_igmon 0:ad6637c36dc7 237 notenum2df(gena,gena_temp);
p_igmon 0:ad6637c36dc7 238 // gena->velocity = velocity;
p_igmon 0:ad6637c36dc7 239 gena++;
p_igmon 0:ad6637c36dc7 240 gena_temp++;
p_igmon 0:ad6637c36dc7 241 gencount++;
p_igmon 0:ad6637c36dc7 242 break;// exit while
p_igmon 0:ad6637c36dc7 243 }
p_igmon 0:ad6637c36dc7 244 gena++;
p_igmon 0:ad6637c36dc7 245 gena_temp++;
p_igmon 0:ad6637c36dc7 246 gencount++;
p_igmon 0:ad6637c36dc7 247 }
p_igmon 0:ad6637c36dc7 248 }
p_igmon 0:ad6637c36dc7 249 sgen++;
p_igmon 0:ad6637c36dc7 250 sgencount++;
p_igmon 0:ad6637c36dc7 251 } // while loop
p_igmon 0:ad6637c36dc7 252 }else{
p_igmon 0:ad6637c36dc7 253 #ifdef DCF
p_igmon 0:ad6637c36dc7 254 if(gen_encount > (GENMAX - 1))return;// 140707 Gen count limit
p_igmon 0:ad6637c36dc7 255 for (i=0;i<VOICEMAX;i++){
p_igmon 0:ad6637c36dc7 256 if(voicea->enable == 0) break;// 遨コ縺・※縺・kvoice
p_igmon 0:ad6637c36dc7 257 voicea++;
p_igmon 0:ad6637c36dc7 258 }
p_igmon 0:ad6637c36dc7 259 if(i>(VOICEMAX - 1))return;// All Voice is Working
p_igmon 0:ad6637c36dc7 260 // voicea->enable = 0;
p_igmon 0:ad6637c36dc7 261 gena = voicea->gen;
p_igmon 0:ad6637c36dc7 262 gena_temp = voicea->gen_temp;
p_igmon 0:ad6637c36dc7 263 sgen = gen;// source
p_igmon 0:ad6637c36dc7 264
p_igmon 0:ad6637c36dc7 265 for (i=0;i<PRGGENMAX;i++){
p_igmon 0:ad6637c36dc7 266 if(sgen->sw){
p_igmon 0:ad6637c36dc7 267 memcpy(gena ,sgen ,sizeof(GENERATOR));// sgen1 ->> gena1
p_igmon 0:ad6637c36dc7 268 gena_temp->notenum = notenum;
p_igmon 0:ad6637c36dc7 269 gena_temp->velocity = velocity;
p_igmon 0:ad6637c36dc7 270 gen_attack(gena ,gena_temp);
p_igmon 0:ad6637c36dc7 271 notenum2df(gena ,gena_temp);
p_igmon 0:ad6637c36dc7 272 gen_encount++;// 140707
p_igmon 0:ad6637c36dc7 273 voicea->enable |= 1<<i;
p_igmon 0:ad6637c36dc7 274 }else{
p_igmon 0:ad6637c36dc7 275 gena_temp->status = GEN_IDLE;
p_igmon 0:ad6637c36dc7 276 gena->sw = 0;
p_igmon 0:ad6637c36dc7 277 gena_temp->voltemp = 0;
p_igmon 0:ad6637c36dc7 278 }
p_igmon 0:ad6637c36dc7 279 gena++;
p_igmon 0:ad6637c36dc7 280 gena_temp++;
p_igmon 0:ad6637c36dc7 281 sgen++;
p_igmon 0:ad6637c36dc7 282 }
p_igmon 0:ad6637c36dc7 283
p_igmon 0:ad6637c36dc7 284 }
p_igmon 0:ad6637c36dc7 285 #else
p_igmon 0:ad6637c36dc7 286 if(gen_encount > (GENMAX - 1))return;// 140707 Gen count limit
p_igmon 0:ad6637c36dc7 287 while(sgencount < PRGGENMAX){// 騾壼クク・・
p_igmon 0:ad6637c36dc7 288 if(sgen->sw){ // 130302
p_igmon 0:ad6637c36dc7 289 while(gencount < GENMAX){
p_igmon 0:ad6637c36dc7 290 if(gena_temp->status == GEN_IDLE){
p_igmon 0:ad6637c36dc7 291 memcpy(gena ,sgen ,sizeof(GENERATOR));// sgen ->> gena
p_igmon 0:ad6637c36dc7 292 gena_temp->notenum = notenum;
p_igmon 0:ad6637c36dc7 293 gena_temp->velocity = velocity;
p_igmon 0:ad6637c36dc7 294 gen_attack(gena ,gena_temp);
p_igmon 0:ad6637c36dc7 295 notenum2df(gena ,gena_temp);
p_igmon 0:ad6637c36dc7 296 gena++;
p_igmon 0:ad6637c36dc7 297 gena_temp++;
p_igmon 0:ad6637c36dc7 298 gencount++;
p_igmon 0:ad6637c36dc7 299 gen_encount++;// 140707
p_igmon 0:ad6637c36dc7 300 break;// exit while
p_igmon 0:ad6637c36dc7 301 }
p_igmon 0:ad6637c36dc7 302 gena++;
p_igmon 0:ad6637c36dc7 303 gena_temp++;
p_igmon 0:ad6637c36dc7 304 gencount++;
p_igmon 0:ad6637c36dc7 305 }
p_igmon 0:ad6637c36dc7 306 }
p_igmon 0:ad6637c36dc7 307 sgen++;
p_igmon 0:ad6637c36dc7 308 sgencount++;
p_igmon 0:ad6637c36dc7 309 }
p_igmon 0:ad6637c36dc7 310 }
p_igmon 0:ad6637c36dc7 311 #endif
p_igmon 0:ad6637c36dc7 312 }
p_igmon 0:ad6637c36dc7 313
p_igmon 0:ad6637c36dc7 314 void noteoff(U8 notenum ,U8 velocity){
p_igmon 0:ad6637c36dc7 315 U8 i;
p_igmon 0:ad6637c36dc7 316 GENERATOR *gena;
p_igmon 0:ad6637c36dc7 317 GENERATOR_TEMP *gena_temp;
p_igmon 0:ad6637c36dc7 318 gena = pgen;// 螳滉ス薙・縺サ縺・〒
p_igmon 0:ad6637c36dc7 319 gena_temp = pgen_temp;// 螳滉ス薙・縺サ縺・〒
p_igmon 0:ad6637c36dc7 320 for(i=0;i<GENMAX;i++){
p_igmon 0:ad6637c36dc7 321 if(((gena_temp->status == GEN_NOTEON)||(gena_temp->status == GEN_PORON)) && (gena_temp->notenum == notenum)){ // 130302
p_igmon 0:ad6637c36dc7 322
p_igmon 0:ad6637c36dc7 323 /* 111025 Velocity active untill release time
p_igmon 0:ad6637c36dc7 324 gena->velocity = 0;
p_igmon 0:ad6637c36dc7 325 */
p_igmon 0:ad6637c36dc7 326 if (portament){
p_igmon 0:ad6637c36dc7 327 gena_temp->status = GEN_POROFF;
p_igmon 0:ad6637c36dc7 328 }else{
p_igmon 0:ad6637c36dc7 329 /* Generator Start Release */
p_igmon 0:ad6637c36dc7 330 gena_temp->status = GEN_NOTEOFF;
p_igmon 0:ad6637c36dc7 331 gena_temp->eg_status = EG_RELEASE;
p_igmon 0:ad6637c36dc7 332 }
p_igmon 0:ad6637c36dc7 333 }
p_igmon 0:ad6637c36dc7 334 gena++;
p_igmon 0:ad6637c36dc7 335 gena_temp++;
p_igmon 0:ad6637c36dc7 336 }
p_igmon 0:ad6637c36dc7 337 }
p_igmon 0:ad6637c36dc7 338
p_igmon 0:ad6637c36dc7 339 void pgmchg(U8 number){
p_igmon 0:ad6637c36dc7 340 if (number >63) return;
p_igmon 0:ad6637c36dc7 341 PresetVoiceNum = number + 1;
p_igmon 0:ad6637c36dc7 342 presetvoice();
p_igmon 0:ad6637c36dc7 343 }
p_igmon 0:ad6637c36dc7 344
p_igmon 0:ad6637c36dc7 345
p_igmon 0:ad6637c36dc7 346 /*
p_igmon 0:ad6637c36dc7 347 Interpolaton value
p_igmon 0:ad6637c36dc7 348 x - 逵溘・豕「蠖「縺ョ蠎ァ讓・
p_igmon 0:ad6637c36dc7 349 y - 陬憺俣險育ョ励↓繧医▲縺ヲ蠕励ky(x)
p_igmon 0:ad6637c36dc7 350
p_igmon 0:ad6637c36dc7 351 謖・焚驛ィ・主ー乗焚驛ィ
p_igmon 0:ad6637c36dc7 352 20 12 bit
p_igmon 0:ad6637c36dc7 353 */
p_igmon 0:ad6637c36dc7 354
p_igmon 0:ad6637c36dc7 355 uint32_t temp32a;
p_igmon 0:ad6637c36dc7 356 /* DMA Wave繝舌ャ繝輔ぃ縺ォ豕「蠖「繧呈嶌縺崎セシ繧€ */
p_igmon 0:ad6637c36dc7 357 void wave_generate(void){
p_igmon 0:ad6637c36dc7 358 U8 i;
p_igmon 0:ad6637c36dc7 359 U16 count;
p_igmon 0:ad6637c36dc7 360 S32 rch,lch;
p_igmon 0:ad6637c36dc7 361 S16 rchout,lchout;
p_igmon 0:ad6637c36dc7 362 S16 temps16;
p_igmon 0:ad6637c36dc7 363 S32 sample;
p_igmon 0:ad6637c36dc7 364 S16 interpovalue;
p_igmon 0:ad6637c36dc7 365 S32 interpovalue32;
p_igmon 0:ad6637c36dc7 366 GENERATOR *gena;
p_igmon 0:ad6637c36dc7 367 GENERATOR_TEMP *gena_temp;
p_igmon 0:ad6637c36dc7 368 STR_VOICE *voicea;
p_igmon 0:ad6637c36dc7 369
p_igmon 0:ad6637c36dc7 370 volatile S16 *ptr;
p_igmon 0:ad6637c36dc7 371 U16 temp;
p_igmon 0:ad6637c36dc7 372 S32 y;
p_igmon 0:ad6637c36dc7 373 U32 expo_x; // 謖・焚驛ィ 20bit
p_igmon 0:ad6637c36dc7 374 U16 fract_x;// 蟆乗焚驛ィ 12bit
p_igmon 0:ad6637c36dc7 375
p_igmon 0:ad6637c36dc7 376 volatile S16 *ptr0;
p_igmon 0:ad6637c36dc7 377 GENERATE_ON
p_igmon 0:ad6637c36dc7 378 if (--TimerCount10mS < 0) TimerCount10mS = 0;
p_igmon 0:ad6637c36dc7 379
p_igmon 0:ad6637c36dc7 380 if (BufferOffset == DMA_FullComplete){
p_igmon 0:ad6637c36dc7 381 ptr0 = (S16 *)&DMA_Buffer[DMA_BUFFERSIZE>>1];// From Half
p_igmon 0:ad6637c36dc7 382 }else{
p_igmon 0:ad6637c36dc7 383 ptr0 = (S16 *)&DMA_Buffer[0];// From Top
p_igmon 0:ad6637c36dc7 384 }
p_igmon 0:ad6637c36dc7 385 BufferOffset = DMA_Idle;
p_igmon 0:ad6637c36dc7 386
p_igmon 0:ad6637c36dc7 387 count = DMA_BUFFERSIZE/4;// DMA 繝舌ャ繝輔ぃ縺ョ繧オ繧、繧コ
p_igmon 0:ad6637c36dc7 388 while(count-- > 0){
p_igmon 0:ad6637c36dc7 389 if(samplecount++ > 43){
p_igmon 0:ad6637c36dc7 390 samplecount = 0;
p_igmon 0:ad6637c36dc7 391 envelope_work();
p_igmon 0:ad6637c36dc7 392 }
p_igmon 0:ad6637c36dc7 393 voicea = &voice[0];
p_igmon 0:ad6637c36dc7 394 sample = 0;
p_igmon 0:ad6637c36dc7 395 gena = pgen;// 螳滉ス薙・縺サ縺・〒
p_igmon 0:ad6637c36dc7 396 gena_temp = pgen_temp;// 螳滉ス薙・縺サ縺・〒
p_igmon 0:ad6637c36dc7 397 for(i=0;i<GENMAX;i++){
p_igmon 0:ad6637c36dc7 398 if(gena_temp->eg_status != EG_IDLE){
p_igmon 0:ad6637c36dc7 399 // if(gena_temp->status !=GEN_IDLE){
p_igmon 0:ad6637c36dc7 400
p_igmon 0:ad6637c36dc7 401 /*
p_igmon 0:ad6637c36dc7 402 #ifdef BEND
p_igmon 0:ad6637c36dc7 403 gena->x += (((U32)gena_temp->df>>16) + (S16)gena->detune + gena->lfo1value + gena->bendvalue);
p_igmon 0:ad6637c36dc7 404 #else
p_igmon 0:ad6637c36dc7 405 // gena_temp->x += (((U32)gena_temp->df>>16) + (S16)gena->detune + gena_temp->lfo1value);
p_igmon 0:ad6637c36dc7 406 gena_temp->x += (((U32)gena_temp->df>>16) + (S32)gena->detune + gena_temp->lfo1value);
p_igmon 0:ad6637c36dc7 407 #endif
p_igmon 0:ad6637c36dc7 408 */
p_igmon 0:ad6637c36dc7 409 gena_temp->x += gena_temp->xx;
p_igmon 0:ad6637c36dc7 410
p_igmon 0:ad6637c36dc7 411 if (gena_temp->x <= (U32)gena_temp->p2<<12){
p_igmon 0:ad6637c36dc7 412 goto generate1;
p_igmon 0:ad6637c36dc7 413 }else if(gena_temp->p1 == 0){// No Loop
p_igmon 0:ad6637c36dc7 414 goto nothing;
p_igmon 0:ad6637c36dc7 415 }else{
p_igmon 0:ad6637c36dc7 416 gena_temp->x -= ((U32)gena_temp->samplecountp1p2 <<12);// Loop p1 - p2
p_igmon 0:ad6637c36dc7 417 }
p_igmon 0:ad6637c36dc7 418
p_igmon 0:ad6637c36dc7 419 generate1: expo_x = gena_temp->x>>12;
p_igmon 0:ad6637c36dc7 420 #ifdef INTERPO2
p_igmon 0:ad6637c36dc7 421 temp = (gena_temp->x) & 0xfff;
p_igmon 0:ad6637c36dc7 422 ptr = (S16*)gena_temp->startadr +((U32)expo_x);
p_igmon 0:ad6637c36dc7 423 y = (*ptr * (4096 - temp));
p_igmon 0:ad6637c36dc7 424 ptr++;
p_igmon 0:ad6637c36dc7 425 y += *ptr * temp;
p_igmon 0:ad6637c36dc7 426 interpovalue32 = (S32)((S16)(y>>12) * limit)>>3;
p_igmon 0:ad6637c36dc7 427 #else
p_igmon 0:ad6637c36dc7 428 fract_x = (gena_temp->x>>8) & 0x0f;
p_igmon 0:ad6637c36dc7 429 ptr = (S16*)gena_temp->startadr +((U32)expo_x);
p_igmon 0:ad6637c36dc7 430
p_igmon 0:ad6637c36dc7 431 temp = k[fract_x];
p_igmon 0:ad6637c36dc7 432 y = *ptr * temp;
p_igmon 0:ad6637c36dc7 433 ptr++;
p_igmon 0:ad6637c36dc7 434 y += (*ptr * (65535 - temp));
p_igmon 0:ad6637c36dc7 435 interpovalue32 = (S16)(y>>16) * limit;
p_igmon 0:ad6637c36dc7 436
p_igmon 0:ad6637c36dc7 437 #endif
p_igmon 0:ad6637c36dc7 438
p_igmon 0:ad6637c36dc7 439 #ifdef DIST
p_igmon 0:ad6637c36dc7 440 // if (gena_temp->eg_status < EG_RELEASE){
p_igmon 0:ad6637c36dc7 441 if (interpovalue32 > 120<<8){
p_igmon 0:ad6637c36dc7 442 interpovalue32 = 120<<8;
p_igmon 0:ad6637c36dc7 443 }else if(interpovalue32 < (120<<8) * -1){
p_igmon 0:ad6637c36dc7 444 interpovalue32 = (120<<8) * -1;
p_igmon 0:ad6637c36dc7 445 }
p_igmon 0:ad6637c36dc7 446 // }
p_igmon 0:ad6637c36dc7 447 #endif
p_igmon 0:ad6637c36dc7 448
p_igmon 0:ad6637c36dc7 449 #ifdef 0
p_igmon 0:ad6637c36dc7 450 if (gena_temp->eg_status < EG_RELEASE){
p_igmon 0:ad6637c36dc7 451 if (interpovalue > limit<<8){
p_igmon 0:ad6637c36dc7 452 interpovalue = limit<<8;
p_igmon 0:ad6637c36dc7 453 }else if(interpovalue < (limit<<8) * -1){
p_igmon 0:ad6637c36dc7 454 interpovalue = (limit<<8) * -1;
p_igmon 0:ad6637c36dc7 455 }
p_igmon 0:ad6637c36dc7 456 }
p_igmon 0:ad6637c36dc7 457 #endif
p_igmon 0:ad6637c36dc7 458
p_igmon 0:ad6637c36dc7 459 // sample += ((S16)interpovalue * ((gena_temp->voltempL)>>1));// 譛牙柑譯∵焚32繝薙ャ繝・
p_igmon 0:ad6637c36dc7 460 sample = satAdd32(sample ,((S16)interpovalue32 * ((gena_temp->voltempL)>>1)));
p_igmon 0:ad6637c36dc7 461 nothing:
p_igmon 0:ad6637c36dc7 462
p_igmon 0:ad6637c36dc7 463 }
p_igmon 0:ad6637c36dc7 464 #ifdef DCF
p_igmon 0:ad6637c36dc7 465 if ((i & (PRGGENMAX - 1))== (PRGGENMAX - 1)){
p_igmon 0:ad6637c36dc7 466 voicea->signal[0] = (S32)(sample);// 譛牙柑譯∵焚32繝薙ャ繝・
p_igmon 0:ad6637c36dc7 467 voicea++;
p_igmon 0:ad6637c36dc7 468 sample = 0;
p_igmon 0:ad6637c36dc7 469 }
p_igmon 0:ad6637c36dc7 470 #endif
p_igmon 0:ad6637c36dc7 471 gena++;
p_igmon 0:ad6637c36dc7 472 gena_temp++;
p_igmon 0:ad6637c36dc7 473 }
p_igmon 0:ad6637c36dc7 474 #ifdef DCF
p_igmon 0:ad6637c36dc7 475 voicea =&voice[0];
p_igmon 0:ad6637c36dc7 476 lch = 0;
p_igmon 0:ad6637c36dc7 477 i = VOICEMAX;
p_igmon 0:ad6637c36dc7 478 while(i--){
p_igmon 0:ad6637c36dc7 479 // lch += (S16)(dcf64(voicea->dcf_param ,&voicea->signal[0]));
p_igmon 0:ad6637c36dc7 480 lch = satAdd16(lch ,(S16)(dcf64(voicea->dcf_param ,&voicea->signal[0])));
p_igmon 0:ad6637c36dc7 481 // lch += (S16)((S32)voicea->signal[0]>>16);// NoneLPF
p_igmon 0:ad6637c36dc7 482 voicea++;
p_igmon 0:ad6637c36dc7 483 }
p_igmon 0:ad6637c36dc7 484 #else
p_igmon 0:ad6637c36dc7 485 lch = sample >> 16;
p_igmon 0:ad6637c36dc7 486 #endif
p_igmon 0:ad6637c36dc7 487
p_igmon 0:ad6637c36dc7 488 // temps16 = (((S32)lch) * (((S16)MasterVolume)<<1))>>16;
p_igmon 0:ad6637c36dc7 489
p_igmon 0:ad6637c36dc7 490 #ifdef 0
p_igmon 0:ad6637c36dc7 491 if (lch > limit<<8){
p_igmon 0:ad6637c36dc7 492 lch = limit<<8;
p_igmon 0:ad6637c36dc7 493 }else if(lch < (limit<<8) * -1){
p_igmon 0:ad6637c36dc7 494 lch = (limit<<8) * -1;
p_igmon 0:ad6637c36dc7 495 }
p_igmon 0:ad6637c36dc7 496 #endif
p_igmon 0:ad6637c36dc7 497
p_igmon 0:ad6637c36dc7 498 #if 0
p_igmon 0:ad6637c36dc7 499 /* Reverve */
p_igmon 0:ad6637c36dc7 500 #ifdef REVERVE16BIT
p_igmon 0:ad6637c36dc7 501 if (count & 1){
p_igmon 0:ad6637c36dc7 502 if(++reverve_wtemp == (reverve_buf + 22000)) reverve_wtemp = reverve_buf;
p_igmon 0:ad6637c36dc7 503 *reverve_wtemp = temps16;
p_igmon 0:ad6637c36dc7 504 rchout = lchout = 0;
p_igmon 0:ad6637c36dc7 505 for(i=0;i<90;i += 3){
p_igmon 0:ad6637c36dc7 506 S16 *temp_ptr = reverve_wtemp - reverve_tap[i];
p_igmon 0:ad6637c36dc7 507 if(temp_ptr < reverve_buf){
p_igmon 0:ad6637c36dc7 508 lchout += ((S16)(*(temp_ptr + 22000)) * (U16)reverve_tap[i+1])>>18;
p_igmon 0:ad6637c36dc7 509 rchout += ((S16)(*(temp_ptr + 22000)) * (U16)reverve_tap[i+2])>>18;
p_igmon 0:ad6637c36dc7 510 }else{
p_igmon 0:ad6637c36dc7 511 lchout += ((S16)(*temp_ptr) * (U16)reverve_tap[i+1])>>18;
p_igmon 0:ad6637c36dc7 512 rchout += ((S16)(*temp_ptr) * (U16)reverve_tap[i+2])>>18;
p_igmon 0:ad6637c36dc7 513 }
p_igmon 0:ad6637c36dc7 514 }
p_igmon 0:ad6637c36dc7 515 }
p_igmon 0:ad6637c36dc7 516 #else
p_igmon 0:ad6637c36dc7 517 /* Reverve */
p_igmon 0:ad6637c36dc7 518 rchout = lchout = 0;
p_igmon 0:ad6637c36dc7 519 if(++reverve_wtemp == (reverve_buf + 44000)) reverve_wtemp = reverve_buf;
p_igmon 0:ad6637c36dc7 520 *reverve_wtemp = S8(temps16>>8);
p_igmon 0:ad6637c36dc7 521 for(i=0;i<90;i += 3){
p_igmon 0:ad6637c36dc7 522 S8 *temp_ptr = reverve_wtemp - reverve_tap[i];
p_igmon 0:ad6637c36dc7 523 if(temp_ptr < reverve_buf){
p_igmon 0:ad6637c36dc7 524 lchout += ((S8)(*(temp_ptr + 44000)) * (U16)reverve_tap[i+1])>>10;
p_igmon 0:ad6637c36dc7 525 rchout += ((S8)(*(temp_ptr + 44000)) * (U16)reverve_tap[i+2])>>10;
p_igmon 0:ad6637c36dc7 526 }else{
p_igmon 0:ad6637c36dc7 527 lchout += ((S8)(*temp_ptr) * (U16)reverve_tap[i+1])>>10;
p_igmon 0:ad6637c36dc7 528 rchout += ((S8)(*temp_ptr) * (U16)reverve_tap[i+2])>>10;
p_igmon 0:ad6637c36dc7 529 }
p_igmon 0:ad6637c36dc7 530
p_igmon 0:ad6637c36dc7 531 }
p_igmon 0:ad6637c36dc7 532
p_igmon 0:ad6637c36dc7 533 #endif
p_igmon 0:ad6637c36dc7 534 // *bufptr++ = ((rch + (rchout & 0xffff))<<16)|(((lch & 0xffff) + (lchout & 0xffff)) & 0xffff);
p_igmon 0:ad6637c36dc7 535
p_igmon 0:ad6637c36dc7 536 *ptr0++ = temps16 + rchout;
p_igmon 0:ad6637c36dc7 537 *ptr0++ = temps16 + lchout;
p_igmon 0:ad6637c36dc7 538 #endif
p_igmon 0:ad6637c36dc7 539
p_igmon 0:ad6637c36dc7 540 temps16 = (((S32)lch) * (((S16)MasterVolume)<<1))>>16;
p_igmon 0:ad6637c36dc7 541 *ptr0++ = temps16;
p_igmon 0:ad6637c36dc7 542 *ptr0++ = rch_pol * temps16;
p_igmon 0:ad6637c36dc7 543
p_igmon 0:ad6637c36dc7 544 }
p_igmon 0:ad6637c36dc7 545 GENERATE_OFF
p_igmon 0:ad6637c36dc7 546 }
p_igmon 0:ad6637c36dc7 547
p_igmon 0:ad6637c36dc7 548
p_igmon 0:ad6637c36dc7 549 void uGen4_init(void)
p_igmon 0:ad6637c36dc7 550 {
p_igmon 0:ad6637c36dc7 551 GENERATOR *gena;
p_igmon 0:ad6637c36dc7 552 GENERATOR_TEMP *gena_temp;
p_igmon 0:ad6637c36dc7 553
p_igmon 0:ad6637c36dc7 554 mvoldiv = 0;
p_igmon 0:ad6637c36dc7 555 portament = 0;// 130213
p_igmon 0:ad6637c36dc7 556
p_igmon 0:ad6637c36dc7 557 gena = pgen;
p_igmon 0:ad6637c36dc7 558 gena_temp = pgen_temp;
p_igmon 0:ad6637c36dc7 559 for(int i=0;i<GENMAX;i++){
p_igmon 0:ad6637c36dc7 560 gena_temp->status = GEN_IDLE;
p_igmon 0:ad6637c36dc7 561 gena->sw = 0;
p_igmon 0:ad6637c36dc7 562 gena_temp->voltemp = 0;
p_igmon 0:ad6637c36dc7 563 gena++;
p_igmon 0:ad6637c36dc7 564 gena_temp++;
p_igmon 0:ad6637c36dc7 565 }
p_igmon 0:ad6637c36dc7 566
p_igmon 0:ad6637c36dc7 567 init_voice();
p_igmon 0:ad6637c36dc7 568
p_igmon 0:ad6637c36dc7 569 midi_note_ch = midi_base_ch;
p_igmon 0:ad6637c36dc7 570 midi_prog_ch = midi_base_ch;
p_igmon 0:ad6637c36dc7 571
p_igmon 0:ad6637c36dc7 572 // init_midi();
p_igmon 0:ad6637c36dc7 573
p_igmon 0:ad6637c36dc7 574 }
p_igmon 0:ad6637c36dc7 575