You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6252 lines
160 KiB
6252 lines
160 KiB
#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; j<lng; j++)
|
|
{
|
|
high_p = mem+8;
|
|
low_p = mem;
|
|
|
|
*high_p = *in_low + *in_high;
|
|
*low_p = *in_low++ - *in_high++;
|
|
|
|
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++ = (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<N/4; i++) {
|
|
short temp;
|
|
|
|
*output++ = *input++;
|
|
*output++ = *input++;
|
|
*output++ = *input++;
|
|
*output++ = temp = *input++;
|
|
*output++ = temp;
|
|
}
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef _X86_
|
|
void iConvert8To64(short *input, short *output, short N, short *mem)
|
|
{
|
|
short LOW_A;
|
|
|
|
_asm
|
|
{
|
|
|
|
MOV ESI,[input]
|
|
MOV EDI,[output]
|
|
|
|
MOV CX,0
|
|
|
|
iDOWNSAMP:
|
|
CMP CX,WORD PTR [N]
|
|
JGE iEND_DOWNSAMP
|
|
|
|
MOV AX,[ESI]
|
|
MOV [EDI],AX ; out[0]=in[0]
|
|
|
|
MOV WORD PTR [LOW_A],0
|
|
MOV EBX,0
|
|
MOV AX,-3623
|
|
IMUL word ptr [ESI]
|
|
ADD [LOW_A],AX
|
|
MOVSX EAX,DX
|
|
ADC EBX,EAX
|
|
MOV AX,29200
|
|
IMUL word ptr [ESI+2]
|
|
ADD [LOW_A],AX
|
|
MOVSX EAX,DX
|
|
ADC EBX,EAX
|
|
MOV AX,7191
|
|
IMUL word ptr [ESI+4]
|
|
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,-3677
|
|
IMUL word ptr [ESI+2]
|
|
ADD [LOW_A],AX
|
|
MOVSX EAX,DX
|
|
ADC EBX,EAX
|
|
MOV AX,18494
|
|
IMUL word ptr [ESI+4]
|
|
ADD [LOW_A],AX
|
|
MOVSX EAX,DX
|
|
ADC EBX,EAX
|
|
MOV AX,17950
|
|
IMUL word ptr [ESI+6]
|
|
ADD [LOW_A],AX
|
|
MOVSX EAX,DX
|
|
ADC EBX,EAX
|
|
SAL EBX,1
|
|
MOV word ptr [EDI+4],BX ; out[2]
|
|
|
|
MOV AX,[ESI+8]
|
|
MOV [EDI+6],AX ; out[3]=in[4]
|
|
|
|
ADD CX,5
|
|
ADD SI,10
|
|
ADD EDI,8
|
|
|
|
JMP iDOWNSAMP
|
|
|
|
iEND_DOWNSAMP:
|
|
|
|
}
|
|
}
|
|
#else
|
|
/* Resample 8 KHz to 6.4 KHz */
|
|
void iConvert8To64(short *input, /* Pointer to input sample buffer */
|
|
short *output, /* Pointer to output sample buffer */
|
|
short N, /* Count of input samples */
|
|
short *mem) /* Pointer to two word temporary storage */
|
|
{
|
|
int i;
|
|
|
|
/* This copies 4 of every 5 samples */
|
|
/* (and leaves garbage at the end if not a multiple of 5 */
|
|
for(i=0; i<N/5; i++) {
|
|
*output++ = *input++ >> 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<lng; i++) {
|
|
*dest++ = *src++ * *fen++;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef _X86_
|
|
void autocor(short *vech,long *ri,short nech,short ordre)
|
|
{
|
|
short low_a,compta;
|
|
|
|
_asm
|
|
{
|
|
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
|
|
MOV BX,[nech]
|
|
MOV WORD PTR [low_a],0
|
|
MOV ECX,0
|
|
|
|
DYNAMIC:
|
|
MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source
|
|
IMUL AX ; DX:AX = xi*xi
|
|
ADD [low_a],AX
|
|
MOVSX EAX,DX
|
|
ADC ECX,EAX ;accumuler sur 48 bits
|
|
ADD ESI,2 ;Pointer ‚l‚men suiv.
|
|
SUB BX,1
|
|
JG DYNAMIC
|
|
|
|
MOV EDI,[ri] ;ES:DI adresse vect. autocorr.
|
|
|
|
MOV EAX,ECX
|
|
SAR EAX,15
|
|
ADD AX,0
|
|
JZ FORMAT_OK
|
|
|
|
;RISK_OV:
|
|
MOV AX,[low_a]
|
|
ADD AX,8
|
|
ADC ECX,0
|
|
SAR AX,4
|
|
AND AX,0FFFH
|
|
|
|
SAL ECX,12
|
|
OR CX,AX
|
|
MOV DWORD PTR [EDI],ECX ;Sauvegarder R(0)
|
|
|
|
MOVSX EAX,[ordre]
|
|
SAL EAX,2
|
|
ADD EDI,EAX ;Pointer dernier ‚l‚ment du vect. autoc.
|
|
|
|
ATCROV1:
|
|
MOV CX,[nech] ;Charger nombre de points vect. source
|
|
SUB CX,[ordre] ;D‚cr‚menter de l'ordre de corr‚lation
|
|
MOV [compta],CX
|
|
|
|
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
|
|
MOVSX EBX,[ordre]
|
|
ADD EBX,EBX ;D‚finir un Deplacement d'adresse vect. source
|
|
MOV ECX,0
|
|
MOV WORD PTR [low_a],0 ; //SS:
|
|
|
|
ATCROV2:
|
|
MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source
|
|
IMUL WORD PTR [ESI+EBX] ;Multiplier par l'‚l‚ment d‚cal‚
|
|
ADD [low_a],AX
|
|
MOVSX EAX,DX
|
|
ADC ECX,EAX
|
|
ADD ESI,2 ;Pointer ‚l‚men suiv.
|
|
SUB WORD PTR [compta],1 ; //SS:
|
|
JG ATCROV2
|
|
|
|
MOV AX,[low_a]
|
|
ADD AX,8
|
|
ADC ECX,0
|
|
SAR AX,4
|
|
AND AX,0FFFH
|
|
|
|
SAL ECX,12
|
|
OR CX,AX
|
|
MOV DWORD PTR [EDI],ECX ;Sauvegarder r‚sultat
|
|
SUB EDI,4 ;Pointer autocor. pr‚c‚dant
|
|
SUB WORD PTR [ordre],1 ;Test de fin de boucle //SS:
|
|
JG ATCROV1
|
|
|
|
JMP FIN_ATCR
|
|
|
|
FORMAT_OK:
|
|
SAL ECX,16
|
|
MOV CX,[low_a]
|
|
MOV DWORD PTR [EDI],ECX ;Sauvegarder R(0)
|
|
MOVSX EAX,WORD PTR [ordre]
|
|
SAL EAX,2
|
|
ADD EDI,EAX ;Pointer dernier ‚l‚ment du vect. autoc.
|
|
|
|
ATCR10:
|
|
MOV CX,[nech] ;Charger nombre de points vect. source
|
|
SUB CX,[ordre] ;D‚cr‚menter de l'ordre de corr‚lation
|
|
MOV [compta],CX
|
|
|
|
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
|
|
MOVSX EBX,[ordre]
|
|
ADD EBX,EBX ;D‚finir un Deplacement d'adresse vect. source
|
|
MOV CX,0
|
|
MOV WORD PTR [low_a],0 ;//SS:
|
|
|
|
ATCR20:
|
|
MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source
|
|
IMUL WORD PTR [ESI+EBX] ;Multiplier par l'‚l‚ment d‚cal‚
|
|
ADD [low_a],AX
|
|
ADC CX,DX
|
|
ADD ESI,2 ;Pointer ‚l‚men suiv.
|
|
SUB WORD PTR [compta],1 ;//SS:
|
|
JG ATCR20
|
|
|
|
MOV AX,[low_a]
|
|
MOV WORD PTR [EDI],AX ;Sauvegarder r‚sultat
|
|
MOV WORD PTR [EDI+2],CX
|
|
|
|
SUB EDI,4 ;Pointer autocor. pr‚c‚dant
|
|
SUB WORD PTR [ordre],1 ;Test de fin de boucle
|
|
JG ATCR10
|
|
|
|
FIN_ATCR:
|
|
|
|
} // _asm
|
|
}
|
|
#else
|
|
void autocor(short *vech,long *ri,short nech,short ordre)
|
|
{
|
|
// TODO: Fill this in
|
|
}
|
|
#endif
|
|
|
|
#ifdef _X86_
|
|
short max_autoc(short *vech,short nech,short debut,short fin)
|
|
{
|
|
short max_pos,max_l,compta;
|
|
long lmax_h;
|
|
|
|
_asm
|
|
{
|
|
MOV WORD PTR [max_pos],69
|
|
MOV DWORD PTR [lmax_h],-6969
|
|
MOV WORD PTR [max_l],69
|
|
|
|
M_ATCR1:
|
|
MOV CX,[nech] ;Charger nombre de points vect. source
|
|
MOVSX EBX,WORD PTR [fin]
|
|
SUB CX,BX ;D‚cr‚menter de l'ordre de corr‚lation
|
|
MOV [compta],CX
|
|
|
|
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
|
|
|
|
ADD EBX,EBX ;D‚finir un Deplacement d'adresse vect. source
|
|
|
|
MOV ECX,0
|
|
MOV DI,0;
|
|
|
|
M_ATCR2:
|
|
MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source
|
|
IMUL WORD PTR [ESI+EBX] ;Multiplier par l'‚l‚ment d‚cal‚
|
|
ADD DI,AX
|
|
MOVSX EAX,DX
|
|
ADC ECX,EAX
|
|
ADD ESI,2 ;Pointer ‚l‚men suiv.
|
|
SUB WORD PTR [compta],1
|
|
JG M_ATCR2
|
|
|
|
MOV BX,[max_l]
|
|
SUB BX,DI
|
|
|
|
MOV EDX,[lmax_h]
|
|
SBB EDX,ECX
|
|
|
|
JGE NEXT_ITR
|
|
|
|
MOV [max_l],DI ;save max
|
|
MOV [lmax_h],ECX
|
|
MOV AX,[fin]
|
|
MOV [max_pos],AX
|
|
|
|
NEXT_ITR:
|
|
MOV CX,[fin] ;Test de fin de boucle
|
|
SUB CX,1
|
|
MOV [fin],CX
|
|
SUB CX,[debut]
|
|
JGE M_ATCR1
|
|
|
|
}
|
|
|
|
// MOV AX,[max_pos]
|
|
return max_pos;
|
|
}
|
|
#else
|
|
short max_autoc(short *vech,short nech,short debut,short fin)
|
|
{
|
|
// TODO need 64-bit
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef _X86_
|
|
#pragma warning(disable : 4035)
|
|
short max_vect(short *vech,short nech)
|
|
{
|
|
|
|
_asm
|
|
{
|
|
MOV CX,[nech] ;Charger nombre de points vect. source
|
|
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
|
|
|
|
MOV AX,-32767 ; AX = maximum
|
|
|
|
L_M_VECT:
|
|
MOV BX,WORD PTR [ESI] ;Charger elem. vect.
|
|
ADD BX,0
|
|
JGE BX_POSIT
|
|
NEG BX
|
|
|
|
BX_POSIT:
|
|
CMP BX,AX
|
|
JLE NEXT_VALUE
|
|
MOV AX,BX
|
|
|
|
NEXT_VALUE:
|
|
ADD ESI,2
|
|
DEC CX
|
|
JNE L_M_VECT
|
|
}
|
|
|
|
}
|
|
#pragma warning(default : 4035)
|
|
|
|
void upd_max(long *corr_ene,long *vval,short pitch)
|
|
{
|
|
_asm
|
|
{
|
|
MOV ESI,[corr_ene] ; DS:SI adresse correlation et energie
|
|
MOV EDI,[vval] ; ES:DI maximum.
|
|
|
|
|
|
MOV EAX,DWORD PTR [ESI+8] ; AX = partie haute de ener
|
|
SAR EAX,15
|
|
ADD AX,0
|
|
JE FORMA32
|
|
|
|
MOV EAX,DWORD PTR [ESI] ;EAX = corr. high
|
|
MOV BX,WORD PTR [ESI+4]
|
|
ADD BX,8
|
|
ADC EAX,0
|
|
SAR BX,4
|
|
AND BX,0FFFH
|
|
SAL EAX,12
|
|
OR AX,BX
|
|
ADD EAX,0
|
|
JGE CORR_POSIT
|
|
NEG EAX
|
|
|
|
CORR_POSIT:
|
|
MOV DWORD PTR [ESI+16],EAX
|
|
|
|
MOV EBX,DWORD PTR [ESI+8]
|
|
MOV DX,WORD PTR [ESI+12]
|
|
ADD DX,8
|
|
ADC EBX,0
|
|
SAR DX,4
|
|
AND DX,0FFFH
|
|
SAL EBX,12
|
|
OR BX,DX
|
|
MOV DWORD PTR [ESI+20],EBX
|
|
MOV ECX,4
|
|
JMP DEB_COMP
|
|
|
|
FORMA32:
|
|
MOV ECX,0 ; init normalisat.
|
|
MOV AX,WORD PTR [ESI]
|
|
SAL EAX,16
|
|
MOV AX,WORD PTR [ESI+4]
|
|
ADD EAX,0
|
|
JGE CORR_POSIT2
|
|
NEG EAX
|
|
|
|
CORR_POSIT2:
|
|
MOV DWORD PTR [ESI+16],EAX
|
|
MOV BX,WORD PTR [ESI+8]
|
|
SAL EBX,16
|
|
MOV BX,WORD PTR [ESI+12]
|
|
MOV DWORD PTR [ESI+20],EBX
|
|
|
|
DEB_COMP:
|
|
; EAX = correl.
|
|
; EBX = ener
|
|
ADD EBX,0
|
|
JE ENER_NULL
|
|
|
|
MOV DX,WORD PTR [ESI+22]
|
|
ADD DX,WORD PTR [ESI+18]
|
|
JG GT16BIT
|
|
|
|
;FORM_16:
|
|
SAL EBX,15
|
|
SAL EAX,15
|
|
SUB ECX,15
|
|
GT16BIT:
|
|
ADD EAX,0
|
|
JE ENER_NULL
|
|
CMP EBX,40000000H
|
|
JGE NO_E_NORMU
|
|
NORM_ENEU:
|
|
ADD EBX,EBX
|
|
INC ECX
|
|
CMP EBX,40000000H
|
|
JL NORM_ENEU
|
|
|
|
NO_E_NORMU:
|
|
CMP EAX,40000000H ; normaliser acc
|
|
JGE PAS_D_N_C
|
|
|
|
NORM_CORL:
|
|
ADD EAX,EAX
|
|
SUB ECX,2
|
|
CMP EAX,40000000H
|
|
JL NORM_CORL
|
|
PAS_D_N_C:
|
|
IMUL EAX ;EDX:EAX = produit
|
|
CMP EDX,20000000H
|
|
JLE MAKE_DIVU
|
|
|
|
SHRD EAX,EDX,1
|
|
SAR EDX,1
|
|
INC ECX
|
|
|
|
MAKE_DIVU:
|
|
IDIV EBX
|
|
CMP EAX,40000000H
|
|
JGE SAVE_RAPP
|
|
|
|
NORM_RAPP:
|
|
ADD EAX,EAX
|
|
DEC ECX
|
|
CMP EAX,40000000H
|
|
JLE NORM_RAPP
|
|
|
|
SAVE_RAPP:
|
|
MOV EBX,DWORD PTR [EDI+4]
|
|
CMP ECX,EBX
|
|
JG UPDATE_M
|
|
JL ENER_NULL
|
|
|
|
;EBX_EQU_ECX:
|
|
MOV EBX,DWORD PTR [EDI]
|
|
CMP EAX,EBX
|
|
JLE ENER_NULL
|
|
|
|
UPDATE_M:
|
|
MOV DWORD PTR [EDI],EAX ; sauver mant. et exp. max
|
|
MOV DWORD PTR [EDI+4],ECX
|
|
|
|
MOV EAX,DWORD PTR [ESI+16]
|
|
MOV EDX,DWORD PTR [ESI]
|
|
ADD EDX,0
|
|
JGE SIGNE_OK
|
|
NEG EAX
|
|
SIGNE_OK:
|
|
MOV DWORD PTR [EDI+8],EAX
|
|
MOV EAX,DWORD PTR [ESI+20]
|
|
MOV DWORD PTR [EDI+12],EAX
|
|
|
|
MOVSX EAX,WORD PTR [pitch]
|
|
MOV DWORD PTR [EDI+16],EAX
|
|
|
|
ENER_NULL:
|
|
|
|
}
|
|
}
|
|
|
|
|
|
#pragma warning(disable : 4035)
|
|
|
|
short upd_max_d(long *corr_ene,long *vval)
|
|
{
|
|
_asm
|
|
{
|
|
MOV ESI,[corr_ene] ; DS:SI adresse correlation et energie
|
|
MOV EDI,[vval] ; ES:DI maximum.
|
|
|
|
MOV AX,0
|
|
MOV EBX,DWORD PTR [ESI+4] ;EBX = ener
|
|
ADD EBX,0
|
|
JE ENER_ZRO
|
|
|
|
MOV EAX,DWORD PTR [ESI] ; EAX = corr.
|
|
SAL EAX,10 ; 12 initialement
|
|
IMUL EAX ; EDX:EAX = corr*corr
|
|
|
|
IDIV EBX ; EAX = corr*corr/ener
|
|
|
|
MOV ECX,EAX
|
|
MOV AX,0
|
|
MOV EDX,DWORD PTR [EDI] ; EDX = GGmax
|
|
CMP ECX,EDX
|
|
JLE ENER_ZRO
|
|
MOV DWORD PTR [EDI],ECX ; save max
|
|
MOV DWORD PTR [EDI+8],EBX
|
|
MOV EAX,DWORD PTR [ESI] ; EAX = corr.
|
|
MOV DWORD PTR [EDI+4],EAX
|
|
MOV AX,7FFFH
|
|
ENER_ZRO:
|
|
}
|
|
}
|
|
#pragma warning(default : 4035)
|
|
|
|
void norm_corrl(long *corr,long *vval)
|
|
{
|
|
_asm
|
|
{
|
|
MOV ESI,[corr] ; DS:SI adresse vect. corr.
|
|
MOV EDI,[vval] ; ES:DI adresse acc et ener.
|
|
|
|
MOV EAX,DWORD PTR [EDI+8] ; AX = partie haute de ener
|
|
SAR EAX,15
|
|
ADD AX,0
|
|
JE FORM_32
|
|
|
|
MOV EAX,DWORD PTR [EDI]
|
|
MOV BX,WORD PTR [EDI+4]
|
|
ADD BX,32
|
|
ADC EAX,0
|
|
SAR BX,5
|
|
AND BX,07FFH
|
|
SAL EAX,11 ;
|
|
OR AX,BX
|
|
MOV DWORD PTR [EDI+16],EAX
|
|
|
|
MOV EBX,DWORD PTR [EDI+8]
|
|
MOV DX,WORD PTR [EDI+12]
|
|
ADD DX,32
|
|
ADC EBX,0
|
|
SAR DX,5
|
|
AND DX,07FFH
|
|
SAL EBX,11 ;
|
|
OR BX,DX
|
|
MOV DWORD PTR [EDI+20],EBX
|
|
MOV ECX,5
|
|
JMP DEB_PROC
|
|
|
|
FORM_32:
|
|
MOV ECX,0 ; init normalisation
|
|
MOV AX,WORD PTR [EDI]
|
|
SAL EAX,16
|
|
MOV AX,WORD PTR [EDI+4]
|
|
MOV DWORD PTR [EDI+16],EAX
|
|
|
|
MOV BX,WORD PTR [EDI+8]
|
|
SAL EBX,16
|
|
MOV BX,WORD PTR [EDI+12]
|
|
MOV DWORD PTR [EDI+20],EBX
|
|
|
|
DEB_PROC:
|
|
ADD EAX,0 ;EAX = acc
|
|
JLE CORR_LE_0
|
|
|
|
CMP EBX,40000000H
|
|
JGE NO_E_NORM
|
|
|
|
NORM_ENE:
|
|
ADD EBX,EBX
|
|
INC ECX
|
|
CMP EBX,40000000H
|
|
JL NORM_ENE
|
|
|
|
NO_E_NORM:
|
|
CMP EAX,40000000H ; normaliser acc
|
|
JGE PAS_D_NORM
|
|
|
|
NORM_ACC:
|
|
ADD EAX,EAX
|
|
SUB ECX,2
|
|
CMP EAX,40000000H
|
|
JL NORM_ACC
|
|
|
|
PAS_D_NORM:
|
|
IMUL EAX ;EDX:EAX = produit
|
|
CMP EDX,20000000H
|
|
JLE MAKE_DIV
|
|
SHRD EAX,EDX,1
|
|
SAR EDX,1
|
|
INC ECX
|
|
|
|
MAKE_DIV:
|
|
IDIV EBX
|
|
CMP EAX,40000000H
|
|
JL SAVE_CRR
|
|
|
|
SAR EAX,1
|
|
INC ECX
|
|
JMP SAVE_CRR
|
|
|
|
CORR_LE_0:
|
|
MOV EAX,0
|
|
MOV ECX,-69
|
|
|
|
SAVE_CRR:
|
|
MOV DWORD PTR [ESI],EAX
|
|
MOV DWORD PTR [ESI+4],ECX
|
|
}
|
|
}
|
|
|
|
void norm_corrr(long *corr,long *vval)
|
|
{
|
|
_asm
|
|
{
|
|
MOV ESI,[corr] ; DS:SI adresse vect. corr.
|
|
MOV EDI,[vval] ; ES:DI adresse acc et ener.
|
|
|
|
MOV EAX,DWORD PTR [EDI+8] ; AX = partie haute de ener
|
|
SAR EAX,15
|
|
ADD AX,0
|
|
JE FORM_32R
|
|
|
|
MOV EAX,DWORD PTR [EDI]
|
|
MOV BX,WORD PTR [EDI+4]
|
|
ADD BX,32
|
|
ADC EAX,0
|
|
SAR BX,5
|
|
AND BX,07FFH
|
|
SAL EAX,11 ;
|
|
OR AX,BX
|
|
MOV DWORD PTR [EDI+16],EAX
|
|
|
|
MOV EBX,DWORD PTR [EDI+8]
|
|
MOV DX,WORD PTR [EDI+12]
|
|
ADD DX,32
|
|
ADC EBX,0
|
|
SAR DX,5
|
|
AND DX,07FFH
|
|
SAL EBX,11 ;
|
|
OR BX,DX
|
|
MOV DWORD PTR [EDI+20],EBX
|
|
MOV ECX,5
|
|
JMP DEB_PROCR
|
|
|
|
FORM_32R:
|
|
MOV ECX,0 ; init normalisat.
|
|
MOV AX,WORD PTR [EDI]
|
|
SAL EAX,16
|
|
MOV AX,WORD PTR [EDI+4]
|
|
MOV DWORD PTR [EDI+16],EAX
|
|
|
|
MOV BX,WORD PTR [EDI+8]
|
|
SAL EBX,16
|
|
MOV BX,WORD PTR [EDI+12]
|
|
MOV DWORD PTR [EDI+20],EBX
|
|
|
|
DEB_PROCR:
|
|
;EAX = acc
|
|
ADD EAX,0
|
|
JLE CORRR_LE_0
|
|
;EBX = ener
|
|
CMP EBX,40000000H
|
|
JGE NO_E_NORMR
|
|
|
|
NORM_ENER:
|
|
ADD EBX,EBX
|
|
INC ECX
|
|
CMP EBX,40000000H
|
|
JL NORM_ENER
|
|
|
|
NO_E_NORMR:
|
|
CMP EAX,40000000H ; normaliser acc
|
|
JGE PAS_D_NORMR
|
|
|
|
NORM_ACCR:
|
|
ADD EAX,EAX
|
|
SUB ECX,2
|
|
CMP EAX,40000000H
|
|
JL NORM_ACCR
|
|
|
|
PAS_D_NORMR:
|
|
IMUL EAX ;EDX:EAX = produit
|
|
CMP EDX,20000000H
|
|
JLE MAKE_DIVR
|
|
|
|
SHRD EAX,EDX,1
|
|
SAR EDX,1
|
|
INC ECX
|
|
|
|
MAKE_DIVR:
|
|
IDIV EBX
|
|
CMP EAX,40000000H
|
|
JL SAVE_CRRR
|
|
|
|
SAR EAX,1
|
|
INC ECX
|
|
|
|
SAVE_CRRR:
|
|
MOV EBX,DWORD PTR [ESI+4]
|
|
CMP EBX,ECX
|
|
JL BX_LT_CX
|
|
JG BX_GT_CX
|
|
|
|
;BX_EQU_CX:
|
|
ADD DWORD PTR [ESI],EAX
|
|
JMP CORRR_LE_0
|
|
|
|
BX_LT_CX:
|
|
MOV DWORD PTR [ESI+4],ECX ; sauver exp.
|
|
SUB CX,BX ;
|
|
MOV EDX,DWORD PTR [ESI]
|
|
SAR EDX,CL
|
|
ADD EAX,EDX
|
|
MOV DWORD PTR [ESI],EAX
|
|
JMP CORRR_LE_0
|
|
|
|
BX_GT_CX:
|
|
SUB BX,CX ;
|
|
MOV CL,BL
|
|
SAR EAX,CL
|
|
ADD DWORD PTR [ESI],EAX
|
|
CORRR_LE_0:
|
|
MOV EAX,DWORD PTR [ESI]
|
|
MOV ECX,DWORD PTR [ESI+4]
|
|
ADD EAX,0
|
|
JZ END_CRRR
|
|
|
|
CMP EAX,40000000H
|
|
JGE END_CRRR
|
|
|
|
NRM_RR:
|
|
ADD EAX,EAX
|
|
DEC ECX
|
|
CMP EAX,40000000H
|
|
JL NRM_RR
|
|
|
|
MOV DWORD PTR [ESI],EAX
|
|
MOV DWORD PTR [ESI+4],ECX
|
|
|
|
END_CRRR:
|
|
}
|
|
}
|
|
|
|
void energy(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_ENERGY:
|
|
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_ENERGY
|
|
|
|
MOV ESI,[ene] ; adresse result.
|
|
MOV DWORD PTR [ESI],EBX
|
|
MOV WORD PTR [ESI+4],DI
|
|
}
|
|
}
|
|
|
|
void venergy(short *vech,long *vene,short lng)
|
|
{
|
|
_asm
|
|
{
|
|
|
|
MOV ESI,[vech] ; DS:SI adresse vect. echantillons
|
|
MOV EDI,[vene] ; adresse result.
|
|
|
|
MOV EBX,0
|
|
MOV CX,0
|
|
L_VENERGY:
|
|
MOV AX,WORD PTR [ESI] ;Charger ‚l‚ment vect. source
|
|
IMUL AX ;Multiplier
|
|
ADD CX,AX
|
|
MOVSX EAX,DX
|
|
ADC EBX,EAX ; acc. en EBX:CX
|
|
ADD ESI,2 ;Pointer ‚l‚men suiv.
|
|
|
|
MOV EDX,EBX ; sauver EBX:CX>>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<lng; i++)
|
|
*dest++ = *src++;
|
|
}
|
|
|
|
|
|
void long_to_long(long *src,long *dest,short lng)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void init_zero(short *src,short lng)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void update_ltp(short *y1,short *y2,short hy[],short lng,short gdgrd,short fact)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void proc_gain2(long *corr_ene,long *gain,short bit_garde)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void decode_dic(short *code,short dic,short npuls)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void dsynthesis(long *z,short *coef,short *input,short *output,
|
|
short lng,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void synthesis(short *z,short *coef,short *input,short *output,
|
|
short lng,short netages,short bdgrd )
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void synthese(short *z,short *coef,short *input,short *output,
|
|
short lng,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void f_inverse(short *z,short *coef,short *input,short *output,
|
|
short lng,short netages )
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void filt_iir(long *zx,long *ai,short *Vin,short *Vout,short lfen,short ordre)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void mult_fact(short src[],short dest[],short fact,short lng)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void mult_f_acc(short src[],short dest[],short fact,short lng)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void dec_lsp(short *code,short *tablsp,short *nbit,short *bitdi,short *tabdi)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void teta_to_cos(short *tabcos,short *lsp,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void cos_to_teta(short *tabcos,short *lsp,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void lsp_to_ai(short *ai_lsp,long *tmp,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void ki_to_ai(short *ki,long *ai,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void ai_to_pq(long *aip,short netages)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void horner(long *P,long *T,long *a,short n,short s)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
short calcul_s(long a,long b)
|
|
{
|
|
// TODO need 64-bit
|
|
return 0;
|
|
}
|
|
|
|
void binome(short *lsp,long *PP)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void deacc(short *src,short *dest,short fact,short lfen,short *last_out)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
void filt_in(short *mem,short *Vin,short *Vout,short lfen)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
|
|
short calc_gltp(short *gltp,short *bq,short *bv,long ttt)
|
|
{
|
|
// TODO need 64-bit
|
|
return 0;
|
|
}
|
|
|
|
short calc_garde(short MAX)
|
|
{
|
|
// TODO need 64-bit
|
|
return 0;
|
|
}
|
|
|
|
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)
|
|
{
|
|
// TODO need 64-bit
|
|
return 0;
|
|
}
|
|
|
|
void decimation(short *vin,short *vout,short nech)
|
|
{
|
|
// TODO need 64-bit
|
|
}
|
|
#endif
|
|
|
|
#ifndef _X86_
|
|
/**********************************************************************/
|
|
/**********************************************************************/
|
|
/* */
|
|
/* Function: DotProduct */
|
|
/* Author: Bill Hallahan */
|
|
/* Date: March 10, 1997 */
|
|
/* */
|
|
/* Abstract: */
|
|
/* */
|
|
/* This function returns the dot product of a set of two */
|
|
/* vectors. */
|
|
/* */
|
|
/* Inputs: */
|
|
/* */
|
|
/* pVector_0 A pointer of type T that points to the first */
|
|
/* input vector. */
|
|
/* */
|
|
/* pVector_1 A pointer of type T that points to the second */
|
|
/* input vector. */
|
|
/* */
|
|
/* uiLength The length of the input vectors. */
|
|
/* */
|
|
/* */
|
|
/* Outputs: */
|
|
/* */
|
|
/* The dot product of the two input vectors is calculated. The */
|
|
/* return value is a 64 bit Q30 number. */
|
|
/* */
|
|
/**********************************************************************/
|
|
/**********************************************************************/
|
|
|
|
/**********************************************************************/
|
|
/* Start of routine DotProduct(). */
|
|
/**********************************************************************/
|
|
|
|
_int64 DotProduct( int * piVector_0,
|
|
int * piVector_1,
|
|
unsigned int uiLength )
|
|
{
|
|
/********************************************************************/
|
|
/* Do the multiply-accumulates in groups of 8 values. */
|
|
/********************************************************************/
|
|
|
|
_int64 qSum = 0;
|
|
|
|
while ( uiLength >= 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
|