#ifdef _X86_ void PassLow8(short *vin,short *vout,short *mem,short nech) { short low_a; _asm { MOV ESI,[vin] ; SI adress input samples MOV CX,[nech] BP_LOOP: MOV EBX,0 MOV WORD PTR [low_a],0 MOV EDI,[mem] ; DI adress mem vect. ADD EDI,14 ; point on mem(7) MOV AX,-3126 ; AX=c(8) IMUL WORD PTR [EDI] ; *=mem(7) SUB WORD PTR [low_a],AX ; accumulate in EBX:LOW_A MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 ; mem-- MOV AX,-22721 ; AX=c(7) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX SUB WORD PTR [low_a],AX MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 MOV AX,-12233 ; AX=c(6) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX SUB WORD PTR [low_a],AX MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 MOV AX,11718 ; AX=c(5) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX SUB WORD PTR [low_a],AX MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 MOV AX,-13738 ; AX=c(4) IMUL WORD PTR [EDI] ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SUB EDI,2 MOV AX,-26425 ; AX=c(3) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SUB EDI,2 MOV DX,WORD PTR [EDI] ; c(2)=0 ! MOV WORD PTR [EDI+2],DX SUB EDI,2 MOV AX,26425 ; AX=c(1) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,13738 ; AX=c(0) MOV DX,WORD PTR [ESI] ; *=input !!! ADD ESI,2 MOV WORD PTR [EDI],DX ; DI=mem(0) IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV [EDI+8],BX MOV EDI,[vout] MOV [EDI],BX ADD DWORD PTR [vout],2 ; vout++ DEC CX JNE BP_LOOP } } #else void PassLow8(short *vin,short *vout,short *mem,int nech) { int j,k; long X; for (j=nech;j>0;j--) { X = 0; X -= (((long)-3126*(long)mem[7])+ ((long)-22721*(long)mem[6])+ ((long)-12233*(long)mem[5])+ ((long)11718*(long)mem[4]))>>1; X += (((long)-13738*(long)mem[3])+ ((long)-26425*(long)mem[2])+ ((long)26425*(long)mem[0])+ ((long)13738*(long)(*vin)))>>1; mem[7]=mem[6]; mem[6]=mem[5]; mem[5]=mem[4]; mem[4]=(int)(X>>14); mem[3]=mem[2]; mem[2]=mem[1]; mem[1]=mem[0]; mem[0]=*vin++; *vout++=mem[4]; } } #endif #if 0 // PhilF: The following is never called!!! void PassLow11(short *vin,short *vout,short *mem,short nech) { short low_a; _asm { MOV ESI,[vin] ; ESI adress input samples MOV CX,[nech] BP11_LOOP: MOV EBX,0 MOV WORD PTR [low_a],0 MOV EDI,[mem] ; EDI adress mem vect. ADD EDI,14 ; point on mem(7) MOV AX,3782 ; AX=c(8) IMUL WORD PTR [EDI] ; *=mem(7) SUB WORD PTR [low_a],AX ; accumulate in EBX:low_a MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 ; mem-- MOV AX,-8436 ; AX=c(7) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX SUB WORD PTR [low_a],AX MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 MOV AX,17092 ; AX=c(6) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX SUB WORD PTR [low_a],AX MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 MOV AX,-10681 ; AX=c(5) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX SUB WORD PTR [low_a],AX MOVSX EAX,DX SBB EBX,EAX SUB EDI,2 MOV AX,1179 ; AX=c(4) IMUL WORD PTR [EDI] ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SUB EDI,2 MOV AX,4280 ; AX=c(3) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SUB EDI,2 MOV AX,6208 ; AX=c(3) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SUB EDI,2 MOV AX,4280 ; AX=c(1) MOV DX,WORD PTR [EDI] MOV WORD PTR [EDI+2],DX IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,1179 ; AX=c(0) MOV DX,WORD PTR [ESI] ; *=input !!! ADD ESI,2 MOV WORD PTR [EDI],DX ; EDI=mem(0) IMUL DX ADD WORD PTR [low_a],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,2 MOV [EDI+8],BX MOV EDI,[vout] MOV [EDI],BX ADD WORD PTR [vout],2 ; vout++ DEC CX JNE BP11_LOOP } } #endif #if 0 // PhilF: The following is never called!!! void PassHigh8(short *mem, short *Vin, short *Vout, short lfen) { _asm { MOV CX,[lfen] ;CX=cpteur MOV EDI,[mem] PH8_LOOP: MOV ESI,[Vin] MOV BX,WORD PTR [ESI] ;BX=Xin MOV AX,WORD PTR [EDI] ;AX=z(1) MOV WORD PTR [EDI],BX ;mise a jour memoire SUB BX,AX ;BX=Xin-z(1) ADD WORD PTR [Vin],2 ;pointer echant svt MOV AX,WORD PTR [EDI+2] ;AX=z(2) MOV DX,30483 ;DX=0.9608 IMUL DX ADD AX,16384 ADC DX,0 ;arrondi et dble signe SHLD DX,AX,1 ADD DX,BX ;reponse=DX=tmp MOV WORD PTR [EDI+2],DX ;mise a jour memoire MOV ESI,[Vout] MOV WORD PTR [ESI],DX ;output=tmp ADD WORD PTR [Vout],2 ;pointer echant svt DEC CX JNE PH8_LOOP } } #endif #if 0 // PhilF: The following is never called!!! void PassHigh11(short *mem, short *Vin, short *Vout, short lfen) { _asm { MOV CX,[lfen] ;CX=cpteur MOV EDI,[mem] PH11_LOOP: MOV ESI,[Vin] MOV BX,WORD PTR [ESI] ;BX=Xin MOV AX,WORD PTR [EDI] ;AX=z(1) MOV WORD PTR [EDI],BX ;mise a jour memoire SUB BX,AX ;BX=Xin-z(1) ADD WORD PTR [Vin],2 ;pointer echant svt MOV AX,WORD PTR [EDI+2] ;AX=z(2) MOV DX,30830 ;DX=0.9714 IMUL DX ADD AX,16384 ADC DX,0 ;arrondi et dble signe SHLD DX,AX,1 ADD DX,BX ;reponse=DX=tmp MOV WORD PTR [EDI+2],DX ;mise a jour memoire MOV ESI,[Vout] MOV WORD PTR [ESI],DX ;output=tmp ADD WORD PTR [Vout],2 ;pointer echant svt DEC CX JNE PH11_LOOP } } #endif #if 0 // PhilF: The following is never called!!! void Down11_8(short *Vin, short *Vout, short *mem) { short low_a, count; _asm { MOV WORD PTR [count],176 MOV ESI,[Vin] MOV EDI,[Vout] MOV CX,[ESI] ; *mem=*in DOWN_LOOP: MOV [EDI],CX ADD EDI,2 ADD ESI,2 MOV AX,7040 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,2112 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-960 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,3584 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,5376 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-768 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX ADD ESI,2 MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,8064 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,576 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-448 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,6144 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,3072 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-1024 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,1920 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,6720 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-448 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX ADD ESI,2 MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,7680 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,1280 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-768 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,4992 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,4160 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-960 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX ADD ESI,4 MOV CX,[ESI] ADD EDI,2 SUB WORD PTR [count],11 JNE DOWN_LOOP SUB ESI,2 MOV EBX,[mem] MOV CX,[ESI] MOV [EBX],CX ; *memory=*(++ptr_in) } } #endif #if 0 // PhilF: The following is never called!!! void Up8_11(short *Vin, short *Vout, short *mem1, short *mem2) { short low_a, count; _asm { MOV WORD PTR [count],128 MOV ESI,[Vin] MOV EBX,[mem1] MOV CX,[EBX] ;CX=memo MOV EDI,[mem2] MOV AX,7582 IMUL CX MOV [low_a],AX MOV BX,DX MOV AX,1421 IMUL WORD PTR [ESI] ADD [low_a],AX ADC BX,DX MOV AX,-812 IMUL WORD PTR [EDI] ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV EDI,[Vout] MOV [EDI],AX ADD EDI,2 UP_LOOP: MOV AX,[ESI] MOV [EDI],AX ADD EDI,2 MOV AX,3859 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,5145 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-812 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,6499 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,2708 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-1015 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,7921 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,880 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-609 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX ADD EDI,2 MOV AX,1421 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,7108 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-338 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,4874 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,4265 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-947 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,7108 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,2031 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-947 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,8124 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,406 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-338 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX ADD EDI,2 MOV AX,2708 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,6093 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-609 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 MOV AX,5754 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,3452 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-1015 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 CMP WORD PTR [count],8 JE END_OF_LOOP MOV AX,7582 IMUL WORD PTR [ESI] MOV [low_a],AX MOV BX,DX MOV AX,1421 IMUL WORD PTR [ESI+2] ADD [low_a],AX ADC BX,DX MOV AX,-812 IMUL CX ADD [low_a],AX ADC BX,DX MOV AX,[low_a] SHRD AX,BX,13 MOV [EDI],AX MOV CX,[ESI] ADD ESI,2 ADD EDI,2 END_OF_LOOP: SUB WORD PTR [count],8 JNE UP_LOOP MOV EBX,[mem2] MOV CX,[ESI-2] MOV [EBX],CX ; *memory2=*(ptr_in-1) MOV EBX,[mem1] MOV CX,[ESI] MOV [EBX],CX ; *memory=*(ptr_in) } } #endif #ifdef _X86_ void QMFilter(short *input,short *coef,short *out_low,short *out_high, short *mem,short lng) { long R1,R0; _asm { QMF_LOOP: MOV ESI,[input] ; ES:SI for input MOV EBX,[mem] ; DS:BX for memory MOV AX,WORD PTR [ESI] ; AX=*input MOV WORD PTR [EBX+16],AX ; *high_mem=*input ADD ESI,2 ; input++ MOV AX,WORD PTR [ESI] ; AX=*input MOV WORD PTR [EBX],AX ; *low_mem=*input ADD DWORD PTR [input],4 ; input++ MOV DWORD PTR [R1],0 ; initialize accumulation in R1 MOV DWORD PTR [R0],0 ; initialize accumulation in R0 MOV ESI,[coef] ; ES:SI for ptr1 MOV EDI,ESI ADD EDI,14 ; ES:DI for ptr2 ADD EBX,14 ; DS:BX for end of mem vector MOV CX,8 ; CX=count QMF_LOOP2: MOV AX,WORD PTR [ESI] ; AX=*ptr1 ADD ESI,2 ; ptr1++ IMUL WORD PTR [EBX+16] ; DX:AX *=(*high_mem) AND EAX,0000ffffH SAL EDX,16 ADD EDX,EAX ADD DWORD PTR [R1],EDX MOV AX,WORD PTR [EDI] ; AX=*ptr0 SUB EDI,2 ; ptr1-- IMUL WORD PTR [EBX] ; DX:AX *=(*low_mem) AND EAX,0000ffffH SAL EDX,16 ADD EDX,EAX ADD DWORD PTR [R0],EDX MOV AX,WORD PTR [EBX-2] MOV WORD PTR [EBX],AX ; *low_mem=*(low_mem-1) MOV AX,WORD PTR [EBX+14] MOV WORD PTR [EBX+16],AX ; *high_mem=*(high_mem-1) SUB EBX,2 ; *low_mem-- , *high_mem-- DEC CX JNE QMF_LOOP2 MOV EAX,DWORD PTR [R0] SUB EAX,DWORD PTR [R1] SAR EAX,15 MOV EDI,[out_high] MOV WORD PTR [EDI],AX ; *high_out=R0-R1 ADD DWORD PTR [out_high],2 ; high_low++ MOV EAX,DWORD PTR [R0] ADD EAX,DWORD PTR [R1] SAR EAX,15 MOV EDI,[out_low] MOV WORD PTR [EDI],AX ; *low_out=R0+R1 ADD DWORD PTR [out_low],2 ; low_out++ DEC WORD PTR [lng] JNE QMF_LOOP } } #else void QMFilter(short *in,short *coef,short *out_low,short *out_high, short *mem,short lng) { int i,j; long R1,R0; short *ptr0,*ptr1,*high_p,*low_p; for (j=lng; j>0; j--) { high_p = mem+8; low_p = mem; *high_p = *in++; *low_p = *in++; R1=R0=0; ptr0 = coef; ptr1 = coef+8-1; for (i=8; i>0; i--) { R1 += (long)(*ptr1--) * (long)(*high_p++); R0 += (long)(*ptr0++) * (long)(*low_p++); } *out_low++ = (short)((R0+R1)>>15); *out_high++ = (short)((R0-R1)>>15); for (i=8; i>0; i--) { high_p--; low_p--; *high_p = *(high_p-1); *low_p = *(low_p-1); } } } #endif #ifdef _X86_ void QMInverse(short *in_low,short *in_high,short *coef, short *output,short *mem,short lng) { long R0,R1; _asm { QMI_LOOP: MOV ESI,[in_low] ; ES:SI for input low MOV EDI,[in_high] ; ES:DI for input high MOV EBX,[mem] ; DS:BX for memory MOV AX,WORD PTR [ESI] SUB AX,WORD PTR [EDI] ; AX=*in_low-*in_high MOV WORD PTR [EBX],AX ; *low_mem=*in_low-*in_high MOV AX,WORD PTR [ESI] ADD AX,WORD PTR [EDI] ; AX=*in_low+*in_high MOV WORD PTR [EBX+16],AX ; *high_mem=*in_low+*in_high ADD DWORD PTR [in_low],2 ; in_low++ ADD DWORD PTR [in_high],2 ; in_high++ MOV DWORD PTR [R0],0 MOV DWORD PTR [R1],0 MOV ESI,[coef] ; ES:SI for ptr1 MOV EDI,ESI ADD EDI,14 ; ES:DI for ptr2 ADD EBX,14 ; DS:BX for end of mem vector MOV CX,8 ; DX=count QMI_LOOP2: MOV AX,WORD PTR [ESI] ; AX=*ptr1 ADD ESI,2 ; ptr1++ IMUL WORD PTR [EBX+16] ; DX:AX*=(*high_mem) AND EAX,0000ffffH SAL EDX,16 ADD EDX,EAX ADD DWORD PTR [R1],EDX ; Accumulate in R1 MOV AX,WORD PTR [EDI] ; AX=*ptr0 SUB EDI,2 ; ptr1-- IMUL WORD PTR [EBX] ; DX:AX*=(*low_mem) AND EAX,0000ffffH SAL EDX,16 ADD EDX,EAX ADD DWORD PTR [R0],EDX ; Accumulate in R0 MOV AX,WORD PTR [EBX-2] MOV WORD PTR [EBX],AX ; *low_mem=*(low_mem-1) MOV AX,WORD PTR [EBX+14] MOV WORD PTR [EBX+16],AX ; *high_mem=*(high_mem-1) SUB EBX,2 ; *low_mem-- , *high_mem-- DEC CX JNE QMI_LOOP2 MOV EDI,[output] MOV EAX,DWORD PTR [R1] SAR EAX,15 MOV WORD PTR [EDI+2],AX ; *(out+1)=R1 MOV EAX,DWORD PTR [R0] SAR EAX,15 MOV WORD PTR [EDI],AX ; *out=R0 ADD DWORD PTR [output],4 ; out++,out++ DEC WORD PTR [lng] JNE QMI_LOOP } } #else void QMInverse(short *in_low,short *in_high,short *coef, short *out,short *mem,short lng) { int i,j; long R1,R0; short *ptr0,*ptr1,*high_p,*low_p; for (j=0; j0; i--) { R1 += (long)(*ptr1--) * (long)(*high_p++); R0 += (long)(*ptr0++) * (long)(*low_p++); } *out++ = (short)(R0>>15); *out++ = (short)(R1>>15); for (i=8; i>0; i--) { high_p--; low_p--; *high_p = *(high_p-1); *low_p = *(low_p-1); } } } #endif #ifdef _X86_ void iConvert64To8(short *input, short *output, short N, short *mem) { short LOW_A; _asm { MOV ESI,[input] MOV EDI,[output] MOV AX,[ESI] MOV [EDI],AX ; out[0]=in[0] MOV WORD PTR [LOW_A],0 MOV AX,-3072 MOV EBX,[mem] ; BX for memory IMUL word ptr [EBX] MOV EBX,0 ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,14336 IMUL word ptr [ESI] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,21504 IMUL word ptr [ESI+2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV word ptr [EDI+2],BX ; out[1] MOV WORD PTR [LOW_A],0 MOV EBX,0 MOV AX,-4096 IMUL word ptr [ESI] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,24576 IMUL word ptr [ESI+2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,12288 IMUL word ptr [ESI+4] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV word ptr [EDI+4],BX ; out[2] MOV WORD PTR [LOW_A],0 MOV EBX,0 MOV AX,-3072 IMUL word ptr [ESI+2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,30720 IMUL word ptr [ESI+4] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,5120 IMUL word ptr [ESI+6] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV word ptr [EDI+6],BX ; out[3] MOV AX,[ESI+6] MOV [EDI+8],AX ; out[4] MOV CX,0 iUPSAMP: ADD CX,4 CMP CX,WORD PTR [N] JGE iEND_UPSAMP ADD ESI,8 ADD EDI,10 MOV AX,[ESI] MOV [EDI],AX ; out[0]=in[0] MOV WORD PTR [LOW_A],0 MOV EBX,0 MOV AX,-3072 IMUL word ptr [ESI-2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,14336 IMUL word ptr [ESI] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,21504 IMUL word ptr [ESI+2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV word ptr [EDI+2],BX ; out[1] MOV WORD PTR [LOW_A],0 MOV EBX,0 MOV AX,-4096 IMUL word ptr [ESI] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,24576 IMUL word ptr [ESI+2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,12288 IMUL word ptr [ESI+4] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV word ptr [EDI+4],BX ; out[2] MOV WORD PTR [LOW_A],0 MOV EBX,0 MOV AX,-3072 IMUL word ptr [ESI+2] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,30720 IMUL word ptr [ESI+4] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX MOV AX,5120 IMUL word ptr [ESI+6] ADD [LOW_A],AX MOVSX EAX,DX ADC EBX,EAX SAL EBX,1 MOV word ptr [EDI+6],BX ; out[3] MOV AX,[ESI+6] MOV [EDI+8],AX ; out[4] JMP iUPSAMP iEND_UPSAMP: MOV EBX,[mem] MOV AX,[ESI+6] MOV [EBX],AX ; mem[0]=in[N-1] } } #else void iConvert64To8(short *input, /* Pointer to input buffer */ short *output, /* Pointer to output buffer */ short N, /* Number of input samples */ short *mem) /* Pointer to two word temporary storage */ { int i; /* This copies samples and replicates every 4th */ /* (and leaves garbage at the end if not a multiple of 4 */ for(i=0; i> 1; *output++ = *input++ >> 1; *output++ = *input++ >> 1; *output++ = *input++ >> 1; input++; } } #endif #ifdef _X86_ void fenetre(short *src,short *fen,short *dest,short lng) { _asm { MOV ESI,[src] MOV EDI,[fen] MOV EBX,[dest] MOV CX,[lng] ; CX : compteur fen_loop: MOV AX,WORD PTR [ESI] ; AX = src IMUL WORD PTR [EDI] ; DX:AX = src*fen ADD AX,16384 ADC DX,0 ; arrondi SHLD DX,AX,1 MOV WORD PTR [EBX],DX ADD ESI,2 ADD EDI,2 ADD EBX,2 DEC CX JNE fen_loop } } #else /* Window the data in buffer */ /* not tested - tfm */ void fenetre(short *src,short *fen,short *dest,short lng) { int i; for(i=0; i>5 MOV AX,CX ; mettre dans EDX:AX ADD AX,16 ; arrondi ADC EDX,0 SAL EDX,11 ; EDX<<11 SAR AX,5 ; AND AX,07FFH OR DX,AX ; EDX = (EBX:CX + 16) >> 5 MOV DWORD PTR [EDI],EDX ADD EDI,4 SUB WORD PTR [lng],1 JG L_VENERGY } } void energy2(short *vech,long *ene,short lng) { _asm { MOV ESI,[vech] ; DS:SI adresse vect. echantillons MOV CX,[lng] ;Initialiser le compteur MOV EBX,0 MOV DI,0 L_ENERGY2: MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source IMUL AX ;Multiplier ADD DI,AX MOVSX EAX,DX ADC EBX,EAX ADD ESI,2 ;Pointer ‚l‚men suiv. DEC CX JNE L_ENERGY2 MOV ESI,[ene] ; adresse result. ; sauver EBX:[LOW_A]>>5 ADD DI,16 ; arrondi ADC EBX,0 SAL EBX,11 ; EBX<<11 SAR DI,5 ; AND DI,07FFH OR BX,DI ; EBX = (EBX:AX + 16) >> 5 MOV DWORD PTR [ESI],EBX } } void upd_ene(long *ener,long *val) { _asm { MOV ESI,[ener] ; DS:SI adresse vect. corr. MOV EDI,[val] ; ES:DI adresse acc et ener. MOV EBX,DWORD PTR [ESI] ; EBX partie H ene MOV AX,WORD PTR [ESI+4] ; AX = partie low MOV CX,WORD PTR [EDI] MOVSX EDX,WORD PTR [EDI+2] ; EDX:CX … ajouter ADD AX,CX ADC EBX,EDX MOV CX,WORD PTR [EDI+4] MOVSX EDX,WORD PTR [EDI+6] ; EDX:CX … retirer SUB AX,CX SBB EBX,EDX MOV DWORD PTR [ESI],EBX MOV WORD PTR [ESI+4],AX } } #pragma warning(disable : 4035) short max_posit(long *vcorr,long *maxval,short pitch,short lvect) { _asm { MOV ESI,[vcorr] ; DS:SI adresse vect. corr. MOV EDI,[maxval] ; ES:DI adresse val max MOV CX,[lvect] ; init compt MOV EAX,DWORD PTR [ESI] ; init max MOV EBX,DWORD PTR [ESI+4] ADD ESI,8 MOV WORD PTR [EDI],CX DEC CX L_MAX_POS: MOV EDX,DWORD PTR [ESI+4] ; EDX = exp. du candidat CMP EDX,EBX JG UPDT_MAX JL NEXT_IND MOV EDX,DWORD PTR [ESI] ; EDX = mantisse CMP EDX,EAX JLE NEXT_IND UPDT_MAX: MOV EAX,DWORD PTR [ESI] MOV EBX,DWORD PTR [ESI+4] MOV WORD PTR [EDI],CX NEXT_IND: ADD ESI,8 DEC CX JNE L_MAX_POS MOV CX,WORD PTR [EDI] NEG CX ADD CX,[lvect] MOV DX,[lvect] SAR DX,1 SUB CX,DX ADD CX,[pitch] MOV DWORD PTR [EDI],EAX MOV DWORD PTR [EDI+4],EBX MOV AX,CX } } #pragma warning(default : 4035) void correlation(short *vech,short *vech2,long *acc,short lng) { short low_a; _asm { MOV ESI,[vech] ; DS:SI adresse vect. echantillons MOV EDI,[vech2] ; ES:DI adresse 2d vect. MOV CX,[lng] ;Initialiser le compteur MOV EBX,0 MOV WORD PTR [low_a],0 L_CORREL: MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source IMUL WORD PTR [EDI] ;Multiplier par l'‚l‚ment d‚cal‚ ADD [low_a],AX MOVSX EAX,DX ADC EBX,EAX ADD ESI,2 ;Pointer ‚l‚men suiv. ADD EDI,2 DEC CX JNE L_CORREL MOV ESI,[acc] ; adresse result. MOV DWORD PTR [ESI],EBX MOV AX,[low_a] MOV WORD PTR [ESI+4],AX } } void schur(short *parcor,long *Ri,short netages) { short cmpt2; _asm { MOV ESI,[Ri] MOV EDI,ESI ADD EDI,44 ; DS:DI for V MOV EBX,DWORD PTR [ESI] ; EBX = R(0) MOV CL,0 CMP EBX,40000000H ;normaliser R(0) JGE OUT_N_R0 NORM_R0: ADD EBX,EBX INC CL CMP EBX,40000000H JL NORM_R0 OUT_N_R0: MOV DWORD PTR [ESI],EBX ;Initialisation de V = R1..Rp MOV DX,[netages] ;Charger ordre p du LPC ADD ESI,4 ;Pointer R1 INIT_V: MOV EAX,DWORD PTR [ESI] ;EAX = Ri SAL EAX,CL MOV DWORD PTR [ESI],EAX ;Sauver dans U[i] MOV DWORD PTR [EDI],EAX ;Sauver dans V[i] ADD ESI,4 ;passer au suivant ADD EDI,4 DEC DX JG INIT_V MOV WORD PTR [cmpt2],1 ;I=1 HANITRA: MOV CX,[netages] ;CX = NETAGES SUB CX,[cmpt2] ;CX = NETAGES-I ADD WORD PTR [cmpt2],1 MOV ESI,[Ri] ;Charger vecteur U MOV EDI,ESI ADD EDI,44 ;Charger vect. V MOV EDX,DWORD PTR [EDI] ; EDX = V(0) MOV EAX,0 SHRD EAX,EDX,1 SAR EDX,1 MOV EBX,DWORD PTR [ESI] ; EBX = S(0) NEG EBX IDIV EBX MOV EBX,EAX ; EBX = KI MOV EAX,DWORD PTR [EDI] ; EAX =V(0) IMUL EBX ; EDX:EAX = PARCOR*V[0] SHLD EDX,EAX,1 ADD EDX,DWORD PTR [ESI] ; EDX = U[0]+V[0]*PARCOR CMP CX,0 JE FINATCR MOV DWORD PTR [ESI],EDX ;Sauver U[0]; EBX = KI LALA: ADD EDI,4 ;Incrementer les pointeurs ADD ESI,4 ; MOV EAX,DWORD PTR [ESI] IMUL EBX ;EDX:EAX = PARCOR*U[I] SHLD EDX,EAX,1 ADD EDX,DWORD PTR [EDI] ;EDX = V[I]+U[I]*PARCOR MOV DWORD PTR [EDI-4],EDX ;Sauver V[I-1]; MOV EAX,DWORD PTR [EDI] IMUL EBX ;EDX:EAX = PARCOR*V[I] SHLD EDX,EAX,1 ADD EDX,DWORD PTR [ESI] ;EDX = U[I]+V[I]*PARCOR MOV DWORD PTR [ESI],EDX ;Sauver U[I]; ST = KI DEC CX JNE LALA MOV EDI,[parcor] ADD EBX,32768 SAR EBX,16 MOV WORD PTR [EDI],BX ; sauver KI ADD DWORD PTR [parcor],2 ;Next KI JMP HANITRA FINATCR: ADD EBX,32768 SAR EBX,16 MOV EDI,[parcor] MOV WORD PTR [EDI],BX ; sauver KI } } void interpol(short *lsp1,short *lsp2,short *dest,short lng) { _asm { MOV ESI,[lsp1] MOV EDI,[lsp2] MOV EBX,[dest] MOV CX,[lng] ; CX : compteur interp_loop: MOVSX EAX,WORD PTR [ESI] ; AX = lsp1 ADD ESI,2 ADD EAX,EAX ; EAX = 2*lsp1 MOVSX EDX,WORD PTR [EDI] ADD EAX,EDX ; EAX = 2*lsp1+lsp2 ADD EDI,2 MOV EDX,21845 ; 21845 = 1/3 IMUL EDX ; EDX:EAX = AX/3 ADD EAX,32768 SAR EAX,16 MOV WORD PTR [EBX],AX ADD EBX,2 DEC CX JNE interp_loop } } void add_sf_vect(short *y1,short *y2,short deb,short lng) { _asm { MOV ESI,[y1] MOV EDI,[y2] MOV CX,[lng] MOVSX EBX,WORD PTR [deb] SUB CX,BX ; CX : compteur ADD BX,BX ADD ESI,EBX ADD_SHFT: MOV AX,WORD PTR [EDI] ADD WORD PTR [ESI],AX ADD ESI,2 ADD EDI,2 DEC CX JNE ADD_SHFT } } void sub_sf_vect(short *y1,short *y2,short deb,short lng) { _asm { MOV ESI,[y1] MOV EDI,[y2] MOV CX,[lng] MOVSX EBX,[deb] SUB CX,BX ; CX : compteur ADD BX,BX ADD ESI,EBX SUB_SHFT: MOV AX,WORD PTR [EDI] SUB WORD PTR [ESI],AX ADD ESI,2 ADD EDI,2 DEC CX JNE SUB_SHFT } } void short_to_short(short *src,short *dest,short lng) { _asm { MOV ESI,[src] MOV EDI,[dest] MOV CX,[lng] ; CX : compteur COPY_LOOP: MOV AX,WORD PTR [ESI] MOV WORD PTR [EDI],AX ADD ESI,2 ADD EDI,2 DEC CX JNE COPY_LOOP } } void inver_v_int(short *src,short *dest,short lng) { _asm { MOV ESI,[src] MOV EDI,[dest] MOV CX,[lng] ; CX : compteur MOVSX EBX,CX DEC EBX ADD EBX,EBX ADD EDI,EBX INVERS_LOOP: MOV AX,WORD PTR [ESI] MOV WORD PTR [EDI],AX ADD ESI,2 SUB EDI,2 DEC CX JNE INVERS_LOOP } } void long_to_long(long *src,long *dest,short lng) { _asm { MOV ESI,[src] MOV EDI,[dest] MOV CX,[lng] ; CX : compteur COPY_LOOP2: MOV EAX,DWORD PTR [ESI] MOV DWORD PTR [EDI],EAX ADD ESI,4 ADD EDI,4 DEC CX JNE COPY_LOOP2 } } void init_zero(short *src,short lng) { _asm { MOV ESI,[src] MOV CX,[lng] ; CX : compteur MOV AX,0 COPY_LOOP3: MOV WORD PTR [ESI],AX ADD ESI,2 DEC CX JNE COPY_LOOP3 } } #if 0 // PhilF: The following is never called!!! void update_dic(short *y1,short *y2,short hy[],short lng,short i0,short fact) { _asm { MOV ESI,[y1] MOV EDI,[y2] MOV CX,[i0] ; CX : compteur MOV DX,CX UPDAT_LOOP1: MOV AX,WORD PTR [EDI] ; y1 = y2 for (i=0..i0-1) MOV WORD PTR [ESI],AX ADD ESI,2 ADD EDI,2 DEC CX JNE UPDAT_LOOP1 MOV EBX,[hy] MOV CX,[lng] SUB CX,DX ; CX = lng-i0 = compteur MOV AX,[fact] ADD AX,0 JL FACT_NEG UPDAT_LOOP2: MOV AX,WORD PTR [EDI] ; AX = y2[i] MOV DX,WORD PTR [EBX] ADD AX,DX ADD AX,DX ; AX = y2[i] + 2*hy[i] MOV WORD PTR [ESI],AX ADD ESI,2 ADD EDI,2 ADD EBX,2 DEC CX JNE UPDAT_LOOP2 JMP FIN_UPDT FACT_NEG: MOV AX,WORD PTR [EDI] ; AX = y2[i] MOV DX,WORD PTR [EBX] SUB AX,DX SUB AX,DX ; AX = y2[i] - 2*hy[i] MOV WORD PTR [ESI],AX ADD ESI,2 ADD EDI,2 ADD EBX,2 DEC CX JNE FACT_NEG FIN_UPDT: } } #endif void update_ltp(short *y1,short *y2,short hy[],short lng,short gdgrd,short fact) { short arrondi; _asm { MOV ESI,[y1] MOV EDI,[y2] MOV BX,[fact] MOV CX,[gdgrd] ; CX = bit de garde ADD CX,0 JE BDG_NUL DEC CL SAR BX,CL ADD BX,1 SAR BX,1 INC CL BDG_NUL: MOV WORD PTR [ESI],BX ADD ESI,2 ADD CL,11 MOV AX,1 SAL AX,CL MOV [arrondi],AX ; [BP-2] = arrondi INC CL SUB WORD PTR [lng],1 MOV BX,[fact] UPDAT_LTP: XCHG ESI,[hy] MOV AX,WORD PTR [ESI] ; AX = hy[i] IMUL BX ; DX:AX = fact*hy ADD AX,[arrondi] ;arrondi ADC DX,0 SHRD AX,DX,CL ADD AX,WORD PTR [EDI] ADD ESI,2 ; increm. ADD EDI,2 XCHG ESI,[hy] MOV WORD PTR [ESI],AX ADD ESI,2 SUB WORD PTR [lng],1 JG UPDAT_LTP } } void proc_gain2(long *corr_ene,long *gain,short bit_garde) { _asm { MOV ESI,[corr_ene] ; DS:SI adresse correlation et energie MOV EAX,0 MOV EBX,DWORD PTR [ESI+4] ;EBX = ener ADD EBX,0 JE G_ENER_NULL2 MOV CX,[bit_garde] ADD CL,19 MOV EAX,DWORD PTR [ESI] ; EAX = corr CDQ SHLD EDX,EAX,CL ; SAL EAX,CL IDIV EBX G_ENER_NULL2: MOV ESI,[gain] ; DS:SI adresse resultat MOV DWORD PTR [ESI],EAX } } #if 0 void proc_gain(long *corr_ene,long *gain) { _asm { MOV ESI,[corr_ene] ; DS:SI adresse correlation et energie MOV EAX,0 MOV EBX,DWORD PTR [ESI+4] ;EBX = ener ADD EBX,0 JE G_ENER_NULL MOV EAX,DWORD PTR [ESI] ; EAX = corr CDQ SHLD EDX,EAX,13 SAL EAX,13 IDIV EBX G_ENER_NULL: MOV ESI,[gain] ; DS:SI adresse resultat MOV DWORD PTR [ESI],EAX } } #else void proc_gain(long *corr_ene,long gain) { _asm { MOV ESI,[corr_ene] MOV EAX,0 MOV EBX,DWORD PTR [ESI+4] ;EBX = energy ADD EBX,0 JLE G_ENER_NULL ; REPLACED JE BY JLE: ENERGY MUST BE POSITIVE MOV EAX,DWORD PTR [ESI] ; EAX = correlation CDQ SHLD EDX,EAX,13 SAL EAX,13 ; ---------------------------------------------- ; AT THIS POINT, EDX:EAX contains the dividend, EBX the divisor. HERE IS THE ADDED CHECK MOV ECX,EDX ; COPY EDX IN ECX CMP ECX,0 ; CHECK SIGN OF ECX JGE G_CORR_POS NEG ECX ; IF ECX IS NEGATIVE, TAKE ABS(ECX) SAL ECX,2 ; AND COMPARE ECX<<2 WITH EBX CMP ECX,EBX ; IF (ECX<<2) >= EBX, THERE IS A RISK OF OVERFLOW, JL G_NO_OVERFLOW ; IN THAT CASE WE SAVE A BIG VALUE IN EAX MOV EAX,-2147483647 ; (NEGATIVE BECAUSE EDX<0) JMP G_ENER_NULL ; AND WE EXIT G_CORR_POS: SAL ECX,2 CMP ECX,EBX ; THE SAME CHECKING FOR THE CASE EDX>0 JL G_NO_OVERFLOW ; BUT HERE WE SAVE A BIG POSITIVE VALUE MOV EAX,2147483647 ; IN CASE OF OVERFLOW JMP G_ENER_NULL G_NO_OVERFLOW: ; END OF ADDED CODE ;------------------------------------------------- IDIV EBX ; IF THERE IS NO RISK OF OVERFLOW, WE MAKE THE DIV G_ENER_NULL: MOV ESI,[gain] MOV DWORD PTR [ESI],EAX } } #endif void decode_dic(short *code,short dic,short npuls) { _asm { MOV ESI,[code] MOVSX ECX,[npuls] DEC ECX ADD ECX,ECX ; CX = deplacement ADD ESI,ECX MOV BX,[dic] ; BX = Dictionnaire MOV AX,1 ; AX = Mask MOV CX,[npuls] ; CX : compteur DEC CX dic_loop: MOV DX,BX ; DX = dec AND DX,AX ; Masquer JNZ NO_NUL ; Saut si non null MOV WORD PTR [ESI],-1 JMP NDAO NO_NUL: MOV WORD PTR [ESI],1 NDAO: SUB ESI,2 ADD AX,AX DEC CX JNE dic_loop } } void dsynthesis(long *z,short *coef,short *input,short *output, short lng,short netages) { short depl,count; _asm { MOV CX,[netages] ; CX = filter order ADD CX,CX ;D‚finir un Deplacement d'adresse vect. source MOV [depl],CX ; [BP-2] = deplacement DSYNTH_GEN: MOV EDI,[z] MOV ESI,[input] ; FS:[SI] input MOVSX EBX,WORD PTR [ESI] ; EBX = entr‚e NEG EBX SAL EBX,16 ADD DWORD PTR [input],2 ; increm. MOV DWORD PTR [EDI],EBX ; mise … jour m‚moire MOV ESI,[coef] MOVSX ECX,[depl] ADD ESI,ECX ADD EDI,ECX ADD EDI,ECX MOV CX,[netages] ;Charger ordre du filtre MOV [count],CX MOV EBX,0 MOV ECX,0 DSYNTHL: MOV EAX,DWORD PTR [EDI] ;EAX = Zi MOV DWORD PTR [EDI+4],EAX ;update memory MOVSX EDX,WORD PTR [ESI] ;EDX = Ai IMUL EDX ;EDX:EAX = Zi*Ai SUB ECX,EAX SBB EBX,EDX ;Acc en EBX:ECX SUB EDI,4 ;Incrementer SUB ESI,2 ; SUB WORD PTR [count],1 JGE DSYNTHL ADD ECX,512 ADC EBX,0 SHLD EBX,ECX,22 ADD EDI,8 MOV DWORD PTR [EDI],EBX ; mise … jour m‚moire MOV ESI,[output] ADD EBX,32768 SAR EBX,16 MOV WORD PTR [ESI],BX ; sauver output ADD DWORD PTR [output],2 SUB WORD PTR [lng],1 ;decrem compt JG DSYNTH_GEN } } void synthesis(short *z,short *coef,short *input,short *output, short lng,short netages,short bdgrd ) { short depl,count,coeff; _asm { MOV CX,[netages] ; CX = filter order ADD CX,CX ;D‚finir un Deplacement d'adresse vect. source MOV [depl],CX ; [BP-2] = deplacement MOV ESI,[coef] MOV AX,WORD PTR [ESI] MOV [coeff],AX MOV CX,[bdgrd] SAR AX,CL MOV WORD PTR [ESI],AX SYNTH_GEN: MOV EDI,[z] MOV ESI,[input] ; FS:[SI] input MOV BX,WORD PTR [ESI] ; BX = entr‚e NEG BX ADD DWORD PTR [input],2 ; increm. MOV WORD PTR [EDI],BX ; mise … jour m‚moire MOV ESI,[coef] ADD SI,[depl] ADD DI,[depl] MOV CX,[netages] ;Charger ordre du filtre MOV [count],CX MOV CX,0 MOV BX,0 SYNTHL: MOV AX,WORD PTR [EDI] ;AX = Zi MOV WORD PTR [EDI+2],AX ;update memory MOV DX,WORD PTR [ESI] ;DX = Ai IMUL DX ;DX:AX = Zi*Ai SUB BX,AX SBB CX,DX ;acc. en CX:BX SUB EDI,2 ;Incrementer SUB ESI,2 ; SUB WORD PTR [count],1 ;Decrem. compt. JGE SYNTHL ADD BX,512 ;arrondi ADC CX,0 SHRD BX,CX,10 ADD EDI,4 MOV WORD PTR [EDI],BX ; mise … jour m‚moire MOV ESI,[output] MOV WORD PTR [ESI],BX ; sauver output ADD DWORD PTR [output],2 SUB WORD PTR [lng],1 ;Decrem. compt. JG SYNTH_GEN MOV ESI,[coef] MOV AX,[coeff] MOV WORD PTR [ESI],AX } } void synthese(short *z,short *coef,short *input,short *output, short lng,short netages) { short depl,count; _asm { MOV CX,[netages] ; CX = filter order ADD CX,CX ;D‚finir un Deplacement d'adresse vect. source MOV [depl],CX ; [BP-2] = deplacement SYNTH_GEN2: MOV EDI,[z] MOV ESI,[input] ; FS:[SI] input MOV BX,WORD PTR [ESI] ; BX = entr‚e NEG BX ADD DWORD PTR [input],2 ; increm. MOV WORD PTR [EDI],BX ; mise … jour m‚moire MOV ESI,[coef] ADD SI,[depl] ADD DI,[depl] MOV CX,[netages] ;Charger ordre du filtre MOV [count],CX MOV CX,0 MOV BX,0 SYNTHL2: MOV AX,WORD PTR [EDI] ;AX = Zi MOV WORD PTR [EDI+2],AX ;update memory MOV DX,WORD PTR [ESI] ;DX = Ai IMUL DX ;DX:AX = Zi*Ai SUB BX,AX SBB CX,DX ;acc. en CX:BX SUB EDI,2 ;Incrementer SUB ESI,2 ; SUB WORD PTR [count],1 ;Decrem. compt. JGE SYNTHL2 ADD BX,512 ;arrondi ADC CX,0 SHRD BX,CX,10 ADD EDI,4 MOV WORD PTR [EDI],BX ; mise … jour m‚moire MOV ESI,[output] MOV WORD PTR [ESI],BX ; sauver output ADD DWORD PTR [output],2 SUB WORD PTR [lng],1 ;Decrem. compt. JG SYNTH_GEN2 } } void f_inverse(short *z,short *coef,short *input,short *output, short lng,short netages ) { short depl,count; _asm { MOV CX,[netages] ; CX = filter order ADD CX,CX ; D‚finir un Deplacement d'adresse vect. source MOV [depl],CX ; [BP-2] = deplacement INVER_GEN: MOV EDI,[z] MOV ESI,[input] ; FS:[SI] input MOV BX,WORD PTR [ESI] ; BX = entr‚e ADD DWORD PTR [input],2 ; increm. MOV WORD PTR [EDI],BX ; mise … jour m‚moire MOV ESI,[coef] ADD SI,[depl] ADD DI,[depl] MOV CX,[netages] ;Charger ordre du filtre MOV [count],CX ;BP-4 : compteur MOV CX,0 MOV BX,0 INVERL: MOV AX,WORD PTR [EDI] ;AX = Zi MOV WORD PTR [EDI+2],AX ;update memory MOV DX,WORD PTR [ESI] ;DX = Ai IMUL DX ;DX:AX = Zi*Ai ADD CX,AX ADC BX,DX ; acc. en BX:CX SUB EDI,2 ;Incrementer SUB ESI,2 ; SUB WORD PTR [count],1 JGE INVERL MOV ESI,[output] ADD CX,512 ;arrondi ADC BX,0 SHRD CX,BX,10 MOV WORD PTR [ESI],CX ; sauver output ADD DWORD PTR [output],2 SUB WORD PTR [lng],1 ;decrem. JG INVER_GEN } } void filt_iir(long *zx,long *ai,short *Vin,short *Vout,short lfen,short ordre) { long off_coef,off_mem,delta; long acc_low; _asm { MOVSX ECX,[ordre] ;ordre du filtre SAL ECX,3 ;D‚finir un Deplacement d'adresse MOV [off_coef],ECX ; [OFF_COEF] = deplacement pour coeff ADD ECX,4 MOV [off_mem],ECX ; [OFF_MEM] = depl. pour mem. ADD ECX,20 SAR ECX,1 MOV [delta],ECX IIR_FIL: MOV CX,[ordre] ;init compteur MOV EBX,[Vin] ; BX = offset input MOVSX EDX,WORD PTR [EBX] ; EDX = input avec extension de signe ADD DWORD PTR [Vin],2 ; incr‚menter l'offset de input MOV ESI,[zx] ; DS:SI pointe zx MOV DWORD PTR [ESI],EDX ; mettre … jour zx MOV EDI,[ai] ; ES:DI pointe coeff ADD EDI,[off_coef] ADD ESI,[off_mem] MOV DWORD PTR [acc_low],0 ; initialiser ACC_LOW … 0 SUB EBX,EBX ; init EBX = 0 F_IIR_Y: MOV EAX,DWORD PTR [ESI] ;EAX = *zx MOV DWORD PTR [ESI+4],EAX ;mettre … jour zx MOV EDX,DWORD PTR [EDI] ;EDX = coeff IMUL EDX ;EDX:EAX = zx*coeff SUB [acc_low],EAX ; accumuler les LSB SBB EBX,EDX ; acc avec borrow les MSB SUB EDI,4 ;Incrementer SUB ESI,4 ; DEC CX JNE F_IIR_Y SUB ESI,4 MOV CX,[ordre] ;Charger ordre du filtre INC CX F_IIR_X: MOV EAX,DWORD PTR [ESI] ;EAX = *zy MOV DWORD PTR [ESI+4],EAX ;update zy MOV EDX,DWORD PTR [EDI] ;EDX = coeff IMUL EDX ;EDS:EAX = zy*coeff ADD [acc_low],EAX ;acc LSB ADC EBX,EDX ;acc avec carry MSB SUB EDI,4 ;Decrementer SUB ESI,4 ; DEC CX JNE F_IIR_X MOV EAX,[delta] ADD ESI,EAX MOV EAX,[acc_low] ; EAX = LSB de l'acc. ADD EAX,8192 ; arrondi ADC EBX,0 SHRD EAX,EBX,14 ; cadrer MOV DWORD PTR [ESI],EAX ; mettre … jour zy SAR EAX,14 ; cadrer en x4.0 ; logique saturante CMP EAX,32767 JG SATUR_POS ; jump if ov CMP EAX,-32767 JL SATUR_NEG JMP NEXT SATUR_POS: MOV AX,32767 JMP NEXT SATUR_NEG: MOV AX,-32767 JMP NEXT NEXT: MOV ESI,[Vout] ;di offset output MOV WORD PTR [ESI],AX ;sauver output ADD DWORD PTR [Vout],2 ;incr‚menter offset SUB WORD PTR [lfen],1 JNZ IIR_FIL } } #if 0 // PhilF: The following is never called!!! void filt_iir_a(long *zx,long *ai,short *Vin,short *Vout,short lfen,short ordre) { short off_coef,off_mem,delta; long acc_low; _asm { MOV CX,[ordre] ;ordre du filtre SAL CX,3 ;D‚finir un Deplacement d'adresse MOV [off_coef],CX ; [OFF_COEF] = deplacement pour coeff ADD CX,4 MOV [off_mem],CX ; [OFF_MEM] = depl. pour mem. ADD CX,20 SAR CX,1 MOV [delta],CX A_IIR_FIL: MOV CX,[ordre] ;init compteur MOV EBX,[Vin] ; BX = offset input MOVSX EDX,WORD PTR [EBX] ; EDX = input avec extension de signe ADD WORD PTR [Vin],2 ; incr‚menter l'offset de input MOV ESI,[zx] ; DS:SI pointe zx MOV DWORD PTR [ESI],EDX ; mettre … jour zx MOV EDI,[ai] ; ES:DI pointe coeff ADD DI,[off_coef] ADD SI,[off_mem] MOV DWORD PTR [acc_low],0 ; initialiser ACC_LOW … 0 SUB EBX,EBX ; init EBX = 0 F_IIR_Y_A: MOV EAX,DWORD PTR [ESI] ;EAX = *zx MOV DWORD PTR [ESI+4],EAX ;mettre … jour zx MOV EDX,DWORD PTR [EDI] ;EDX = coeff IMUL EDX ;EDX:EAX = zx*coeff SUB [acc_low],EAX ; accumuler les LSB SBB EBX,EDX ; acc avec borrow les MSB SUB EDI,4 ;Incrementer SUB ESI,4 ; DEC CX JNE F_IIR_Y_A SUB ESI,4 MOV CX,[ordre] ;Charger ordre du filtre INC CX F_IIR_X_A: MOV EAX,DWORD PTR [ESI] ;EAX = *zy MOV DWORD PTR [ESI+4],EAX ;update zy MOV EDX,DWORD PTR [EDI] ;EDX = coeff IMUL EDX ;EDS:EAX = zy*coeff ADD [acc_low],EAX ;acc LSB ADC EBX,EDX ;acc avec carry MSB SUB EDI,4 ;Decrementer SUB ESI,4 ; DEC CX JNE F_IIR_X_A MOVSX EAX,[delta] ADD ESI,EAX MOV EAX,[acc_low] ; EAX = LSB de l'acc. ADD EAX,8192 ; arrondi ADC EBX,0 SHRD EAX,EBX,14 ; cadrer MOV DWORD PTR [ESI],EAX ; mettre … jour zy ADD EAX,32768 SAR EAX,16 ; cadrer en x4.0 MOV ESI,[Vout] ;di offset output MOV WORD PTR [ESI],AX ;sauver output ADD WORD PTR [Vout],2 ;incr‚menter offset SUB WORD PTR [lfen],1 JNZ A_IIR_FIL } } #endif void mult_fact(short src[],short dest[],short fact,short lng) { _asm { MOV ESI,[src] MOV EDI,[dest] MOV BX,[fact] ; BX = Factor MOV CX,[lng] ; init compteur MULT_F: MOV AX,WORD PTR [ESI] ; AX = src IMUL BX ; DX:AX = src*fact ADD AX,4096 ADC DX,0 SHRD AX,DX,13 ; cadrer MOV WORD PTR [EDI],AX ;save ADD ESI,2 ;incr‚menter ADD EDI,2 DEC CX JNE MULT_F } } void mult_f_acc(short src[],short dest[],short fact,short lng) { _asm { MOV EDI,[src] MOV ESI,[dest] MOV BX,[fact] ; BX = Factor MOV CX,[lng] ; init compteur MULT_F_A: MOV AX,WORD PTR [EDI] ; AX = src IMUL BX ; DX:AX = src*fact ADD AX,4096 ADC DX,0 SHRD AX,DX,13 ; cadrer ADD WORD PTR [ESI],AX ; Accumuler dest = dest + src*fact ADD ESI,2 ;incr‚menter ADD EDI,2 DEC CX JNE MULT_F_A } } void dec_lsp(short *code,short *tablsp,short *nbit,short *bitdi,short *tabdi) { short compt; long pointer; _asm { MOV EDI,[tablsp] MOV ESI,[code] MOVSX EBX,WORD PTR [ESI] ; BX = depl. ADD EBX,EBX MOV AX,WORD PTR [EDI+EBX] ; AX = code[0]; MOV WORD PTR [ESI],AX ; ADD ESI,4 ; MOV CX,4 ; init compteur LSP_PAIR: MOV EBX,[nbit] ; lsptab += nbit[i] MOVSX EAX,WORD PTR [EBX] ; AX = nbit[i] ADD EAX,EAX ADD EDI,EAX ; ADD EBX,2 ; increm MOV [nbit],EBX MOVSX EBX,WORD PTR [ESI] ; BX = depl. ADD EBX,EBX MOV AX,WORD PTR [EDI+EBX] ; AX = code[i]; MOV WORD PTR [ESI],AX ; ADD ESI,4 DEC CX JNE LSP_PAIR ADD DWORD PTR [nbit],2 MOV EDI,[tabdi] SUB ESI,20 ; pointer code[0] MOV WORD PTR [compt],5 REPEAT_DEC: MOV EBX,[bitdi] MOV CX,WORD PTR [EBX] ; MOV BX,WORD PTR [ESI+4] ; BX = lsp[2*k+2] SUB BX,WORD PTR [ESI] ; = lsp[2*k+2]-lsp[2*k] = delta ; ne pas faire /2 --> pas de corr. signe * MOV EAX,[nbit] MOV [pointer],EAX LOOP_DI1: MOV AX,WORD PTR [EDI] ; AX = TABDI ADD EDI,2 IMUL BX ; DX:AX = tabdi * delta ADD AX,32768 ADC DX,0 ;arrondi ADD DX,WORD PTR [ESI] XCHG ESI,[pointer] MOV WORD PTR [ESI],DX ; sauver ADD ESI,2 XCHG ESI,[pointer] DEC CX JNE LOOP_DI1 MOV DX,BX MOV EBX,[bitdi] MOV CX,WORD PTR [EBX] ; ADD ESI,4 SUB CX,2 JLE IALAO MOV BX,DX NEG BX LOOP_DI2: MOV AX,WORD PTR [EDI] ; AX = TABDI ADD EDI,2 IMUL BX ; DX:AX = tabdi * delta ADD DX,WORD PTR [ESI] XCHG ESI,[pointer] MOV WORD PTR [ESI],DX ; sauver ADD ESI,2 XCHG ESI,[pointer] DEC CX JNE LOOP_DI2 IALAO: ADD DWORD PTR [bitdi],2 ; MOV EBX,[nbit] ; BX = adresse de veclsp SUB ESI,2 ; pointer code[2*k+1] MOVSX EAX,WORD PTR [ESI] ADD EAX,EAX ; AX = depl. ADD EBX,EAX MOV AX,WORD PTR [EBX] ; AX = veclsp[code[2*k+1] MOV WORD PTR [ESI],AX ADD ESI,2 SUB WORD PTR [compt],1 JNZ REPEAT_DEC } } void teta_to_cos(short *tabcos,short *lsp,short netages) { short norm,arrondi,ptm1,lts2; _asm { MOV EDI,[lsp] MOV CX,[netages] ;init compteur TETA_LOOP: MOV AX,WORD PTR [EDI] ; AX = lsp[i] CMP AX,04000H ; comparer … 4000h JLE INIT_VAL ; NEG AX ADD AX,32767 ; prendre le compl‚ment INIT_VAL: MOV ESI,[tabcos] CMP AX,0738H ; comparer … JG BIGTABLE ;SMALLTAB: ADD ESI,550 ; pointer tabteta2 MOV WORD PTR [ptm1],3 MOV WORD PTR [lts2],16 MOV WORD PTR [arrondi],512 MOV WORD PTR [norm],10 JMP DEBUT_LP BIGTABLE: ADD ESI,258 ; pointer tabteta1 MOV WORD PTR [ptm1],6 MOV WORD PTR [lts2],128 MOV WORD PTR [arrondi],64 MOV WORD PTR [norm],7 DEBUT_LP: MOVSX EDX,[lts2] ; init incr‚ment ADD ESI,EDX ; SI = index MOV CX,[ptm1] LOCAL_L: SAR EDX,1 ; increm >> 1 CMP AX,WORD PTR [ESI] JG ADD_INCRM SUB ESI,EDX JMP AURORA ADD_INCRM: ADD ESI,EDX AURORA: DEC CX JNE LOCAL_L CMP AX,WORD PTR [ESI] JG INTERP_V SUB ESI,2 INTERP_V: SUB AX,WORD PTR [ESI] ; AX = teta - tabteta[index] MOV DX,AX MOV AX,0 MOV CX,WORD PTR [ESI+2] SUB CX,WORD PTR [ESI] ; CX = tabteta[index+1]-tabteta[index] ADD CX,CX ; multiplier par 2 pour ne pas SHRD de DX:AX DIV CX ADD AX,[arrondi] ; MOV CX,[norm] ; CX = normalisation SAR AX,CL NEG AX CMP CX,7 JE GRAN_TAB SUB ESI,34 ADD AX,WORD PTR [ESI] ;AX = tabcos[index]+delta JMP ADD_SIGN GRAN_TAB: SUB ESI,258 ADD AX,WORD PTR [ESI] ;AX = tabcos[index]+delta ADD_SIGN: CMP WORD PTR [EDI],04000H JLE END_LOOP NEG AX END_LOOP: MOV WORD PTR [EDI],AX ; save cos ADD EDI,2 SUB WORD PTR [netages],1 JG TETA_LOOP } } void cos_to_teta(short *tabcos,short *lsp,short netages) { _asm { MOV EDI,[lsp] MOV CX,[netages] ;init compteur COS_LOOP: MOV ESI,[tabcos] ADD ESI,258 MOV AX,WORD PTR [EDI] ; AX = lsp[i] ADD AX,0 JGE DEBUT_CS ; prendre ABS NEG AX DEBUT_CS: CMP AX,07DFFH ; comparer … 7DFFh JGE TABLE2 ;TABLE1: MOV BX,AX AND BX,0FFH ; BX = cos & mask MOV CL,8 SAR AX,CL ADD AX,AX MOV EDX,256 ; BX index SUB DX,AX ADD ESI,EDX MOV AX,WORD PTR [ESI] ; AX=teta[index] SUB AX,WORD PTR [ESI-2] ; IMUL BX ADD AX,128 ADC DX,0 SHRD AX,DX,8 ; cadrer NEG AX MOV BX,WORD PTR [ESI] ADD AX,BX MOV BX,WORD PTR [EDI] ; tester signe de lsp ADD BX,0 JGE END_COS NEG AX ADD AX,07FFFH ; AX = 7fff-AX JMP END_COS TABLE2: ADD ESI,292 ; pointer tabteta2 MOV BX,AX ; BX = AX SUB AX,07DFFH ; retirer delta MOV CL,5 SAR AX,CL ADD AX,AX MOV EDX,32 ; DX index SUB DX,AX ADD ESI,EDX MOV AX,WORD PTR [ESI] ; AX=teta2[index] CMP BX,AX JGE NO_INCRM ADD ESI,2 NO_INCRM: MOV AX,WORD PTR [ESI] ; AX=teta2[index] MOV CX,AX ; pour plus tard SUB AX,WORD PTR [ESI-2] ; SUB ESI,34 ; pointer tabcos2 SUB BX,WORD PTR [ESI] ; IMUL BX ADD AX,16 ADC DX,0 SHRD AX,DX,5 ; cadrer NEG AX ADD AX,CX ; AX = cos + delta MOV BX,WORD PTR [EDI] ; tester signe de lsp ADD BX,0 JGE END_COS NEG AX ADD AX,07FFFH ; AX = 7fff-AX END_COS: MOV WORD PTR [EDI],AX ; ADD EDI,2 SUB WORD PTR [netages],1 JG COS_LOOP } } void lsp_to_ai(short *ai_lsp,long *tmp,short netages) { short cmptr; long index; _asm { MOV ESI,[tmp] MOV EBX,ESI ADD EBX,4*11 ;DS:BX vect. Q MOV EDI,[ai_lsp] ;LSP_AI: MOV DWORD PTR [ESI],0400000H ; P(0) = 1 MOV DWORD PTR [ESI+8],0400000H ; P(2) = 1 MOV DWORD PTR [EBX],0400000H ; Q(0) = 1 MOV DWORD PTR [EBX+8],0400000H ; Q(2) = 1 MOVSX EAX,WORD PTR [EDI] ; EAX = lsp(0) SAL EAX,8 NEG EAX ; EAX = -lsp(0)>>8 MOV DWORD PTR [ESI+4],EAX ;P(1) = EAX MOVSX EAX,WORD PTR [EDI+2] ; EAX = lsp(1) SAL EAX,8 NEG EAX ; EAX = -lsp(1)>>8 MOV DWORD PTR [EBX+4],EAX ; Q(1) = EAX MOV WORD PTR [cmptr],1 ;init compteur SUB WORD PTR [netages],2 ADD EBX,8 MOV [index],EBX ; sauver BX = i ADD ESI,8 ; DS:SI P(2) ADD EDI,4 ; ES:DI lsp(2) MOV CX,[netages] GL_LOOP: MOV [netages],CX MOV DWORD PTR [ESI+8],0400000H ; P(i+2) = 1 MOVSX EAX,WORD PTR [EDI] ; EAX = lsp(i) MOV EBX,EAX ; memoriser lsp(i) SAL EAX,8 MOV ECX,DWORD PTR [ESI-4] ; ECX = P(i-1) SUB ECX,EAX ; ECX = P(i-1) - lsp(i)<<8 MOV DWORD PTR [ESI+4],ECX ; P(i+1)=ECX MOV CX,[cmptr] ; LOCAL_P: MOV EAX,DWORD PTR [ESI-4] ; EAX = P(j-1) IMUL EBX ; EDX:EAX = P(j-1)*lsp(i) ADD EAX,8192 ADC EDX,0 SHRD EAX,EDX,14 ; EAX = 2*P(j-1)*lsp(i) SUB DWORD PTR [ESI],EAX ; P(j)=P(j)-EAX MOV EAX,DWORD PTR [ESI-8] ; EAX = P(j-2) ADD DWORD PTR [ESI],EAX ; P(j) += P(j-2) SUB ESI,4 DEC CX JNE LOCAL_P ; DS:SI pointe P(1) MOV EAX,DWORD PTR [ESI-4] ; EAX = P(0) IMUL EBX ; EDX:EAX = P(0)*lsp(i) ADD EAX,8192 ADC EDX,0 SHRD EAX,EDX,14 ; EAX = 2*P(0)*lsp(i) SUB DWORD PTR [ESI],EAX ; P(1) = P(1)-2*P(0)*lsp(i) XCHG ESI,[index] ; DS:SI pointe Q(j) MOV DWORD PTR [ESI+8],0400000H ; Q(i+2) = 1 MOVSX EAX,WORD PTR [EDI+2] ; EAX = lsp(i+1) MOV EBX,EAX ; memoriser lsp(i+1) SAL EAX,8 MOV ECX,DWORD PTR [ESI-4] ; ECX = Q(i-1) SUB ECX,EAX ; ECX = Q(i-1) - lsp(i+1)<<8 MOV DWORD PTR [ESI+4],ECX ; Q(i+1)=ECX MOV CX,[cmptr] ; LOCAL_Q: MOV EAX,DWORD PTR [ESI-4] ; EAX = Q(j-1) IMUL EBX ; EDX:EAX = Q(j-1)*lsp(i+1) ADD EAX,8192 ADC EDX,0 SHRD EAX,EDX,14 ; EAX = 2*Q(j-1)*lsp(i+1) SUB DWORD PTR [ESI],EAX ; Q(j)=Q(j)-EAX MOV EAX,DWORD PTR [ESI-8] ; EAX = Q(j-2) ADD DWORD PTR [ESI],EAX ; Q(j) += Q(j-2) SUB ESI,4 DEC CX JNE LOCAL_Q ; DS:SI pointe Q(1) MOV EAX,DWORD PTR [ESI-4] ; EAX = Q(0) IMUL EBX ; EDX:EAX = Q(0)*lsp(i+1) ADD EAX,8192 ADC EDX,0 SHRD EAX,EDX,14 ; EAX = 2*Q(0)*lsp(i+1) SUB DWORD PTR [ESI],EAX ; Q(1) = Q(1)-2*Q(0)*lsp(i+1) MOVSX ECX,[cmptr] ADD CX,2 MOV [cmptr],CX SAL ECX,2 ADD ESI,ECX ; increm. offset de Q XCHG ESI,[index] ; ADD ESI,ECX ; increm. offset de P ADD EDI,4 MOV CX,[netages] SUB CX,2 JG GL_LOOP MOV ESI,[tmp] ;DS:SI vect P MOV EBX,ESI ADD EBX,4*11 ;DS:BX vect. Q MOV EDI,[ai_lsp] ;ES:DI lsp et ai MOV WORD PTR [EDI],0400H ; ai(0) = 1 ADD EDI,2 MOV CX,10 ; init compteur ADD EBX,4 ; ADD ESI,4 CALC_AI: MOV EAX,DWORD PTR [ESI] ; EAX = P(i) ADD EAX,DWORD PTR [ESI-4] ; +P(i-1) ADD EAX,DWORD PTR [EBX] ; +Q(i) SUB EAX,DWORD PTR [EBX-4] ; -Q(i-1) ADD EAX,01000H ; arrondi SAR EAX,13 MOV WORD PTR [EDI],AX ; save ai ADD EDI,2 ADD ESI,4 ADD EBX,4 DEC CX JNE CALC_AI } } void ki_to_ai(short *ki,long *ai,short netages) { short cmptk; long indam1,indexk,kiim1; _asm { MOV ESI,[ai] MOV EBX,ESI ADD EBX,44 ; DS:BX vect. interm. MOV EDI,[ki] MOV DWORD PTR [ESI],0400000H ; ai(0) = 1 MOVSX EAX,WORD PTR [EDI] ; EAX = ki(0) SAL EAX,7 MOV DWORD PTR [ESI+4],EAX ; ai(1) = EAX ADD ESI,4 ; DS:SI ai(1) ADD EBX,8 ADD EDI,2 ; ES:DI ki(1) MOV WORD PTR [cmptk],1 MOV CX,[netages] KI_AI_LP: MOV [netages],CX MOVSX EAX,WORD PTR [EDI] ; EAX = ki(i-1) MOV [kiim1],EAX ; memoriser ki(i-1) SAL EAX,7 MOV DWORD PTR [EBX],EAX ; tmp(i)=EAX SUB EBX,4 MOV [indexk],EBX MOVSX ECX,[cmptk] ; MOV EBX,ECX DEC EBX SAL EBX,2 ; DI : deplacement MOV [indam1],ESI SUB ESI,EBX MOV EBX,[indexk] LOCAL_AI: MOV EAX,DWORD PTR [ESI] ; EAX = ai(i-j) IMUL DWORD PTR [kiim1] ; EDX:EAX = ai(i-j)*ki(i-1) ADD EAX,16384 ADC EDX,0 SHRD EAX,EDX,15 ; EAX = ai(i-j)*ki(i-1) ADD ESI,4 XCHG ESI,[indam1] ADD EAX,DWORD PTR [ESI] ; + ai(j) SUB ESI,4 XCHG ESI,[indam1] MOV DWORD PTR [EBX],EAX ; tmp(j) = EAX SUB EBX,4 DEC CX JNE LOCAL_AI XCHG ESI,[indam1] MOV CX,[cmptk] INC CX MOV [cmptk],CX ADD ESI,4 ADD EBX,4 L_COPY: MOV EAX,DWORD PTR [EBX] ; EAX = tmp(i) MOV DWORD PTR [ESI],EAX ; ai(i) = EAX ADD EBX,4 ADD ESI,4 DEC CX JNE L_COPY ADD EDI,2 ; increm. i SUB ESI,4 MOV CX,[netages] DEC CX JNE KI_AI_LP } } void ai_to_pq(long *aip,short netages) { _asm { MOV ESI,[aip] MOV EDI,ESI ADD EDI,4*11 ;DS:DI vect. Q MOV EDX,DWORD PTR [ESI] ; EAX = ai(0) = P(0) MOV DWORD PTR [EDI],EDX ; Q(0) = ai(0) MOV CX,[netages] MOVSX EBX,CX DEC EBX SAL EBX,2 ; BX deplacement ADD ESI,4 ADD EDI,4 SAR CX,1 AI_LSP1: MOV EAX,DWORD PTR [ESI] ; EAX = ai(i) = P(i) MOV EDX,EAX ; memoriser ADD EAX,DWORD PTR [ESI+EBX] ; + ai(j) SUB EAX,DWORD PTR [ESI-4] ; - P(i-1) MOV DWORD PTR [ESI],EAX ; P(i)=EAX SUB EDX,DWORD PTR [ESI+EBX] ; EDX = ai(i) - ai(j) ADD EDX,DWORD PTR [EDI-4] ; - Q(i-1) MOV DWORD PTR [EDI],EDX ; Q(i)=EDX SUB EBX,8 ADD ESI,4 ADD EDI,4 DEC CX JNE AI_LSP1 MOV ESI,[aip] ;DS:SI vect. PP = P MOV EAX,DWORD PTR [ESI+20] ;EAX = P(5) ADD EAX,1 SAR EAX,1 SUB EAX,DWORD PTR [ESI+12] ;EAX = P(5)/2 - P(3) ADD EAX,DWORD PTR [ESI+4] ; + P(1) XCHG DWORD PTR [ESI],EAX ; PP(0) = EAX et EAX = P(0) MOV EBX,EAX ; save EBX = P(0) SAL EAX,2 ; EAX = 2*P(0) ADD EAX,EBX ; EAX = 5*P(0) ADD EAX,DWORD PTR [ESI+16] ; + P(4) MOV EDX,DWORD PTR [ESI+8] ; EDX = P(2) ADD EDX,EDX ; *2 ADD EDX,DWORD PTR [ESI+8] ; EDX = 3*P(2) SUB EAX,EDX ; EAX = P(4) - 3*P(2) + 5*P(0) XCHG EAX,DWORD PTR [ESI+4] ; PP(1)=EAX et EAX = P(1) MOV ECX,EAX ; ECX = P(1) SAL EAX,3 ; *8 MOV DWORD PTR [ESI+16],EAX ; PP(4) = 8*P(1) NEG EAX MOV EDX,DWORD PTR [ESI+12] ; EDX = P(3) ADD EDX,EDX ; * 2 ADD EAX,EDX ; EAX = 2*P(3) - 8*P(1) XCHG EAX,DWORD PTR [ESI+8] ; PP(2) = EAX et EAX = P(2) SAL EAX,2 ; EAX *= 4*P(2) SAL EBX,2 ; EBX = 4*P0 MOV EDX,EBX ; EDX = 4*P(0) SAL EDX,2 ; EDX = 16*P(0) MOV DWORD PTR [ESI+20],EDX ; PP(5) = 16*P(0) ADD EBX,EDX ; EDX = 20*P(0) NEG EBX ADD EAX,EBX MOV DWORD PTR [ESI+12],EAX ; PP(3) = 4*P(2)-20*P(0) MOV EDI,ESI ADD ESI,4*11 ;DS:SI vect. Q ADD EDI,4*6 ;DS:DI vect QQ MOV EAX,DWORD PTR [ESI+20] ;EAX = Q(5) ADD EAX,1 SAR EAX,1 SUB EAX,DWORD PTR [ESI+12] ;EAX = Q(5)/2 - Q(3) ADD EAX,DWORD PTR [ESI+4] ; + Q(1) MOV DWORD PTR [EDI],EAX ; QQ(0) = EAX MOV EAX,DWORD PTR [ESI] ; EAX = Q(0) MOV EBX,EAX SAL EAX,2 ; EAX = 2*Q(0) ADD EAX,DWORD PTR [ESI] ; EAX = 5*Q(0) ADD EAX,DWORD PTR [ESI+16] ; + Q(4) MOV EDX,DWORD PTR [ESI+8] ; EDX = Q(2) ADD EDX,EDX ; *2 ADD EDX,DWORD PTR [ESI+8] ; EDX = 3*Q(2) SUB EAX,EDX ; EAX = Q(4) - 3*Q(2) + 5*Q(0) MOV DWORD PTR [EDI+4],EAX ; QQ(1)=EAX MOV EAX,DWORD PTR [ESI+4] ; EAX = Q(1) MOV ECX,EAX ; ECX = Q(1) SAL EAX,3 ; *8 MOV DWORD PTR [EDI+16],EAX ; QQ(4) = 8*Q(1) NEG EAX MOV EDX,DWORD PTR [ESI+12] ; EDX = Q(3) ADD EDX,EDX ; * 2 ADD EAX,EDX ; EAX = 2*Q(3) - 8*Q(1) MOV DWORD PTR [EDI+8],EAX ; QQ(2) = EAX MOV EAX,DWORD PTR [ESI+8] ; EAX = Q(2) SAL EAX,2 ; EAX *= 4*Q(2) SAL EBX,2 ; EBX = 4*Q0 MOV EDX,EBX ; EDX = 4*Q(0) SAL EDX,2 ; EDX = 16*Q(0) MOV DWORD PTR [EDI+20],EDX ; QQ(5) = 16*Q(0) ADD EBX,EDX ; EDX = 20*Q(0) NEG EBX ADD EAX,EBX MOV DWORD PTR [EDI+12],EAX ; QQ(3) = 4*Q(2)-20*Q(0) } } void horner(long *P,long *T,long *a,short n,short s) { _asm { MOV ESI,[P] MOV EDI,[T] MOV CX,[n] MOVSX EBX,CX SAL EBX,2 ADD ESI,EBX ; SI : P(n) SUB EBX,4 ADD EDI,EBX ; DI : Q(n-1) MOV EAX,DWORD PTR [ESI] ; EAX = P(n) MOV DWORD PTR [EDI],EAX ; Q(n-1) = P(n) SUB ESI,4 DEC CX MOVSX EBX,WORD PTR [s] LOOP_HNR: MOV EAX,DWORD PTR [EDI] ; EAX = Q(i) IMUL EBX ; EDX:EAX = s*Q(i) ADD EAX,16384 ; ADC EDX,0 SHRD EAX,EDX,15 ; cadrer SUB EDI,4 ADD EAX,DWORD PTR [ESI] ; EAX = Q(i) = P(i) + s*Q(i) MOV DWORD PTR [EDI],EAX ; SUB ESI,4 DEC CX JNE LOOP_HNR MOV EAX,DWORD PTR [EDI] ; EAX = Q(0) IMUL EBX ; EDX:EAX = s*Q(0) ADD EAX,16384 ; ADC EDX,0 SHRD EAX,EDX,15 ; cadrer ADD EAX,DWORD PTR [ESI] ; EAX = P(0) + s*Q(0) MOV ESI,[a] MOV DWORD PTR [ESI],EAX } } #pragma warning(disable : 4035) short calcul_s(long a,long b) { _asm { MOV EBX,[b] ADD EBX,0 JGE B_POSIT NEG EBX B_POSIT: MOV CL,0 CMP EBX,40000000H ;normaliser b JGE OUT_NORM NORM_B: ADD EBX,EBX INC CL CMP EBX,40000000H ; JGE OUT_NORM JMP NORM_B OUT_NORM: ADD EBX,16384 SAR EBX,15 MOV EDX,[b] ADD EDX,0 JGE PUT_SIGN NEG EBX PUT_SIGN: MOV EAX,[a] SAL EAX,CL ; shifter a de CL CDQ IDIV EBX ; AX = a/b MOV BX,AX IMUL BX ; DX:AX = sqr(a/b) ADD AX,8192 ADC DX,0 SHRD AX,DX,14 ; AX = 2*sqr(a/b) MOV DX,AX ADD DX,1 SAR DX,1 ADD AX,DX ; AX = 3*sqr(a/b) NEG AX SUB AX,BX ; AX = -a/b - 3*sqr(a/b) } } #pragma warning(default : 4035) void binome(short *lsp,long *PP) { short inc_sq; long sqr; _asm { MOV EDI,[lsp] MOV ESI,[PP] MOV EBX,DWORD PTR [ESI+8] ;EBX = PP(2) ADD EBX,0 JGE B_POSIT_P NEG EBX B_POSIT_P: MOV CL,0 CMP EBX,40000000H ;normaliser PP(2) JGE OUT_NORM_P NORM_B_P: ADD EBX,EBX INC CL CMP EBX,40000000H ; JGE OUT_NORM_P JMP NORM_B_P OUT_NORM_P: ADD EBX,16384 SAR EBX,15 MOV EDX,DWORD PTR [ESI+8] ADD EDX,0 JGE PUT_SIGN_P NEG EBX PUT_SIGN_P: ; BX = PP(2) MOV EAX,DWORD PTR [ESI] ; EAX = PP(0) SAL EAX,CL ; shifter a de CL CDQ IDIV EBX ; AX = PP(0)/PP(2) NEG AX MOV WORD PTR [EDI],AX ; ES:[DI] = -PP(0)/PP(2) MOV EAX,DWORD PTR [ESI+4] ; EAX = PP(1) SAL EAX,CL ; shifter a de CL SAR EAX,1 CDQ IDIV EBX NEG EAX ; va = AX = -PP(1)/2*PP(2) MOV DWORD PTR [ESI],EAX MOV CX,WORD PTR [EDI] ; vb = CX = -PP(0)/PP(2) IMUL EAX ; EAX = va*va MOVSX EBX,CX ; EAX = vb SAL EBX,15 ; EAX = vb*32768 ADD EAX,EBX ; EBX = va*va + vb*32768 MOV [sqr],EAX MOV CX,14 ; CX = compteur MOV BX,0 ; BX = racine MOV WORD PTR [inc_sq],4000H ; SQRT_L: ADD BX,[inc_sq] ; rac += incrm MOVSX EAX,BX IMUL EAX ; EAX = rac*rac SUB EAX,[sqr] ; EAX = rac*rac - SQR JZ VITA_SQ JLE NEXTIT SUB BX,[inc_sq] ; rac = rac - incrm NEXTIT: SAR WORD PTR [inc_sq],1 ; incrm >> 1 DEC CX JNE SQRT_L VITA_SQ: MOV EAX,DWORD PTR [ESI] ; AX = b MOV DX,AX SUB AX,BX ; AX = b-sqrt() MOV WORD PTR [EDI+4],AX ; sauver ADD DX,BX ; DX = b+sqrt() MOV WORD PTR [EDI],DX ; sauver ; idem with QQ ADD ESI,24 ;DS:SI QQ MOV EBX,DWORD PTR [ESI+8] ;EBX = QQ(2) ADD EBX,0 JGE B_POSIT_Q NEG EBX B_POSIT_Q: MOV CL,0 CMP EBX,40000000H ;normaliser QQ(2) JGE OUT_NORM_Q NORM_B_Q: ADD EBX,EBX INC CL CMP EBX,40000000H ; JGE OUT_NORM_Q JMP NORM_B_Q OUT_NORM_Q: ADD EBX,16384 SAR EBX,15 MOV EDX,DWORD PTR [ESI+8] ADD EDX,0 JGE PUT_SIGN_Q NEG EBX PUT_SIGN_Q: ; BX = QQ(2) MOV EAX,DWORD PTR [ESI] ; EAX = QQ(0) SAL EAX,CL ; shifter a de CL CDQ IDIV EBX ; AX = QQ(0)/QQ(2) NEG AX MOV WORD PTR [EDI+2],AX ; ES:[DI+2] = -QQ(0)/QQ(2) MOV EAX,DWORD PTR [ESI+4] ; EAX = QQ(1) SAL EAX,CL ; shifter a de CL SAR EAX,1 CDQ IDIV EBX NEG EAX ; va = AX = -QQ(1)/2*QQ(2) MOV DWORD PTR [ESI],EAX MOV CX,WORD PTR [EDI+2] ; vb = CX = -QQ(0)/QQ(2) IMUL EAX ; EAX = va*va MOVSX EBX,CX ; EAX = vb SAL EBX,15 ; EAX = vb*32768 ADD EAX,EBX ; EBX = va*va + vb*32768 MOV [sqr],EAX MOV CX,14 ; CX = compteur MOV BX,0 ; BX = racine MOV WORD PTR [inc_sq],4000H ; SQRT_LQ: ADD BX,[inc_sq] ; rac += incrm MOVSX EAX,BX IMUL EAX ; EAX = rac*rac SUB EAX,[sqr] ; EAX = rac*rac - SQR JZ VITA_SQ2 JLE NEXTITQ SUB BX,[inc_sq] ; rac = rac - incrm NEXTITQ: SAR WORD PTR [inc_sq],1 ; incrm >> 1 DEC CX JNE SQRT_LQ VITA_SQ2: MOV EAX,DWORD PTR [ESI] ; AX = b MOV DX,AX SUB AX,BX ; AX = b-sqrt() MOV WORD PTR [EDI+6],AX ; sauver ADD DX,BX ; DX = b+sqrt() MOV WORD PTR [EDI+2],DX ; sauver } } void deacc(short *src,short *dest,short fact,short lfen,short *last_out) { _asm { MOV ESI,[src] MOV EDI,[dest] MOV EBX,[last_out] ; FS:BX = last_out MOV AX,WORD PTR [EBX] ; AX = last_out MOV BX,[fact] ; BX = Fact MOV CX,[lfen] ; init compteur LOOP_DEAC: IMUL BX ; DX:AX = fact * y(i-1) ADD AX,16384 ADC DX,0 ; arrondi SHLD DX,AX,1 ; DX = fact * x(i-1; MOV AX,WORD PTR [ESI] ; AX = x(i) ADD AX,DX ; DX = x(i) + fact*x(i-1) MOV WORD PTR [EDI],AX ;Sauver Xout ADD ESI,2 ; ADD EDI,2 ;Pointer composantes suivantes DEC CX JNE LOOP_DEAC MOV EBX,[last_out] MOV WORD PTR [EBX],AX ;Sauver dernier ‚chantillon } } void filt_in(short *mem,short *Vin,short *Vout,short lfen) { _asm { MOV CX,[lfen] ;CX=cpteur MOV EDI,[mem] FIL_IN_LOOP: MOV ESI,[Vin] MOV BX,WORD PTR [ESI] ;BX=Xin SAR BX,2 ;div par 4 MOV AX,WORD PTR [EDI] ;AX=z(1) MOV WORD PTR [EDI],BX ;mise a jour memoire SUB BX,AX ;BX=(Xin-z(1))/4 ADD DWORD PTR [Vin],2 ;pointer echant svt MOV AX,WORD PTR [EDI+2] ;AX=z(2) MOV DX,29491 ;DX=0.9 IMUL DX ;DX=0.9*z(2) ADD AX,16384 ADC DX,0 ;arrondi et dble signe SHLD DX,AX,1 ADD DX,BX ;reponse=DX=tmp MOV WORD PTR [EDI+2],DX ;mise a jour memoire MOV ESI,[Vout] MOV WORD PTR [ESI],DX ;output=tmp/4 ADD DWORD PTR [Vout],2 ;pointer echant svt DEC CX JNE FIL_IN_LOOP } } /* void cal_dic1(short *y,short *sr,short *espopt,short *posit,short dec, short esp,short SIGPI[],short SOULONG,long TLSP[],long VMAX[]) { short ss,vene; _asm { PUSH WORD PTR [INT_SOUL] MOV SI,WORD PTR [INT_SIG] ADD SI,300 PUSH SI PUSH WORD PTR [INT_Y] CALL near ptr venergy ADD SP,6 MOV BX,WORD PTR [INT_SOUL] SAL BX,2 ADD SI,BX SUB SI,4 MOV WORD PTR [VENE],SI MOV AX,WORD PTR [INT_SOUL] MOV WORD PTR [INT_SS],AX ADD AX,WORD PTR [INT_SR] ADD WORD PTR [INT_SS],AX MOV DI,0 MOV SI,WORD PTR [LG_TLSP] PUSH WORD PTR [LG_VMAX] PUSH SI DEC1_LOOP: MOV BX,WORD PTR [INT_SR] MOV EAX,0 MOV DWORD PTR [SI],EAX ADD BX,DI ADD BX,DI DEC1_BCLE: MOVSX EAX,WORD PTR [BX] ADD DWORD PTR [SI],EAX MOV AX,WORD PTR [INT_ESP] ADD BX,AX ADD BX,AX CMP BX,WORD PTR [INT_SS] JL DEC1_BCLE MOV BX,WORD PTR [VENE] SAL DI,2 SUB BX,DI SAR DI,2 MOV EAX,DWORD PTR [BX] MOV DWORD PTR [SI+4],EAX CALL upd_max_d ADD AX,0 JE NO_LIMIT MOV BX,WORD PTR [INT_POS] MOV WORD PTR [BX],DI MOV BX,WORD PTR [INT_EO] MOV AX,WORD PTR [INT_ESP] MOV WORD PTR [BX],AX NO_LIMIT: INC DI CMP DI,WORD PTR [INT_DEC] JL DEC1_LOOP ADD SP,4 POP DI POP SI MOV SP,BP POP BP RET cal_dic1 ENDP COMMENT # COMMENT & ___ void cal_dic2(int q,int espace,int phase,int *s_r,int *hy,int *b, ___ int *vois,int *esp,int *qq,int *phas,int SIGPI[], ___ int SOULONG,long TLSP[],long VMAX[],(int PITCH)) ___ |--->en option... & R11 EQU BP-4 Y1 EQU BP-6 Y2 EQU BP-8 IO EQU BP-10 ST_CC EQU BP-30 ST_SRC EQU BP-50 INT_Q EQU BP+6 ESPACE EQU BP+8 PHASE EQU BP+10 INT_SR EQU BP+12 S_INT_SR EQU BP+14 HY EQU BP+16 S_HY EQU BP+18 INT_B EQU BP+20 S_INT_B EQU BP+22 VOIS EQU BP+24 S_VOIS EQU BP+26 INT_ESP EQU BP+28 S_ESP EQU BP+30 QQ EQU BP+32 S_QQ EQU BP+34 PHAS EQU BP+36 S_PHAS EQU BP+38 SIGPI EQU BP+40 S_SIGPI EQU BP+42 SOULONG EQU BP+44 TLSP EQU BP+46 S_TLSP EQU BP+48 VMAX EQU BP+50 S_VMAX EQU BP+52 ;PITCH EQU BP+54 cal_dic2 PROC FAR PUSH BP MOV BP,SP SUB SP,50 PUSH SI PUSH DI PUSH DS ; PUSH ES MOV DWORD PTR [R11],0 PUSH WORD PTR [SOULONG] PUSH WORD PTR [S_SIGPI] MOV SI,WORD PTR [SIGPI] ADD SI,300 MOV WORD PTR [Y1],SI SUB SI,150 MOV WORD PTR [Y2],SI PUSH SI CALL init_zero ADD SP,6 MOV AX,WORD PTR [PHASE] SUB AX,WORD PTR [ESPACE] MOV WORD PTR [IO],AX PUSH WORD PTR [SOULONG] SUB SP,2 PUSH WORD PTR [S_HY] PUSH WORD PTR [HY] PUSH WORD PTR [S_SIGPI] PUSH SI ADD SP,10 MOV SI,0 MOV DS,WORD PTR [S_INT_SR] CAL2_LOOP: MOV DI,WORD PTR [INT_SR] MOV AX,WORD PTR [IO] ADD AX,WORD PTR [ESPACE] MOV WORD PTR [IO],AX ADD DI,AX ADD DI,AX MOVSX EBX,WORD PTR DS:[DI] ADD SI,SI MOV WORD PTR SS:[ST_SRC+SI],BX ADD EBX,0 JL SRC_NEG MOV WORD PTR SS:[ST_CC+SI],1 ADD DWORD PTR [R11],EBX PUSH AX SUB SP,8 CALL add_sf_vect ADD SP,10 JMP CAL2_SUITE SRC_NEG: MOV WORD PTR SS:[ST_CC+SI],-1 SUB DWORD PTR [R11],EBX PUSH AX SUB SP,8 CALL sub_sf_vect ADD SP,10 CAL2_SUITE: SAR SI,1 ADD SI,1 CMP SI,WORD PTR [INT_Q] JL CAL2_LOOP ADD SP,2 PUSH WORD PTR [SOULONG] PUSH WORD PTR [S_TLSP] MOV SI,WORD PTR [TLSP] ADD SI,4 PUSH SI PUSH WORD PTR [S_SIGPI] PUSH WORD PTR [Y2] CALL energy2 ADD SP,10 MOV DS,WORD PTR [S_TLSP] MOV SI,WORD PTR [TLSP] MOV EAX,DWORD PTR [R11] MOV DS:[SI],EAX PUSH WORD PTR [S_VMAX] PUSH WORD PTR [VMAX] PUSH DS PUSH SI CALL upd_max_d ADD SP,8 ADD AX,0 JE UPD_NULL PUSH WORD PTR [INT_Q] PUSH WORD PTR [S_INT_B] PUSH WORD PTR [INT_B] PUSH SS MOV AX,BP SUB AX,30 PUSH AX CALL int_to_int ADD SP,10 MOV SI,WORD PTR [VOIS] MOV DS,WORD PTR [S_VOIS] MOV DS:[SI],WORD PTR 0 MOV DS,WORD PTR [S_ESP] MOV SI,WORD PTR [INT_ESP] MOV AX,WORD PTR [ESPACE] MOV DS:[SI],AX MOV DS,WORD PTR [S_QQ] MOV SI,WORD PTR [QQ] MOV AX,WORD PTR [INT_Q] MOV DS:[SI],AX MOV DS,WORD PTR [S_PHAS] MOV SI,WORD PTR [PHAS] MOV AX,WORD PTR [PHASE] MOV DS:[SI],AX UPD_NULL: ; CMP WORD PTR [PITCH],80 ; JG FINI COMMENT & MOV AX,WORD PTR [PHASE] SUB AX,WORD PTR [ESPACE] MOV WORD PTR [IO],AX MOV SI,0 CAL2_LOOP2: ADD SI,SI MOV AX,WORD PTR SS:[ST_CC+SI] NEG AX MOV WORD PTR SS:[ST_CC+SI],AX MOV EDX,DWORD PTR [R11] MOVSX EBX,WORD PTR SS:[ST_SRC+SI] ADD AX,0 JL CC_NEG ADD EDX,EBX ADD EDX,EBX JMP CC_NEXT CC_NEG: SUB EDX,EBX SUB EDX,EBX CC_NEXT: MOV DI,WORD PTR [TLSP] MOV DS,WORD PTR [S_TLSP] MOV DS:[DI],EDX MOV AX,WORD PTR [IO] ADD AX,WORD PTR [ESPACE] MOV WORD PTR [IO],AX MOV BX,WORD PTR SS:[ST_CC+SI] ADD BX,BX PUSH BX PUSH AX PUSH WORD PTR [SOULONG] PUSH WORD PTR [S_HY] PUSH WORD PTR [HY] PUSH WORD PTR [S_SIGPI] PUSH WORD PTR [Y2] PUSH WORD PTR [S_SIGPI] PUSH WORD PTR [Y1] CALL update_dic ADD SP,18 PUSH WORD PTR [SOULONG] PUSH DS MOV BX,WORD PTR [TLSP] ADD BX,4 PUSH BX PUSH WORD PTR [S_SIGPI] PUSH WORD PTR [Y1] CALL energy2 ADD SP,10 PUSH WORD PTR [S_VMAX] PUSH WORD PTR [VMAX] PUSH DS PUSH WORD PTR [TLSP] CALL upd_max_d ADD SP,8 ADD AX,0 JE CAL2_END PUSH WORD PTR [INT_Q] PUSH WORD PTR [S_INT_B] PUSH WORD PTR [INT_B] PUSH SS MOV AX,BP SUB AX,30 PUSH AX CALL int_to_int ADD SP,10 MOV DI,WORD PTR [TLSP] MOV EAX,DS:[DI] MOV DWORD PTR [R11],EAX MOV AX,WORD PTR [Y1] XCHG AX,WORD PTR [Y2] MOV WORD PTR [Y1],AX MOV DI,WORD PTR [VOIS] MOV DS,WORD PTR [S_VOIS] MOV DS:[DI],WORD PTR 0 MOV DS,WORD PTR [S_ESP] MOV DI,WORD PTR [INT_ESP] MOV AX,WORD PTR [ESPACE] MOV DS:[DI],AX MOV DS,WORD PTR [S_QQ] MOV DI,WORD PTR [QQ] MOV AX,WORD PTR [INT_Q] MOV DS:[DI],AX MOV DS,WORD PTR [S_PHAS] MOV DI,WORD PTR [PHAS] MOV AX,WORD PTR [PHASE] MOV DS:[DI],AX JMP CAL2_OUT CAL2_END: NEG WORD PTR SS:[ST_CC+SI] CAL2_OUT: SAR SI,1 ADD SI,1 CMP SI,WORD PTR [INT_Q] JL CAL2_LOOP2 FINI: & ; POP ES POP DS POP DI POP SI MOV SP,BP POP BP RET cal_dic2 ENDP # COMMENT & ___ void calc_p(int *p1,int *p2,int pitch,int lim_p1,int lim_p2,int no); & P1 EQU BP+4 P2 EQU BP+6 PITCH EQU BP+8 LIM_P1 EQU BP+10 LIM_P2 EQU BP+12 INT_NO EQU BP+14 calc_p PROC near PUSH BP ; save contexte MOV BP,SP ; PUSH SI ; save C register PUSH DI MOV BX,WORD PTR [PITCH] MOV SI,WORD PTR [P1] MOV CX,WORD PTR [LIM_P1] MOV AX,WORD PTR [INT_NO] ADD AX,0 JE NUM_NULL SUB BX,3 CMP BX,CX JL P1_NEG1 MOV WORD PTR [SI],BX JMP P1_SUITE1 P1_NEG1: MOV WORD PTR [SI],CX P1_SUITE1: ADD BX,7 MOV CX,WORD PTR [LIM_P2] MOV SI,WORD PTR [P2] CMP BX,CX JG P2_POS1 MOV WORD PTR [SI],BX JMP P_FIN P2_POS1: MOV WORD PTR [SI],CX JMP P_FIN NUM_NULL: SUB BX,5 CMP BX,CX JL P1_NEG2 MOV WORD PTR [SI],BX JMP P1_SUITE2 P1_NEG2: MOV WORD PTR [SI],CX P1_SUITE2: ADD BX,10 MOV CX,WORD PTR [LIM_P2] MOV SI,WORD PTR [P2] CMP BX,CX JG P2_POS2 MOV WORD PTR [SI],BX JMP P_FIN P2_POS2: MOV WORD PTR [SI],CX P_FIN: POP DI POP SI MOV SP,BP POP BP RET calc_p ENDP */ #pragma warning(disable : 4035) short calc_gltp(short *gltp,short *bq,short *bv,long ttt) { _asm { MOV EBX,DWORD PTR [ttt] CMP EBX,32767 JLE TEST2 MOV AX,32767 JMP OUT_TEST TEST2: CMP EBX,-32767 JGE TEST3 MOV AX,-32767 JMP OUT_TEST TEST3: MOV AX,BX OUT_TEST: MOV BX,AX ; BX=GLTP ADD AX,0 JGE GLTP_POS NEG AX ; AX=abs(GLTP) GLTP_POS: MOV CX,0 MOV ESI,[bq] MOV EDI,[bv] BOUCLER: ADD CX,1 CMP CX,11 JE FIN_BOUCLER ADD EDI,2 MOV DX,WORD PTR [ESI] CMP AX,DX JL BOUCLER ADD ESI,2 MOV DX,WORD PTR [ESI] CMP AX,DX JGE BOUCLER ADD BX,0 JLE GLTP_NEG DEC CX ;CX=k MOV BX,WORD PTR [EDI] JMP FIN_BOUCLER GLTP_NEG: ADD CX,9 MOV BX,WORD PTR [EDI] NEG BX FIN_BOUCLER: MOV ESI,[bq] ADD ESI,20 MOV DX,WORD PTR [ESI] CMP BX,DX JL GLTP_P MOV EDI,[bv] ADD EDI,20 MOV BX,WORD PTR [EDI] MOV CX,9 GLTP_P: SUB ESI,8 MOV DX,WORD PTR [ESI] NEG DX CMP BX,DX JGE GLTP_G MOV EDI,[bv] ADD EDI,12 MOV BX,WORD PTR [EDI] NEG BX MOV CX,15 GLTP_G: MOV ESI,[gltp] MOV WORD PTR [ESI],BX MOV AX,CX } } #pragma warning(default : 4035) #pragma warning(disable : 4035) short calc_garde(short MAX) { _asm { MOV AX,0 MOV BX,WORD PTR [MAX] AND BX,0FE00H JE STORE SAR BX,9 BCLE_SAR: INC AX SAR BX,1 JE STORE CMP AX,5 JNE BCLE_SAR STORE: } } #pragma warning(default : 4035) #pragma warning(disable : 4035) short calc_gopt(short *c,short *code,short *gq,short *gv,short voise, short npopt,short pitch,short espopt,short depl,short position, short soudecal,long vmax) { _asm { MOV EBX,DWORD PTR [vmax] CMP EBX,32767 JLE COMP2 MOV AX,32767 JMP OUT_COMP COMP2: CMP EBX,-32767 JGE COMP3 MOV AX,-32767 JMP OUT_COMP COMP3: MOV AX,BX ;AX=Gopt OUT_COMP: MOV BX,WORD PTR [voise] ADD BX,0 JNE VOIS_1 MOV ESI,[c] MOV BX,WORD PTR [ESI] CMP BX,-1 JNE CO_1 NEG AX MOVSX ECX,WORD PTR [npopt] ADD ESI,ECX ADD ESI,ECX CX_BCLE: SUB ESI,2 NEG WORD PTR [ESI] DEC CX JNE CX_BCLE CO_1: MOV CX,WORD PTR [npopt] CMP CX,8 JNE NPOPT_9 MOV DX,128 JMP NP_NEXT NPOPT_9: MOV DX,256 ;DX=cod NP_NEXT: MOV DI,1 MOV ESI,[c] DEC CX CJ_BCLE: ADD ESI,2 DEC CX MOV BX,WORD PTR [ESI] SUB BX,1 JNE CJ_1 MOV BX,1 SAL BX,CL ADD DX,BX CJ_1: INC DI CMP DI,WORD PTR [npopt] JL CJ_BCLE JMP VOIS_0 VOIS_1: MOV BX,WORD PTR [espopt] MOV DX,WORD PTR [position] CMP BX,WORD PTR [pitch] JE VOIS_0 ADD DX,WORD PTR [soudecal] VOIS_0: MOVSX ESI,[depl] ADD ESI,ESI ADD ESI,24 ADD ESI,[c] MOV WORD PTR [ESI],DX ; code[12+depl]=cod ADD AX,0 JGE SIGN_0 NEG AX MOV BX,1 JMP SIGN_1 SIGN_0: MOV BX,0 SIGN_1: MOV CX,0 MOV ESI,[gq] MOV EDI,[gv] BOUCLER2: ADD CX,1 CMP CX,17 JE FIN_BOUCLER2 ADD EDI,2 MOV DX,WORD PTR [ESI] CMP AX,DX JL BOUCLER2 ADD ESI,2 MOV DX,WORD PTR [ESI] CMP AX,DX JGE BOUCLER2 DEC CX ;CX=cod MOV AX,WORD PTR [EDI] ;AX=Gopt FIN_BOUCLER2: MOV ESI,[gq] ADD ESI,32 MOV DX,WORD PTR [ESI] CMP AX,DX JL G_GQ MOV EDI,[gv] ADD EDI,32 MOV AX,WORD PTR [EDI] MOV CX,15 G_GQ: ADD BX,0 JE SIGN_NULL NEG AX ADD CX,16 SIGN_NULL: MOVSX ESI,WORD PTR [depl] ADD ESI,ESI ADD ESI,26 ADD ESI,[c] MOV WORD PTR [ESI],CX } } #pragma warning(default : 4035) void decimation(short *vin,short *vout,short nech) { _asm { MOV EDI,[vin] MOV ESI,[vout] DECIMATE: MOV AX,WORD PTR [EDI] MOV WORD PTR [ESI],AX ADD EDI,8 ADD ESI,2 DEC WORD PTR [nech] JNE DECIMATE } } #else void proc_gain(long *corr_ene,long gain) { // TODO need 64-bit } void inver_v_int(short *src,short *dest,short lng) { // TODO need 64-bit } short max_vect(short *vech,short nech) { // TODO need 64-bit return 0; } void upd_max(long *corr_ene,long *vval,short pitch) { // TODO need 64-bit } short upd_max_d(long *corr_ene,long *vval) { // TODO need 64-bit return 0; } void norm_corrl(long *corr,long *vval) { // TODO need 64-bit } void norm_corrr(long *corr,long *vval) { // TODO need 64-bit } void energy(short *vech,long *ene,short lng) { // TODO need 64-bit } void venergy(short *vech,long *vene,short lng) { // TODO need 64-bit } void energy2(short *vech,long *ene,short lng) { // TODO need 64-bit } void upd_ene(long *ener,long *val) { // TODO need 64-bit } short max_posit(long *vcorr,long *maxval,short pitch,short lvect) { // TODO need 64-bit return 0; } void correlation(short *vech,short *vech2,long *acc,short lng) { // TODO need 64-bit } void schur(short *parcor,long *Ri,short netages) { // TODO need 64-bit } void interpol(short *lsp1,short *lsp2,short *dest,short lng) { // TODO need 64-bit } void add_sf_vect(short *y1,short *y2,short deb,short lng) { // TODO need 64-bit } void sub_sf_vect(short *y1,short *y2,short deb,short lng) { // TODO need 64-bit } void short_to_short(short *src,short *dest,short lng) { int i; for(i=0; i= 8 ) { qSum += *piVector_0 * *piVector_1; qSum += *(piVector_0+1) * *(piVector_1+1); qSum += *(piVector_0+2) * *(piVector_1+2); qSum += *(piVector_0+3) * *(piVector_1+3); qSum += *(piVector_0+4) * *(piVector_1+4); qSum += *(piVector_0+5) * *(piVector_1+5); qSum += *(piVector_0+6) * *(piVector_1+6); qSum += *(piVector_0+7) * *(piVector_1+7); piVector_0 += 8; piVector_1 += 8; uiLength -= 8; } /********************************************************************/ /* Conditionally do a group of 4 multiply-accumulates. */ /********************************************************************/ if ( uiLength >= 4 ) { qSum += *piVector_0 * *piVector_1; qSum += *(piVector_0+1) * *(piVector_1+1); qSum += *(piVector_0+2) * *(piVector_1+2); qSum += *(piVector_0+3) * *(piVector_1+3); piVector_0 += 4; piVector_1 += 4; uiLength -= 4; } /********************************************************************/ /* Conditionally do a group of 2 multiply-accumulates. */ /********************************************************************/ if ( uiLength >= 2 ) { qSum += *piVector_0 * *piVector_1; qSum += *(piVector_0+1) * *(piVector_1+1); piVector_0 += 2; piVector_1 += 2; uiLength -= 2; } /********************************************************************/ /* Conditionally do a single multiply-accumulate. */ /********************************************************************/ if ( uiLength >= 1 ) { qSum += *piVector_0 * *piVector_1; } return qSum; } /**********************************************************************/ /**********************************************************************/ /* */ /* Function: FirFilter */ /* Author: Bill Hallahan */ /* Date: March 10, 1997 */ /* */ /* Abstract: */ /* */ /* This function returns the dot product of a set of FIR */ /* filter coefficients and the data in a circular delay line. */ /* All of the input and output data has Q15 scaling. */ /* */ /* Inputs: */ /* */ /* piFilterCoefficients A pointer to the FIR filter */ /* coefficients which are in reverse time */ /* order. */ /* */ /* piFilterDelay A pointer to a delay line that contains the */ /* input samples. */ /* */ /* iDelayPosition An index into the filter delay line. */ /* */ /* iFilterLength The length of the filter impulse response. */ /* (Also the number of filter coefficients. */ /* */ /* */ /* Outputs: */ /* */ /* The dot product of the fir filter coefficients and the */ /* data in the circular delay line is returned. */ /* */ /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /* Start of routine FirFilter(). */ /**********************************************************************/ int FirFilter( int * piFilterCoefficients, int * piFilterDelay, unsigned int uiDelayPosition, unsigned int uiFilterLength ) { int iSum; _int64 qSum; unsigned int uiRemaining; uiRemaining = uiFilterLength - uiDelayPosition; qSum = DotProduct( piFilterCoefficients, &piFilterDelay[uiDelayPosition], uiRemaining ); qSum += DotProduct( piFilterCoefficients + uiRemaining, &piFilterDelay[0], uiDelayPosition ); /********************************************************************/ /* Scale the Q30 number to be a Q15 number. */ /********************************************************************/ iSum = (int)( qSum >> 15 ); return iSum; } /**********************************************************************/ /**********************************************************************/ /* */ /* Function: SampleRate6400To8000 */ /* Author: Bill Hallahan */ /* Date: March 8, 1997 */ /* */ /* Abstract: */ /* */ /* This function converts a block of audio samples from an */ /* 6400 Hz. sample rate to an 8000 Hz. sample rate. This is done */ /* using a set of polyphase filters that can interpolate up to a */ /* 32000 Hz. rate ( 32000 is the LCM of 8000 and 6400.) */ /* */ /* Only the 32000 Hz. samples that correspond to an 8000 Hz. */ /* sample rate are calculated. The input 6400 Hz. rate corresponds */ /* to every 5th (32000/6400) sample at the 32000 Hz. rate. The */ /* output 8000 Hz. rate corresponds to every 4th (32000/8000) */ /* sample at the 32000 Hz. rate. Since the LCM of 4 and 5 is 20, */ /* then the pattern of sample insertion and polyphase filter */ /* selection will repeat every 20 output samples. */ /* */ /* */ /* Inputs: */ /* */ /* pwInputBuffer A pointer to an input buffer of samples */ /* that are sampled at an 6400 Hz. rate. The */ /* samples are in Q15 format and must be */ /* in the range of ( 1 - 2^-15) to -1. */ /* */ /* pwOutputBuffer A buffer that returns the output data */ /* which is the input buffer data resampled */ /* at 8000 Hz. */ /* */ /* The output bufer length MUST be large */ /* enough to accept all of the output data. */ /* The minimum length of the output buffer */ /* is 5/4 times the number of samples in the */ /* input buffer. ( 8000/6400 = 5/4 ) */ /* */ /* uiInputLength The number of samples in the input buffer. */ /* */ /* */ /* THE FOLLOWING INPUT VARIABLES ARE USED */ /* TO MAINTAIN STATE INFORMATION BETWEEN */ /* CALLS TO THIS ROUTINE. */ /* */ /* */ /* piFilterDelay A pointer to a delay line that is used */ /* for FIR filtering. This must be the */ /* length of the polyphase filter's impulse */ /* response. For this routine this is 56. */ /* This buffer should be initialized to zero */ /* once at system initialization. */ /* */ /* puiDelayPosition A pointer to an index into the filter */ /* delay line. This index value should be */ /* initialized to zero at system startup */ /* */ /* piInputSampleTime A pointer to the input sample time. */ /* This time is reset to zero by this routine */ /* when is reaches the value STEP_PRODUCT. */ /* This time is used to track the input */ /* stream time relative to the output stream */ /* time. This time difference is used to */ /* determine whether a new input sample */ /* should be put into the filter delay line. */ /* This should be initialized to zero once */ /* at system initialization. */ /* */ /* piOutputSampleTime A pointer to the output sample time. */ /* This time is reset to zero by this routine */ /* when is reaches the value STEP_PRODUCT. */ /* This time is used to determine if a new */ /* polyphase filter should be applied to the */ /* input sample stream. This is also used to */ /* select the particular polyphase filter */ /* that is applied. */ /* */ /* Outputs: */ /* */ /* This function returns an unsigned integer that is the number */ /* of samples in the output buffer. If the number of input samples */ /* is exactly a multiple of RU_INPUT_SAMPLE_STEP ( 4 ) then this */ /* routine will always return the same value. This value will */ /* then be 5/4 times the number of input samples. */ /* */ /* When this function returns the output buffer contains an array */ /* of integers at the new sample rate. */ /* */ /* */ /* Filter Information: */ /* */ /* The 6400 Hz. -> 32000 Hz. interpolation filter design */ /* is shown here. */ /* */ /* H( 1) = -0.38306729E-03 = H(280) */ /* H( 2) = 0.49756566E-03 = H(279) */ /* H( 3) = 0.13501500E-02 = H(278) */ /* H( 4) = 0.27531907E-02 = H(277) */ /* H( 5) = 0.46118572E-02 = H(276) */ /* H( 6) = 0.67112772E-02 = H(275) */ /* H( 7) = 0.87157665E-02 = H(274) */ /* H( 8) = 0.10221261E-01 = H(273) */ /* H( 9) = 0.10843582E-01 = H(272) */ /* H( 10) = 0.10320566E-01 = H(271) */ /* H( 11) = 0.85992115E-02 = H(270) */ /* H( 12) = 0.58815549E-02 = H(269) */ /* H( 13) = 0.26067111E-02 = H(268) */ /* H( 14) = -0.63367974E-03 = H(267) */ /* H( 15) = -0.32284572E-02 = H(266) */ /* H( 16) = -0.46942858E-02 = H(265) */ /* H( 17) = -0.48050000E-02 = H(264) */ /* H( 18) = -0.36581988E-02 = H(263) */ /* H( 19) = -0.16504158E-02 = H(262) */ /* H( 20) = 0.61691226E-03 = H(261) */ /* H( 21) = 0.25050722E-02 = H(260) */ /* H( 22) = 0.35073524E-02 = H(259) */ /* H( 23) = 0.33904186E-02 = H(258) */ /* H( 24) = 0.22536262E-02 = H(257) */ /* H( 25) = 0.49328664E-03 = H(256) */ /* H( 26) = -0.13216439E-02 = H(255) */ /* H( 27) = -0.26241955E-02 = H(254) */ /* H( 28) = -0.30239364E-02 = H(253) */ /* H( 29) = -0.24250194E-02 = H(252) */ /* H( 30) = -0.10513559E-02 = H(251) */ /* H( 31) = 0.62918884E-03 = H(250) */ /* H( 32) = 0.20572424E-02 = H(249) */ /* H( 33) = 0.27652446E-02 = H(248) */ /* H( 34) = 0.25287948E-02 = H(247) */ /* H( 35) = 0.14388775E-02 = H(246) */ /* H( 36) = -0.12839703E-03 = H(245) */ /* H( 37) = -0.16392219E-02 = H(244) */ /* H( 38) = -0.25793985E-02 = H(243) */ /* H( 39) = -0.26292247E-02 = H(242) */ /* H( 40) = -0.17717101E-02 = H(241) */ /* H( 41) = -0.30041003E-03 = H(240) */ /* H( 42) = 0.12788962E-02 = H(239) */ /* H( 43) = 0.24192522E-02 = H(238) */ /* H( 44) = 0.27206307E-02 = H(237) */ /* H( 45) = 0.20694542E-02 = H(236) */ /* H( 46) = 0.68163598E-03 = H(235) */ /* H( 47) = -0.96732663E-03 = H(234) */ /* H( 48) = -0.23031780E-02 = H(233) */ /* H( 49) = -0.28516089E-02 = H(232) */ /* H( 50) = -0.24051941E-02 = H(231) */ /* H( 51) = -0.11016324E-02 = H(230) */ /* H( 52) = 0.61728584E-03 = H(229) */ /* H( 53) = 0.21542138E-02 = H(228) */ /* H( 54) = 0.29617085E-02 = H(227) */ /* H( 55) = 0.27367356E-02 = H(226) */ /* H( 56) = 0.15328785E-02 = H(225) */ /* H( 57) = -0.24891639E-03 = H(224) */ /* H( 58) = -0.19927153E-02 = H(223) */ /* H( 59) = -0.30787138E-02 = H(222) */ /* H( 60) = -0.31024679E-02 = H(221) */ /* H( 61) = -0.20239211E-02 = H(220) */ /* H( 62) = -0.19259547E-03 = H(219) */ /* H( 63) = 0.17642577E-02 = H(218) */ /* H( 64) = 0.31550473E-02 = H(217) */ /* H( 65) = 0.34669666E-02 = H(216) */ /* H( 66) = 0.25533440E-02 = H(215) */ /* H( 67) = 0.69819519E-03 = H(214) */ /* H( 68) = -0.14703817E-02 = H(213) */ /* H( 69) = -0.31912178E-02 = H(212) */ /* H( 70) = -0.38355463E-02 = H(211) */ /* H( 71) = -0.31353715E-02 = H(210) */ /* H( 72) = -0.12912996E-02 = H(209) */ /* H( 73) = 0.10815051E-02 = H(208) */ /* H( 74) = 0.31569856E-02 = H(207) */ /* H( 75) = 0.41838423E-02 = H(206) */ /* H( 76) = 0.37558281E-02 = H(205) */ /* H( 77) = 0.19692746E-02 = H(204) */ /* H( 78) = -0.59148070E-03 = H(203) */ /* H( 79) = -0.30430311E-02 = H(202) */ /* H( 80) = -0.45054569E-02 = H(201) */ /* H( 81) = -0.44158362E-02 = H(200) */ /* H( 82) = -0.27416693E-02 = H(199) */ /* H( 83) = -0.14716905E-04 = H(198) */ /* H( 84) = 0.28351138E-02 = H(197) */ /* H( 85) = 0.47940183E-02 = H(196) */ /* H( 86) = 0.51221889E-02 = H(195) */ /* H( 87) = 0.36296796E-02 = H(194) */ /* H( 88) = 0.76842826E-03 = H(193) */ /* H( 89) = -0.24999138E-02 = H(192) */ /* H( 90) = -0.50239447E-02 = H(191) */ /* H( 91) = -0.58644302E-02 = H(190) */ /* H( 92) = -0.46395971E-02 = H(189) */ /* H( 93) = -0.16878319E-02 = H(188) */ /* H( 94) = 0.20179905E-02 = H(187) */ /* H( 95) = 0.51868116E-02 = H(186) */ /* H( 96) = 0.66543561E-02 = H(185) */ /* H( 97) = 0.58053876E-02 = H(184) */ /* H( 98) = 0.28218545E-02 = H(183) */ /* H( 99) = -0.13399328E-02 = H(182) */ /* H(100) = -0.52496092E-02 = H(181) */ /* H(101) = -0.74876603E-02 = H(180) */ /* H(102) = -0.71534920E-02 = H(179) */ /* H(103) = -0.42167297E-02 = H(178) */ /* H(104) = 0.42133522E-03 = H(177) */ /* H(105) = 0.51945718E-02 = H(176) */ /* H(106) = 0.83916243E-02 = H(175) */ /* H(107) = 0.87586977E-02 = H(174) */ /* H(108) = 0.59769331E-02 = H(173) */ /* H(109) = 0.83726482E-03 = H(172) */ /* H(110) = -0.49680225E-02 = H(171) */ /* H(111) = -0.93886480E-02 = H(170) */ /* H(112) = -0.10723907E-01 = H(169) */ /* H(113) = -0.82560331E-02 = H(168) */ /* H(114) = -0.25802210E-02 = H(167) */ /* H(115) = 0.45066439E-02 = H(166) */ /* H(116) = 0.10552152E-01 = H(165) */ /* H(117) = 0.13269756E-01 = H(164) */ /* H(118) = 0.11369097E-01 = H(163) */ /* H(119) = 0.51042791E-02 = H(162) */ /* H(120) = -0.36742561E-02 = H(161) */ /* H(121) = -0.12025163E-01 = H(160) */ /* H(122) = -0.16852396E-01 = H(159) */ /* H(123) = -0.15987474E-01 = H(158) */ /* H(124) = -0.90587810E-02 = H(157) */ /* H(125) = 0.21703094E-02 = H(156) */ /* H(126) = 0.14162681E-01 = H(155) */ /* H(127) = 0.22618638E-01 = H(154) */ /* H(128) = 0.23867993E-01 = H(153) */ /* H(129) = 0.16226372E-01 = H(152) */ /* H(130) = 0.87251863E-03 = H(151) */ /* H(131) = -0.18082183E-01 = H(150) */ /* H(132) = -0.34435309E-01 = H(149) */ /* H(133) = -0.41475002E-01 = H(148) */ /* H(134) = -0.33891901E-01 = H(147) */ /* H(135) = -0.94815092E-02 = H(146) */ /* H(136) = 0.29874707E-01 = H(145) */ /* H(137) = 0.78281499E-01 = H(144) */ /* H(138) = 0.12699878E+00 = H(143) */ /* H(139) = 0.16643921E+00 = H(142) */ /* H(140) = 0.18848117E+00 = H(141) */ /* */ /* BAND 1 BAND 2 */ /* LOWER BAND EDGE 0.0000000 0.1000000 */ /* UPPER BAND EDGE 0.0937500 0.5000000 */ /* DESIRED VALUE 1.0000000 0.0000000 */ /* WEIGHTING 0.0080000 1.0000000 */ /* DEVIATION 0.1223457 0.0009788 */ /* DEVIATION IN DB 1.0025328 -60.1864281 */ /* */ /* EXTREMAL FREQUENCIES--MAXIMA OF THE ERROR CURVE */ /* 0.0000000 0.0037946 0.0075893 0.0113839 0.0149554 */ /* 0.0187500 0.0225446 0.0263393 0.0301339 0.0339286 */ /* 0.0377232 0.0415179 0.0450894 0.0488840 0.0526787 */ /* 0.0566966 0.0604912 0.0642859 0.0680805 0.0718751 */ /* 0.0758929 0.0796875 0.0837053 0.0877231 0.0915177 */ /* 0.0937500 0.1000000 0.1006696 0.1024553 0.1049107 */ /* 0.1075892 0.1107142 0.1138391 0.1169641 0.1203123 */ /* 0.1236605 0.1270087 0.1305802 0.1339285 0.1372768 */ /* 0.1408483 0.1444198 0.1477681 0.1513396 0.1549111 */ /* 0.1584826 0.1618309 0.1654024 0.1689740 0.1725455 */ /* 0.1761170 0.1796885 0.1832600 0.1868315 0.1901798 */ /* 0.1937513 0.1973228 0.2008943 0.2044658 0.2080373 */ /* 0.2116089 0.2151804 0.2187519 0.2223234 0.2258949 */ /* 0.2294664 0.2330379 0.2366094 0.2401809 0.2437524 */ /* 0.2473240 0.2508955 0.2544670 0.2580385 0.2616100 */ /* 0.2651815 0.2687530 0.2723245 0.2761193 0.2796908 */ /* 0.2832623 0.2868338 0.2904053 0.2939768 0.2975483 */ /* 0.3011198 0.3046913 0.3082629 0.3118344 0.3154059 */ /* 0.3189774 0.3225489 0.3261204 0.3296919 0.3332634 */ /* 0.3368349 0.3404064 0.3439780 0.3475495 0.3511210 */ /* 0.3549157 0.3584872 0.3620587 0.3656302 0.3692017 */ /* 0.3727733 0.3763448 0.3799163 0.3834878 0.3870593 */ /* 0.3906308 0.3942023 0.3977738 0.4013453 0.4049169 */ /* 0.4084884 0.4120599 0.4158546 0.4194261 0.4229976 */ /* 0.4265691 0.4301406 0.4337122 0.4372837 0.4408552 */ /* 0.4444267 0.4479982 0.4515697 0.4551412 0.4587127 */ /* 0.4622842 0.4658557 0.4694273 0.4732220 0.4767935 */ /* 0.4803650 0.4839365 0.4875080 0.4910795 0.4946510 */ /* 0.4982226 */ /* */ /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /* Symbol Definitions. */ /**********************************************************************/ #define RU_INPUT_SAMPLE_STEP 5 #define RU_OUTPUT_SAMPLE_STEP 4 #define RU_STEP_PRODUCT ( RU_INPUT_SAMPLE_STEP * RU_OUTPUT_SAMPLE_STEP ) #define RU_POLYPHASE_FILTER_LENGTH 56 /**********************************************************************/ /* Start of SampleRate6400To8000 routine */ /**********************************************************************/ unsigned int SampleRate6400To8000( short * pwInputBuffer, short * pwOutputBuffer, unsigned int uiInputBufferLength, int * piFilterDelay, unsigned int * puiDelayPosition, int * piInputSampleTime, int * piOutputSampleTime ) { static int iPolyphaseFilter_0[56] = { 755, 1690, -528, 101, 80, -172, 235, -290, 339, -394, 448, -508, 568, -628, 685, -738, 785, -823, 849, -860, 851, -813, 738, -601, 355, 142, -1553, 30880, 4894, -2962, 2320, -1970, 1728, -1538, 1374, -1226, 1090, -960, 839, -723, 615, -513, 418, -331, 251, -180, 111, -49, -21, 103, -216, 410, -769, 1408, 1099, -62 }; static int iPolyphaseFilter_1[56] = { 451, 1776, -103, -270, 369, -397, 414, -430, 445, -467, 485, -504, 516, -522, 517, -498, 464, -409, 330, -219, 69, 137, -422, 836, -1484, 2658, -5552, 27269, 12825, -5641, 3705, -2761, 2174, -1757, 1435, -1172, 951, -760, 594, -449, 322, -211, 114, -31, -40, 101, -158, 209, -268, 337, -429, 574, -787, 963, 1427, 81 }; static int iPolyphaseFilter_2[56] = { 221, 1674, 427, -599, 555, -495, 453, -422, 396, -377, 352, -326, 289, -240, 177, -96, -2, 125, -276, 462, -690, 979, -1352, 1862, -2619, 3910, -6795, 20807, 20807, -6795, 3910, -2619, 1862, -1352, 979, -690, 462, -276, 125, -2, -96, 177, -240, 289, -326, 352, -377, 396, -422, 453, -495, 555, -599, 427, 1674, 221 }; static int iPolyphaseFilter_3[56] = { 81, 1427, 963, -787, 574, -429, 337, -268, 209, -158, 101, -40, -31, 114, -211, 322, -449, 594, -760, 951, -1172, 1435, -1757, 2174, -2761, 3705, -5641, 12825, 27269, -5552, 2658, -1484, 836, -422, 137, 69, -219, 330, -409, 464, -498, 517, -522, 516, -504, 485, -467, 445, -430, 414, -397, 369, -270, -103, 1776, 451 }; static int iPolyphaseFilter_4[56] = { -62, 1099, 1408, -769, 410, -216, 103, -21, -49, 111, -180, 251, -331, 418, -513, 615, -723, 839, -960, 1090, -1226, 1374, -1538, 1728, -1970, 2320, -2962, 4894, 30880, -1553, 142, 355, -601, 738, -813, 851, -860, 849, -823, 785, -738, 685, -628, 568, -508, 448, -394, 339, -290, 235, -172, 80, 101, -528, 1690, 755 }; static int * ppiPolyphaseFilter[5] = { &iPolyphaseFilter_0[0], &iPolyphaseFilter_1[0], &iPolyphaseFilter_2[0], &iPolyphaseFilter_3[0], &iPolyphaseFilter_4[0] }; register int * piFilterCoefficients; register int iFilterIndex; register unsigned int uiDelayPosition; register int iInputSampleTime; register int iOutputSampleTime; register unsigned int uiInputIndex = 0; register unsigned int uiOutputIndex = 0; /********************************************************************/ /* Get the input filter state parameters. */ /********************************************************************/ uiDelayPosition = *puiDelayPosition; iInputSampleTime = *piInputSampleTime; iOutputSampleTime = *piOutputSampleTime; /********************************************************************/ /* Loop and process all of the input samples. */ /********************************************************************/ while ( uiInputIndex < uiInputBufferLength ) { /******************************************************************/ /* Put input samples in interpolator delay buffer until we */ /* catch up to the next output sample time index. */ /******************************************************************/ while (( iInputSampleTime <= iOutputSampleTime ) && ( uiInputIndex < uiInputBufferLength )) { /****************************************************************/ /* Put a new imput sample in the polyphase filter delay line. */ /****************************************************************/ piFilterDelay[uiDelayPosition++] = (int)pwInputBuffer[uiInputIndex++]; if ( uiDelayPosition >= RU_POLYPHASE_FILTER_LENGTH ) { uiDelayPosition = 0; } /****************************************************************/ /* Increment the input sample time index. */ /****************************************************************/ iInputSampleTime += RU_INPUT_SAMPLE_STEP; } /******************************************************************/ /* Calculate output samples using the interpolator until we */ /* reach the next input sample time. */ /******************************************************************/ while ( iOutputSampleTime < iInputSampleTime ) { /****************************************************************/ /* Calculate the polyphase filter index that corresponds to */ /* the next output sample. */ /****************************************************************/ iFilterIndex = iOutputSampleTime; while ( iFilterIndex >= RU_INPUT_SAMPLE_STEP ) { iFilterIndex = iFilterIndex - RU_INPUT_SAMPLE_STEP; } /****************************************************************/ /* Get the polyphase filter coefficients. */ /****************************************************************/ piFilterCoefficients = ppiPolyphaseFilter[iFilterIndex]; /****************************************************************/ /* Apply the polyphase filter. */ /****************************************************************/ pwOutputBuffer[uiOutputIndex++] = (short)FirFilter( piFilterCoefficients, piFilterDelay, uiDelayPosition, RU_POLYPHASE_FILTER_LENGTH ); /****************************************************************/ /* Increment the output sample time index. */ /****************************************************************/ iOutputSampleTime += RU_OUTPUT_SAMPLE_STEP; } /******************************************************************/ /* Wrap the input and output times indices so they don't */ /* overflow and go back to process more of the input block. */ /******************************************************************/ if ( iInputSampleTime >= RU_STEP_PRODUCT ) { iInputSampleTime -= RU_STEP_PRODUCT; iOutputSampleTime -= RU_STEP_PRODUCT; } } /********************************************************************/ /* Save the input filter state parameters. */ /********************************************************************/ *puiDelayPosition = uiDelayPosition; *piInputSampleTime = iInputSampleTime; *piOutputSampleTime = iOutputSampleTime; /********************************************************************/ /* Return the number of samples in the output buffer. */ /********************************************************************/ return uiOutputIndex; } /**********************************************************************/ /**********************************************************************/ /* */ /* Function: SampleRate8000To6400 */ /* Author: Bill Hallahan */ /* Date: March 8, 1997 */ /* */ /* Abstract: */ /* */ /* This function converts a block of audio samples from an */ /* 8000 Hz. sample rate to a 6400 Hz. sample rate. This is done */ /* using a set of polyphase filters that can interpolate up to a */ /* 32000 Hz. rate ( 32000 is the LCM of 8000 and 6400.) */ /* */ /* Only the 32000 Hz. samples that correspond to a 6400 Hz. */ /* sample rate are calculated. The input 8000 Hz. rate corresponds */ /* to every 4th (32000/8000) sample at the 32000 Hz. rate. The */ /* output 6400 Hz. rate corresponds to every 5th (32000/6400) */ /* sample at the 32000 Hz. rate. Since the LCM of 4 and 5 is 20, */ /* then the pattern of sample insertion and polyphase filter */ /* selection will repeat every 20 output samples. */ /* */ /* */ /* Inputs: */ /* */ /* pwInputBuffer A pointer to an input buffer of samples */ /* that are sampled at an 8000 Hz. rate. The */ /* samples are in Q15 format and must be */ /* in the range of ( 1 - 2^-15) to -1. */ /* */ /* pwOutputBuffer A buffer that returns the output data */ /* which is the input buffer data resampled */ /* at 6400 Hz. Since this is a lower sample */ /* rate than the input rate the data is also */ /* low pass filtered during the conversion */ /* process. The low pass filter cutoff */ /* frequency is at 3000 Hz. All alias */ /* products are down at least 60 dB. past */ /* 3100 Hz. */ /* */ /* The output bufer length MUST be large */ /* enough to accept all of the output data. */ /* The minimum length of the output buffer */ /* is 4/5 times the number of samples in the */ /* input buffer. ( 6400/8000 = 4/5 ) */ /* */ /* uiInputLength The number of samples in the input buffer. */ /* */ /* */ /* THE FOLLOWING INPUT VARIABLES ARE USED */ /* TO MAINTAIN STATE INFORMATION BETWEEN */ /* CALLS TO THIS ROUTINE. */ /* */ /* */ /* piFilterDelay A pointer to a delay line that is used */ /* for FIR filtering. This must be the */ /* length of the polyphase filter's impulse */ /* response. For this routine this is 23. */ /* This buffer should be initialized to zero */ /* once at system initialization. */ /* */ /* puiDelayPosition A pointer to an index into the filter */ /* delay line. This index value should be */ /* initialized to zero at system startup */ /* */ /* piInputSampleTime A pointer to the input sample time. */ /* This time is reset to zero by this routine */ /* when is reaches the value STEP_PRODUCT. */ /* This time is used to track the input */ /* stream time relative to the output stream */ /* time. This time difference is used to */ /* determine whether a new input sample */ /* should be put into the filter delay line. */ /* This should be initialized to zero once */ /* at system initialization. */ /* */ /* piOutputSampleTime A pointer to the output sample time. */ /* This time is reset to zero by this routine */ /* when is reaches the value STEP_PRODUCT. */ /* This time is used to determine if a new */ /* polyphase filter should be applied to the */ /* input sample stream. This is also used to */ /* select the particular polyphase filter */ /* that is applied. */ /* */ /* Outputs: */ /* */ /* This function returns an unsigned integer that is the number */ /* of samples in the output buffer. If the number of input samples */ /* is exactly a multiple of RD_INPUT_SAMPLE_STEP ( 5 ) then this */ /* routine will always return the same value. This value will */ /* then be 4/5 times the number of input samples. */ /* */ /* When this function returns the output buffer contains an array */ /* of integers at the new sample rate. */ /* */ /* */ /* Filter Information: */ /* */ /* The 8000 Hz. -> 32000 Hz. interpolation filter design */ /* is shown here. */ /* */ /* FINITE IMPULSE RESPONSE (FIR) */ /* LINEAR PHASE DIGITAL FILTER DESIGN */ /* REMEZ EXCHANGE ALGORITHM */ /* */ /* BANDPASS FILTER */ /* */ /* FILTER LENGTH = 92 */ /* */ /* ***** IMPULSE RESPONSE ***** */ /* H( 1) = -0.77523338E-03 = H( 92) */ /* H( 2) = -0.56140189E-03 = H( 91) */ /* H( 3) = -0.26485065E-03 = H( 90) */ /* H( 4) = 0.48529240E-03 = H( 89) */ /* H( 5) = 0.15506579E-02 = H( 88) */ /* H( 6) = 0.25692214E-02 = H( 87) */ /* H( 7) = 0.30662031E-02 = H( 86) */ /* H( 8) = 0.26577783E-02 = H( 85) */ /* H( 9) = 0.12834022E-02 = H( 84) */ /* H( 10) = -0.67870057E-03 = H( 83) */ /* H( 11) = -0.24781306E-02 = H( 82) */ /* H( 12) = -0.32756536E-02 = H( 81) */ /* H( 13) = -0.25334368E-02 = H( 80) */ /* H( 14) = -0.34487492E-03 = H( 79) */ /* H( 15) = 0.24779409E-02 = H( 78) */ /* H( 16) = 0.46604010E-02 = H( 77) */ /* H( 17) = 0.50008399E-02 = H( 76) */ /* H( 18) = 0.29790259E-02 = H( 75) */ /* H( 19) = -0.85979374E-03 = H( 74) */ /* H( 20) = -0.49750470E-02 = H( 73) */ /* H( 21) = -0.74064843E-02 = H( 72) */ /* H( 22) = -0.66624931E-02 = H( 71) */ /* H( 23) = -0.25365327E-02 = H( 70) */ /* H( 24) = 0.35602755E-02 = H( 69) */ /* H( 25) = 0.90023531E-02 = H( 68) */ /* H( 26) = 0.11015911E-01 = H( 67) */ /* H( 27) = 0.80042975E-02 = H( 66) */ /* H( 28) = 0.53222617E-03 = H( 65) */ /* H( 29) = -0.85644918E-02 = H( 64) */ /* H( 30) = -0.15142974E-01 = H( 63) */ /* H( 31) = -0.15514131E-01 = H( 62) */ /* H( 32) = -0.82975281E-02 = H( 61) */ /* H( 33) = 0.44855666E-02 = H( 60) */ /* H( 34) = 0.17722420E-01 = H( 59) */ /* H( 35) = 0.25017589E-01 = H( 58) */ /* H( 36) = 0.21431517E-01 = H( 57) */ /* H( 37) = 0.60814521E-02 = H( 56) */ /* H( 38) = -0.16557660E-01 = H( 55) */ /* H( 39) = -0.37409518E-01 = H( 54) */ /* H( 40) = -0.45595154E-01 = H( 53) */ /* H( 41) = -0.32403238E-01 = H( 52) */ /* H( 42) = 0.50128344E-02 = H( 51) */ /* H( 43) = 0.61689958E-01 = H( 50) */ /* H( 44) = 0.12557802E+00 = H( 49) */ /* H( 45) = 0.18087465E+00 = H( 48) */ /* H( 46) = 0.21291447E+00 = H( 47) */ /* */ /* BAND 1 BAND 2 */ /* LOWER BAND EDGE 0.0000000 0.1250000 */ /* UPPER BAND EDGE 0.0968750 0.5000000 */ /* DESIRED VALUE 1.0000000 0.0000000 */ /* WEIGHTING 0.0700000 1.0000000 */ /* DEVIATION 0.0136339 0.0009544 */ /* DEVIATION IN DB 0.1176231 -60.4056206 */ /* */ /* EXTREMAL FREQUENCIES--MAXIMA OF THE ERROR CURVE */ /* 0.0000000 0.0129076 0.0251359 0.0380435 0.0495924 */ /* 0.0618206 0.0733696 0.0842392 0.0930708 0.0968750 */ /* 0.1250000 0.1270380 0.1331521 0.1413043 0.1501357 */ /* 0.1596465 0.1698367 0.1800269 0.1908964 0.2010865 */ /* 0.2119560 0.2228255 0.2330157 0.2438852 0.2547547 */ /* 0.2656242 0.2764937 0.2873632 0.2982327 0.3091022 */ /* 0.3199717 0.3308412 0.3417107 0.3525802 0.3634497 */ /* 0.3743192 0.3851887 0.3960582 0.4069277 0.4177972 */ /* 0.4293461 0.4402156 0.4510851 0.4619546 0.4728241 */ /* 0.4836936 0.4945631 */ /* */ /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ /* Symbol Definitions. */ /**********************************************************************/ #define RD_INPUT_SAMPLE_STEP 4 #define RD_OUTPUT_SAMPLE_STEP 5 #define RD_STEP_PRODUCT ( RD_INPUT_SAMPLE_STEP * RD_OUTPUT_SAMPLE_STEP ) #define RD_POLYPHASE_FILTER_LENGTH 23 /**********************************************************************/ /* Start of SampleRate8000To6400 routine */ /**********************************************************************/ unsigned int SampleRate8000To6400( short * pwInputBuffer, short * pwOutputBuffer, unsigned int uiInputBufferLength, int * piFilterDelay, unsigned int * puiDelayPosition, int * piInputSampleTime, int * piOutputSampleTime ) { static int iPolyphaseFilter_0[23] = { 62, 344, -424, 604, -644, 461, 68, -1075, 2778, -5910, 16277, 23445, -4200, 788, 581, -1110, 1166, -960, 648, -328, 166, 201, -100 }; static int iPolyphaseFilter_1[23] = { -34, 397, -321, 321, -111, -328, 1037, -2011, 3242, -4849, 7996, 27598, 649, -2146, 2297, -1962, 1427, -863, 386, -44, -87, 333, -72 }; static int iPolyphaseFilter_2[23] = { -72, 333, -87, -44, 386, -863, 1427, -1962, 2297, -2146, 649, 27598, 7996, -4849, 3242, -2011, 1037, -328, -111, 321, -321, 397, -34 }; static int iPolyphaseFilter_3[23] = { -100, 201, 166, -328, 648, -960, 1166, -1110, 581, 788, -4200, 23445, 16277, -5910, 2778, -1075, 68, 461, -644, 604, -424, 344, 62 }; static int * ppiPolyphaseFilter[4] = { &iPolyphaseFilter_0[0], &iPolyphaseFilter_1[0], &iPolyphaseFilter_2[0], &iPolyphaseFilter_3[0] }; register int * piFilterCoefficients; register int iFilterIndex; register unsigned int uiDelayPosition; register int iInputSampleTime; register int iOutputSampleTime; register unsigned int uiInputIndex = 0; register unsigned int uiOutputIndex = 0; /********************************************************************/ /* Get the input filter state parameters. */ /********************************************************************/ uiDelayPosition = *puiDelayPosition; iInputSampleTime = *piInputSampleTime; iOutputSampleTime = *piOutputSampleTime; /********************************************************************/ /* Loop and process all of the input samples. */ /********************************************************************/ while ( uiInputIndex < uiInputBufferLength ) { /******************************************************************/ /* Put input samples in interpolator delay buffer until we */ /* catch up to the next output sample time index. */ /******************************************************************/ while (( iInputSampleTime <= iOutputSampleTime ) && ( uiInputIndex < uiInputBufferLength )) { /****************************************************************/ /* Put a new imput sample in the polyphase filter delay line. */ /****************************************************************/ piFilterDelay[uiDelayPosition++] = (int)pwInputBuffer[uiInputIndex++]; if ( uiDelayPosition >= RD_POLYPHASE_FILTER_LENGTH ) { uiDelayPosition = 0; } /****************************************************************/ /* Increment the input sample time index. */ /****************************************************************/ iInputSampleTime += RD_INPUT_SAMPLE_STEP; } /******************************************************************/ /* Calculate output samples using the interpolator until we */ /* reach the next input sample time. */ /******************************************************************/ while ( iOutputSampleTime < iInputSampleTime ) { /****************************************************************/ /* Calculate the polyphase filter index that corresponds to */ /* the next output sample. */ /****************************************************************/ iFilterIndex = iOutputSampleTime; while ( iFilterIndex >= RD_INPUT_SAMPLE_STEP ) { iFilterIndex = iFilterIndex - RD_INPUT_SAMPLE_STEP; } /****************************************************************/ /* Get the polyphase filter coefficients. */ /****************************************************************/ piFilterCoefficients = ppiPolyphaseFilter[iFilterIndex]; /****************************************************************/ /* Apply the polyphase filter. */ /****************************************************************/ pwOutputBuffer[uiOutputIndex++] = (short)FirFilter( piFilterCoefficients, piFilterDelay, uiDelayPosition, RD_POLYPHASE_FILTER_LENGTH ); /****************************************************************/ /* Increment the output sample time index. */ /****************************************************************/ iOutputSampleTime += RD_OUTPUT_SAMPLE_STEP; } /******************************************************************/ /* Wrap the input and output times indices so they don't */ /* overflow and go back to process more of the input block. */ /******************************************************************/ if ( iInputSampleTime >= RD_STEP_PRODUCT ) { iInputSampleTime -= RD_STEP_PRODUCT; iOutputSampleTime -= RD_STEP_PRODUCT; } } /********************************************************************/ /* Save the input filter state parameters. */ /********************************************************************/ *puiDelayPosition = uiDelayPosition; *piInputSampleTime = iInputSampleTime; *piOutputSampleTime = iOutputSampleTime; /********************************************************************/ /* Return the number of samples in the output buffer. */ /********************************************************************/ return uiOutputIndex; } #endif