📄 tetra_op.c
字号:
/***********************************************************************
*
* FILENAME : tetra_op.c
*
* DESCRIPTION : TETRA basic operators
*
************************************************************************
*
* FUNCTIONS : - abs_s()
* - add()
* - div_s()
* - extract_h()
* - extract_l()
* - L_abs()
* - L_add()
* - L_deposit_h()
* - L_deposit_l()
* - L_mac()
* - L_mac0()
* - L_msu()
* - L_msu0()
* - L_mult()
* - L_mult0()
* - L_negate()
* - L_shl()
* - L_shr()
* - L_shr_r()
* - L_sub()
* - mult()
* - mult_r()
* - negate()
* - norm_l()
* - norm_s()
* - round()
* - sature()
* - shl()
* - shr()
* - sub()
*
* COMMENTS : Only the operators used in the actual version
* of the TETRA codec are included in this file
*
************************************************************************
*
* INCLUDED FILES : source.h
* stdio.h
* stdlib.h
*
************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "source.h"
/*-----------------*
* Local Functions *
*-----------------*/
Word16 sature(Word32 L_var1);
/*-----------------------*
* Constants and Globals *
*-----------------------*/
Flag Overflow =0;
Flag Carry =0;
/************************************************************************
*
* Function Name : abs_s
*
* Purpose :
*
* Absolute value of var1; abs_s(-32768) = 32767.
*
* Complexity Weight : 1
*
* Inputs :
*
* var1
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var1 <= 0x0000 7fff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* var_out
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0x0000 0000 <= var_out <= 0x0000 7fff.
*
************************************************************************/
Word16 abs_s(Word16 var1)
{
Word16 var_out;
if (var1 == (Word16)0X8000 )
{
var_out = MAX_16;
}
else
{
if (var1 < 0)
{
var_out = -var1;
}
else
{
var_out = var1;
}
}
return(var_out);
}
/************************************************************************
*
* Function Name : add
*
* Purpose :
*
* Performs the addition (var1+var2) with overflow control and saturation;|
* the 16 bit result is set at +32767 when overflow occurs or at -32768
* when underflow occurs.
*
* Complexity Weight : 1
*
* Inputs :
*
* var1
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var1 <= 0x0000 7fff.
*
* var2
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var2 <= 0x0000 7fff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* var_out
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var_out <= 0x0000 7fff.
*
************************************************************************/
Word16 add(Word16 var1,Word16 var2)
{
Word16 var_out;
Word32 L_somme;
L_somme = (Word32) var1 + var2;
var_out = sature(L_somme);
return(var_out);
}
/************************************************************************
*
* Function Name : div_s
*
* Purpose :
*
* Produces a result which is the fractionnal integer division of var1 by
* var2; var1 and var2 must be positive and var2 must be greater or equal
* to var1; the result is positive (leading bit equal to 0) and truncated
* to 16 bits.
* If var1 = var2 then div(var1,var2) = 32767.
*
* Complexity Weight : 18
*
* Inputs :
*
* var1
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0x0000 0000 <= var1 <= var2 and var2 != 0.
*
* var2
* 16 bit short signed integer (Word16) whose value falls in the
* range : var1 <= var2 <= 0x0000 7fff and var2 != 0.
*
* Outputs :
*
* none
*
* Returned Value :
*
* var_out
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0x0000 0000 <= var_out <= 0x0000 7fff.
* It's a Q15 value (point between b15 and b14).
*
************************************************************************/
Word16 div_s(Word16 var1, Word16 var2)
{
Word16 var_out = 0;
Word16 iteration;
Word32 L_num;
Word32 L_denom;
if ((var1 > var2) || (var1 < 0) || (var2 < 0))
{
//printf("Division Error\n");
exit(0);
}
if (var2 == 0)
{
//printf("Division by 0, Fatal error \n");
exit(0);
}
if (var1 == 0)
{
var_out = 0;
}
else
{
if (var1 == var2)
{
var_out = MAX_16;
}
else
{
L_num = (Word32) (var1);
L_denom = (Word32) (var2);
for(iteration=0;iteration<15;iteration++)
{
var_out <<=1;
L_num <<= 1;
if (L_num >= L_denom)
{
L_num = L_sub(L_num,L_denom);
var_out = add( var_out,(Word16)1 );
}
}
}
}
return(var_out);
}
/************************************************************************
*
* Function Name : extract_h
*
* Purpose :
*
* Return the 16 MSB of L_var1.
*
* Complexity Weight : 1
*
* Inputs :
*
* L_var1
* 32 bit long signed integer (Word32 ) whose value falls in the
* range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* var_out
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var_out <= 0x0000 7fff.
*
************************************************************************/
/*Word16 extract_h(Word32 L_var1)
{
Word16 var_out;
var_out = (Word16) (L_var1 >> 16);
return(var_out);
}*/
/************************************************************************
*
* Function Name : extract_l
*
* Purpose :
*
* Return the 16 LSB of L_var1.
*
* Complexity Weight : 1
*
* Inputs :
*
* L_var1
* 32 bit long signed integer (Word32 ) whose value falls in the
* range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* var_out
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var_out <= 0x0000 7fff.
*
************************************************************************/
/*Word16 extract_l(Word32 L_var1)
{
Word16 var_out;
var_out = (Word16) L_var1;
return(var_out);
}*/
/************************************************************************
*
* Function Name : L_abs
*
* Purpose :
*
* Absolute value of L_var1; Saturate in case where the input is -214783648
*
* Complexity Weight : 3
*
* Inputs :
*
* L_var1
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* L_var_out
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x0000 0000 <= L_var_out <= 0x7fff ffff.
*
************************************************************************/
Word32 L_abs(Word32 L_var1)
{
Word32 L_var_out;
if (L_var1 == MIN_32)
{
L_var_out = MAX_32;
}
else
{
if (L_var1 < 0)
{
L_var_out = -L_var1;
}
else
{
L_var_out = L_var1;
}
}
return(L_var_out);
}
/************************************************************************
*
* Function Name : L_add
*
* Purpose :
*
* 32 bits addition of the two 32 bits variables (L_var1+L_var2) with
* overflow control and saturation; the result is set at +214783647 when
* overflow occurs or at -214783648 when underflow occurs.
*
* Complexity Weight : 2
*
* Inputs :
*
* L_var1
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= L_var1 <= 0x7fff ffff.
*
* L_var2
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= L_var2 <= 0x7fff ffff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* L_var_out
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
*
************************************************************************/
Word32 L_add(Word32 L_var1, Word32 L_var2)
{
Word32 L_var_out;
/*L_var_out = L_var1 + L_var2;
if (((L_var1 ^ L_var2) & MIN_32) == 0)
{
if ((L_var_out ^ L_var1) & MIN_32)
{
L_var_out = (L_var1 < 0) ? MIN_32 : MAX_32;
Overflow = 1;
}
}*/
asm("qadd %0,%1,%2":"=r"(L_var_out):"r"(L_var1),"r"(L_var2):"cc");
return(L_var_out);
}
/************************************************************************
*
* Function Name : L_deposit_h
*
* Purpose :
*
* Deposit the 16 bit var1 into the 16 MS bits of the 32 bit output. The
* 16 LS bits of the output are zeroed.
*
* Complexity Weight : 2
*
* Inputs :
*
* var1
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var1 <= 0x0000 7fff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* L_var_out
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= var_out <= 0x7fff 0000.
*
************************************************************************/
/*Word32 L_deposit_h(Word16 var1)
{
Word32 L_var_out;
L_var_out = (Word32) var1 << 16;
return(L_var_out);
}*/
/************************************************************************
*
* Function Name : L_deposit_l
*
* Purpose :
*
* Deposit the 16 bit var1 into the 16 LS bits of the 32 bit output. The
* 16 MS bits of the output are sign extended.
*
* Complexity Weight : 2
*
* Inputs :
*
* var1
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var1 <= 0x0000 7fff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* L_var_out
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0xFFFF 8000 <= L_var_out <= 0x0000 7fff.
*
************************************************************************/
/*Word32 L_deposit_l(Word16 var1)
{
Word32 L_var_out;
L_var_out = (Word32) var1;
return(L_var_out);
}*/
/************************************************************************
*
* Function Name : L_mac
*
* Purpose :
*
* Multiply var1 by var2 and shift the result left by 1. Add the 32 bit
* result to L_var3 with saturation, return a 32 bit result:
* L_mac(L_var3,var1,var2) = L_add(L_var3,(L_mult(var1,var2)).
*
* Complexity Weight : 1
*
* Inputs :
*
* L_var3
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
*
* var1
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var1 <= 0x0000 7fff.
*
* var2
* 16 bit short signed integer (Word16) whose value falls in the
* range : 0xffff 8000 <= var2 <= 0x0000 7fff.
*
* Outputs :
*
* none
*
* Returned Value :
*
* L_var_out
* 32 bit long signed integer (Word32) whose value falls in the
* range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -