⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fxpt.h

📁 手机加密通话软件
💻 H
📖 第 1 页 / 共 3 页
字号:
/* Copyright 2001,2002,2003 NAH6
 * All Rights Reserved
 *
 * Parts Copyright DoD, Parts Copyright Starium
 *
 */
/* -*-C-*-
*******************************************************************************
*
* RCS:          $Id: fxpt.h,v 1.10 2003/11/22 16:34:28 itsme Exp $
* Description:  fixed point primitives
*
* (C) Copyright 1999, Starium Ltd., all rights reserved.
*
*******************************************************************************
*/

#ifndef __FXPT_H__
#define __FXPT_H__

#include "hal_types.h"

#ifdef _USE_INLINED_FXPT

// !! this cannot be 'static' - otherwise duplicate symbols
#define INLINE static inline
#define FXPT_INCLUDE_HEADER 1
//#define FXPT_INCLUDE_PROTOTYPES 1
#define FXPT_INCLUDE_IMPLEMENTATION 1
#else
#ifdef FXPT_FROM_FXPT_C 
#define INLINE
#define FXPT_INCLUDE_HEADER 1
#define FXPT_INCLUDE_PROTOTYPES 1
#define FXPT_INCLUDE_IMPLEMENTATION 1
#else
#define INLINE
#define FXPT_INCLUDE_HEADER 1
#define FXPT_INCLUDE_PROTOTYPES 1
//#define FXPT_INCLUDE_IMPLEMENTATION 1
#endif
#endif /* _USE_INLINED_FXPT */

#ifdef FXPT_INCLUDE_HEADER

typedef int16   fxpt_16;
typedef uint16  fxpt_u16;

typedef int32   fxpt_32;
typedef uint32  fxpt_u32;

typedef int64   fxpt_64;
typedef uint64  fxpt_u64;


/*
 *  Some fxpt32 notes:
 *
 *  FX32_MIN in decimal is -2147483648
 *  FX32_MAX in decimal is +2147483647
 *  -FX32_MIN overflows
 *  -(FX32_MIN+1) in decimal is +214748364 (FX32_MAX)
 *  -FX32_MAX in decimal is -2147483648 (FX32_MIN)
 */
#define FX32_SIGN (fxpt_32) 0x80000000       /* sign bit for big type */
#define FX32_MIN  (fxpt_32) 0x80000000
#define FX32_MAX  (fxpt_32) 0x7fffffff

#define FX16_SIGN (fxpt_16) 0x8000           /* sign bit for small type */
#define FX16_MIN  (fxpt_16) 0x8000
#define FX16_MAX  (fxpt_16) 0x7fff

/* convert floating point constant in the range [-1..1) to a fxpt_16 */
#define FXPT_FLOAT_TO_Q15(float_const) ((fxpt_16) ((float_const) * (FX16_MAX + 1)))
#define FXPT_FLOAT_TO_Q12(float_const) ((fxpt_16) ((double)(float_const) * (1 << 12)))

typedef fxpt_32 sine_acc_t;     /* sine accumulator     */
typedef fxpt_32 sine_incr_t;    /* sine phase increment */

#define SINE_INCR(freq, sample_rate) \
        ((sine_incr_t) ((64.0*1024*(freq)*64)/(sample_rate)))

#define ROUND_SINE_ACC(acc) \
        ((acc) >> 6)

/*
 * These are needed to deactivate debugging code in main program.
 * Debugging cannot be used without a special version of the fxpt
 * library outfitted with overflow checking code (not for production
 * use).
 */
#define FXPT_ASSERT(x,y)
#define FXPT_SET_WARNERROR(x)
#define FXPT_SET_PUNTERROR(x)
#define FXPT_PUSHSTATE(x,y,z)
#define FXPT_POPSTATE()

#endif  /* FXPT_INCLUDE_HEADER */

#ifdef FXPT_INCLUDE_PROTOTYPES

INLINE fxpt_16 fxpt_abs16 (fxpt_16 var1);
INLINE fxpt_32 fxpt_abs32 (fxpt_32 L_var1);
INLINE fxpt_32 fxpt_add32 (fxpt_32 a, fxpt_32 b);
INLINE fxpt_32 fxpt_add32_fast (fxpt_32 a, fxpt_32 b);
INLINE fxpt_32 fxpt_sub32 (fxpt_32 a, fxpt_32 b);
INLINE fxpt_32 fxpt_mult32 (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_32 fxpt_mult32_fast (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_32 fxpt_mult64_fix (fxpt_32 var1, fxpt_32 var2, int fix);
INLINE fxpt_32 fxpt_mult64_round (fxpt_32 var1, fxpt_32 var2, int fix);
INLINE fxpt_32 fxpt_mac32 (fxpt_32 L_var3, fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_32 fxpt_shl32 (fxpt_32 L_var1, int var2);
INLINE fxpt_32 fxpt_shl32_fast (fxpt_32 L_var1, int var2);
INLINE fxpt_32 fxpt_shr32 (fxpt_32 L_var1, int var2);
INLINE fxpt_32 fxpt_shr32_fast (fxpt_32 L_var1, int var2);
INLINE fxpt_16 fxpt_shl16 (fxpt_16 var1, int var2);
INLINE fxpt_16 fxpt_shl16_fast(fxpt_16 var1, int var2);
INLINE fxpt_16 fxpt_shr16 (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_shr16_fast(fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_shr16_round(fxpt_16 var1, int var2);
INLINE fxpt_16 fxpt_extract_h (fxpt_32 L_var1);
INLINE fxpt_16 fxpt_extract_l (fxpt_32 L_var1);
INLINE fxpt_32 fxpt_negate32 (fxpt_32 L_var1);
INLINE fxpt_16 fxpt_negate16 (fxpt_16 var1);
INLINE fxpt_16 fxpt_round16 (fxpt_32 L_var1);
INLINE fxpt_16 fxpt_saturate16 (fxpt_32 L_var1);
INLINE fxpt_16 fxpt_saturate16_fix (fxpt_32 L_var1, int fix );
INLINE fxpt_16 fxpt_saturate16_round (fxpt_32 L_var1, int fix );
INLINE fxpt_32 fxpt_saturate32 (fxpt_64 LL_var1);
INLINE fxpt_32 fxpt_saturate32_round(fxpt_64 LL_var1, int fix);
INLINE fxpt_32 fxpt_deposit_h (fxpt_16 var1);
INLINE fxpt_32 fxpt_deposit_l (fxpt_16 var1);
INLINE fxpt_16 fxpt_mult_round16 (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_mult_round16_fast (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_mult16 (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_mult16_fast (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_mult16_fix (fxpt_16 var1, fxpt_16 var2, int fix);
INLINE fxpt_16 fxpt_mult16_fix_fast (fxpt_16 var1, fxpt_16 var2, int fix);
INLINE fxpt_16 fxpt_mult16_round (fxpt_16 var1, fxpt_16 var2, int fix);
INLINE fxpt_16 fxpt_square16 (fxpt_16 var1);
INLINE fxpt_16 fxpt_add16 (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_add16_fast (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_sub16 (fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_sub16_fast(fxpt_16 var1, fxpt_16 var2);
INLINE fxpt_16 fxpt_mult16_q15q11 (fxpt_16 a, fxpt_16 b);
INLINE fxpt_16 fxpt_div16 (fxpt_32 num, fxpt_32 den, int fr_bits);
INLINE fxpt_32 fxpt_sine32 (fxpt_32 x);
INLINE fxpt_16 fxpt_cos16 (fxpt_16 x);
INLINE fxpt_32 fxpt_cos32 (fxpt_32 x);
INLINE fxpt_32 fxpt_mult64_round_good (fxpt_32 var1, fxpt_32 var2, int fix);

#endif /* FXPT_INCLUDE_PROTOTYPES */

#ifdef FXPT_INCLUDE_IMPLEMENTATION

/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_abs16
 *
 *   PURPOSE:
 *
 *     Take the absolute value of the 16 bit input.  An input of
 *     -0x8000 results in a return value of 0x7fff.
 *
 *   INPUTS:
 *
 *     var1
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     swOut
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range
 *                     0x0000 0000 <= swOut <= 0x0000 7fff.
 *
 *   IMPLEMENTATION:
 *
 *     Take the absolute value of the 16 bit input.  An input of
 *     -0x8000 results in a return value of 0x7fff.
 *
 *   KEYWORDS: absolute value, abs
 *
 *************************************************************************/

INLINE fxpt_16
fxpt_abs16 (fxpt_16 var1)
{
  if (var1 < 0) {
    if (var1 == FX16_MIN)
      var1 = FX16_MAX;
    else
      var1 = -var1;
  }

  return var1;
}

/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_abs32
 *
 *   PURPOSE:
 *
 *     Take the absolute value of the 32 bit input.  An input of
 *     -0x8000 0000 results in a return value of 0x7fff ffff.
 *
 *   INPUTS:
 *
 *     L_var1
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     L_Out
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *
 *
 *
 *   KEYWORDS: absolute value, abs
 *
 *************************************************************************/

INLINE fxpt_32
fxpt_abs32 (fxpt_32 L_var1)
{
  if (L_var1 < 0) {
    if (L_var1 == FX32_MIN)
      L_var1 = FX32_MAX;
    else
      L_var1 = -L_var1;
  }

  return L_var1;
}


/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_add32
 *
 *   PURPOSE:
 *
 *     Perform the addition of the two 32 bit input variables with
 *     saturation.
 *
 *   INPUTS:
 *
 *     L_var1
 *                     32 bit long signed integer (Longword) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *     L_var2
 *                     32 bit long signed integer (Longword) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var2 <= 0x7fff ffff.
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     L_Out
 *                     32 bit long signed integer (Longword) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *
 *   IMPLEMENTATION:
 *
 *     Perform the addition of the two 32 bit input variables with
 *     saturation.
 *
 *     L_Out = L_var1 + L_var2
 *
 *     L_Out is set to 0x7fff ffff if the operation results in an
 *     overflow.  L_Out is set to 0x8000 0000 if the operation
 *     results in an underflow.
 *
 *   KEYWORDS: add, addition
 *
 *************************************************************************/

INLINE fxpt_32
fxpt_add32 (fxpt_32 a, fxpt_32 b)
{
  fxpt_32 sum;

  sum = a + b;

  if ((a ^ b) > 0  &&  (a ^ sum) < 0) {
    if (b > 0)
      sum = FX32_MAX;
    else
      sum = FX32_MIN;
  }

  return sum;
}

INLINE fxpt_32
fxpt_add32_fast (fxpt_32 a, fxpt_32 b)
{
  return a + b;
}


/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_sub32
 *
 *   PURPOSE:
 *
 *     Perform the subtraction of the two 32 bit input variables with
 *     saturation.
 *
 *   INPUTS:
 *
 *     L_var1
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *     L_var2
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var2 <= 0x7fff ffff.
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     L_Out
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *
 *   IMPLEMENTATION:
 *
 *     Perform the subtraction of the two 32 bit input variables with
 *     saturation.
 *
 *     L_Out = L_var1 - L_var2
 *
 *     L_Out is set to 0x7fff ffff if the operation results in an
 *     overflow.  L_Out is set to 0x8000 0000 if the operation
 *     results in an underflow.
 *
 *   KEYWORDS: sub, subtraction
 *
 *************************************************************************/

INLINE fxpt_32
fxpt_sub32 (fxpt_32 a, fxpt_32 b)
{
  fxpt_32 diff;

  diff = a - b;

  if ((a ^ b) < 0  &&  (a ^ diff) < 0) {
    if (b < 0)
      diff = FX32_MAX;
    else
      diff = FX32_MIN;
  }

  return diff;
}


/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_mult32
 *
 *   PURPOSE:
 *
 *     Perform a fractional multipy of the two 16 bit input numbers
 *     with saturation.  Output a 32 bit number.
 *
 *   INPUTS:
 *
 *     var1
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
 *     var2
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     L_Out
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *
 *   IMPLEMENTATION:
 *
 *     Multiply the two the two 16 bit input numbers. If the
 *     result is within this range, left shift the result by one
 *     and output the 32 bit number.  The only possible overflow
 *     occurs when var1==var2==-0x8000.  In this case output
 *     0x7fff ffff.
 *
 *   KEYWORDS: multiply, mult, mpy
 *
 *************************************************************************/

INLINE fxpt_32
fxpt_mult32 (fxpt_16 var1, fxpt_16 var2)
{
  fxpt_32 L_product;

  if (var1 == FX16_MIN && var2 == FX16_MIN)
    L_product = FX32_MAX;                 /* overflow */
  else
  {
    L_product = (fxpt_32) var1 * var2; /* integer multiply */
    L_product = L_product << 1;
  }
  return (L_product);

}


/*
 *  Same as above without overflow checking.
 */
INLINE fxpt_32
fxpt_mult32_fast (fxpt_16 var1, fxpt_16 var2)
{
  fxpt_32 L_product = (var1 * var2);
  L_product <<= 1;
  return L_product;
}


/*
 *  32*32 bit multiply with custom radix
 */
INLINE fxpt_32
fxpt_mult64_fix (fxpt_32 var1, fxpt_32 var2, int fix)
{
  fxpt_32 L_product;
  fxpt_64 LL_product;

  LL_product = ((fxpt_64) var1 * var2);

  if( fix==0 )
      return (fxpt_32)LL_product;

  if( fix>0 )
  {
      if (LL_product >= 0)
        L_product = (fxpt_32)(LL_product >> fix);
      else {
        L_product = (fxpt_32)((-LL_product) >> fix);
        L_product = -L_product;
      }
  }
  else
  {
      if (LL_product >= 0)
        L_product = ((fxpt_32)LL_product) << (-fix);
      else {
        L_product = ((fxpt_32)(-LL_product)) << (-fix);
        L_product = -L_product;
      }
  }

  return L_product;
}

/*
 *  32*32 bit multiply with rounding and custom radix
 */
INLINE fxpt_32
fxpt_mult64_round (fxpt_32 var1, fxpt_32 var2, int fix)
{
  int sign;
  fxpt_64 LL_product;
  fxpt_32 L_product;

  LL_product = ((fxpt_64) var1 * var2);

  if (fix == 0) {
    return (fxpt_32) LL_product;
  }

  /* Note sign */
  if (LL_product < 0) {
    sign = -1;
    LL_product = -LL_product;
  }
  else
    sign = 0;

  if( fix-1>0 )
      L_product = (fxpt_32) (LL_product >> (fix - 1));
  else
      L_product = (fxpt_32) (LL_product << (-fix + 1));
  /* Round */
  L_product++;
  L_product >>= 1;

  if (sign)
    return -L_product;
  else
    return L_product;
}

/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_mac32
 *
 *   PURPOSE:
 *
 *     Multiply accumulate.  Fractionally multiply two 16 bit
 *     numbers together with saturation.  Add that result to the
 *     32 bit input with saturation.  Return the 32 bit result.
 *
 *   INPUTS:
 *
 *     var1
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range 0xffff 8000 <= var1 <= 0x0000 7fff.
 *     var2
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
 *     L_var3
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var2 <= 0x7fff ffff.
 *
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:
 *
 *     L_Out
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *
 *   IMPLEMENTATION:
 *
 *     Fractionally multiply two 16 bit numbers together with
 *     saturation.  The only numbers which will cause saturation on
 *     the multiply are 0x8000 * 0x8000.
 *
 *     Add that result to the 32 bit input with saturation.
 *     Return the 32 bit result.
 *
 *     Please note that this is not a true multiply accumulate as
 *     most processors would implement it.  The 0x8000*0x8000
 *     causes and overflow for this instruction.  On most
 *     processors this would cause an overflow only if the 32 bit
 *     input added to it were positive or zero.
 *
 *   KEYWORDS: mac, multiply accumulate
 *
 *************************************************************************/
INLINE fxpt_32
fxpt_mac32 (fxpt_32 L_var3, fxpt_16 var1, fxpt_16 var2)
{
  return (fxpt_add32 (L_var3, fxpt_mult32 (var1, var2)));
}


/***************************************************************************
 *
 *   FUNCTION NAME: fxpt_shl32
 *
 *   PURPOSE:
 *
 *     Arithmetic shift left (or right).
 *     Arithmetically shift the input left by var2.   If var2 is
 *     negative then an arithmetic shift right (fxpt_shr32) of L_var1 by
 *     -var2 is performed.
 *
 *   INPUTS:
 *
 *     var2
 *                     16 bit short signed integer (fxpt_16) whose value
 *                     falls in the range 0xffff 8000 <= var2 <= 0x0000 7fff.
 *     L_var1
 *                     32 bit long signed integer (fxpt_32) whose value
 *                     falls in the range
 *                     0x8000 0000 <= L_var1 <= 0x7fff ffff.
 *   OUTPUTS:
 *
 *     none
 *
 *   RETURN VALUE:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -