Windows-Server-2003/enduser/netmeeting/av/codecs/lh/bib_32.c

6253 lines
154 KiB
C
Raw Permalink Blame History

#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 <EFBFBD>l<EFBFBD>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 <EFBFBD>l<EFBFBD>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 <EFBFBD>l<EFBFBD>ment du vect. autoc.
ATCROV1:
MOV CX,[nech] ;Charger nombre de points vect. source
SUB CX,[ordre] ;D<EFBFBD>cr<EFBFBD>menter de l'ordre de corr<EFBFBD>lation
MOV [compta],CX
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
MOVSX EBX,[ordre]
ADD EBX,EBX ;D<EFBFBD>finir un Deplacement d'adresse vect. source
MOV ECX,0
MOV WORD PTR [low_a],0 ; //SS:
ATCROV2:
MOV AX,WORD PTR [ESI] ;Charger <EFBFBD>l<EFBFBD>ment vect. source
IMUL WORD PTR [ESI+EBX] ;Multiplier par l'<EFBFBD>l<EFBFBD>ment d<EFBFBD>cal<EFBFBD>
ADD [low_a],AX
MOVSX EAX,DX
ADC ECX,EAX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>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<EFBFBD>sultat
SUB EDI,4 ;Pointer autocor. pr<EFBFBD>c<EFBFBD>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 <EFBFBD>l<EFBFBD>ment du vect. autoc.
ATCR10:
MOV CX,[nech] ;Charger nombre de points vect. source
SUB CX,[ordre] ;D<EFBFBD>cr<EFBFBD>menter de l'ordre de corr<EFBFBD>lation
MOV [compta],CX
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
MOVSX EBX,[ordre]
ADD EBX,EBX ;D<EFBFBD>finir un Deplacement d'adresse vect. source
MOV CX,0
MOV WORD PTR [low_a],0 ;//SS:
ATCR20:
MOV AX,WORD PTR [ESI] ;Charger <EFBFBD>l<EFBFBD>ment vect. source
IMUL WORD PTR [ESI+EBX] ;Multiplier par l'<EFBFBD>l<EFBFBD>ment d<EFBFBD>cal<EFBFBD>
ADD [low_a],AX
ADC CX,DX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>men suiv.
SUB WORD PTR [compta],1 ;//SS:
JG ATCR20
MOV AX,[low_a]
MOV WORD PTR [EDI],AX ;Sauvegarder r<EFBFBD>sultat
MOV WORD PTR [EDI+2],CX
SUB EDI,4 ;Pointer autocor. pr<EFBFBD>c<EFBFBD>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<EFBFBD>cr<EFBFBD>menter de l'ordre de corr<EFBFBD>lation
MOV [compta],CX
MOV ESI,[vech] ;DS:SI adresse vect. echantillons
ADD EBX,EBX ;D<EFBFBD>finir un Deplacement d'adresse vect. source
MOV ECX,0
MOV DI,0;
M_ATCR2:
MOV AX,WORD PTR [ESI] ;Charger <EFBFBD>l<EFBFBD>ment vect. source
IMUL WORD PTR [ESI+EBX] ;Multiplier par l'<EFBFBD>l<EFBFBD>ment d<EFBFBD>cal<EFBFBD>
ADD DI,AX
MOVSX EAX,DX
ADC ECX,EAX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>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 <EFBFBD>l<EFBFBD>ment vect. source
IMUL AX ;Multiplier
ADD DI,AX
MOVSX EAX,DX
ADC EBX,EAX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>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 <EFBFBD>l<EFBFBD>ment vect. source
IMUL AX ;Multiplier
ADD CX,AX
MOVSX EAX,DX
ADC EBX,EAX ; acc. en EBX:CX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>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 <EFBFBD>l<EFBFBD>ment vect. source
IMUL AX ;Multiplier
ADD DI,AX
MOVSX EAX,DX
ADC EBX,EAX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>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 <EFBFBD> ajouter
ADD AX,CX
ADC EBX,EDX
MOV CX,WORD PTR [EDI+4]
MOVSX EDX,WORD PTR [EDI+6] ; EDX:CX <EFBFBD> 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 <EFBFBD>l<EFBFBD>ment vect. source
IMUL WORD PTR [EDI] ;Multiplier par l'<EFBFBD>l<EFBFBD>ment d<EFBFBD>cal<EFBFBD>
ADD [low_a],AX
MOVSX EAX,DX
ADC EBX,EAX
ADD ESI,2 ;Pointer <EFBFBD>l<EFBFBD>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<EFBFBD>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<EFBFBD>e
NEG EBX
SAL EBX,16
ADD DWORD PTR [input],2 ; increm.
MOV DWORD PTR [EDI],EBX ; mise <EFBFBD> jour m<EFBFBD>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 <EFBFBD> jour m<EFBFBD>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<EFBFBD>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<EFBFBD>e
NEG BX
ADD DWORD PTR [input],2 ; increm.
MOV WORD PTR [EDI],BX ; mise <EFBFBD> jour m<EFBFBD>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 <EFBFBD> jour m<EFBFBD>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<EFBFBD>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<EFBFBD>e
NEG BX
ADD DWORD PTR [input],2 ; increm.
MOV WORD PTR [EDI],BX ; mise <EFBFBD> jour m<EFBFBD>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 <EFBFBD> jour m<EFBFBD>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<EFBFBD>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<EFBFBD>e
ADD DWORD PTR [input],2 ; increm.
MOV WORD PTR [EDI],BX ; mise <EFBFBD> jour m<EFBFBD>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<EFBFBD>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<EFBFBD>menter l'offset de input
MOV ESI,[zx] ; DS:SI pointe zx
MOV DWORD PTR [ESI],EDX ; mettre <EFBFBD> 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 <EFBFBD> 0
SUB EBX,EBX ; init EBX = 0
F_IIR_Y:
MOV EAX,DWORD PTR [ESI] ;EAX = *zx
MOV DWORD PTR [ESI+4],EAX ;mettre <EFBFBD> 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 <EFBFBD> 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<EFBFBD>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<63>menter l'offset de input
MOV ESI,[zx] ; DS:SI pointe zx
MOV DWORD PTR [ESI],EDX ; mettre <20> 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 <20> 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 <20> 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 <20> 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<63>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<EFBFBD>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<EFBFBD>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 <EFBFBD> 4000h
JLE INIT_VAL ;
NEG AX
ADD AX,32767 ; prendre le compl<EFBFBD>ment
INIT_VAL:
MOV ESI,[tabcos]
CMP AX,0738H ; comparer <EFBFBD>
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<EFBFBD>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 <EFBFBD> 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 <EFBFBD>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