Blame libcelt/fixed_generic.h

Packit 664db3
/* Copyright (C) 2003-2008 Jean-Marc Valin, CSIRO */
Packit 664db3
/**
Packit 664db3
   @file fixed_generic.h
Packit 664db3
   @brief Generic fixed-point operations
Packit 664db3
*/
Packit 664db3
/*
Packit 664db3
   Redistribution and use in source and binary forms, with or without
Packit 664db3
   modification, are permitted provided that the following conditions
Packit 664db3
   are met:
Packit 664db3
   
Packit 664db3
   - Redistributions of source code must retain the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer.
Packit 664db3
   
Packit 664db3
   - Redistributions in binary form must reproduce the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer in the
Packit 664db3
   documentation and/or other materials provided with the distribution.
Packit 664db3
   
Packit 664db3
   - Neither the name of the Xiph.org Foundation nor the names of its
Packit 664db3
   contributors may be used to endorse or promote products derived from
Packit 664db3
   this software without specific prior written permission.
Packit 664db3
   
Packit 664db3
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 664db3
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 664db3
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 664db3
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
Packit 664db3
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit 664db3
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit 664db3
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 664db3
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 664db3
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 664db3
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit 664db3
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 664db3
*/
Packit 664db3
Packit 664db3
#ifndef FIXED_GENERIC_H
Packit 664db3
#define FIXED_GENERIC_H
Packit 664db3
Packit 664db3
/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */
Packit 664db3
#define MULT16_16SU(a,b) ((celt_word32_t)(celt_word16_t)(a)*(celt_word32_t)(celt_uint16_t)(b))
Packit 664db3
Packit 664db3
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
Packit 664db3
Packit 664db3
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
Packit 664db3
Packit 664db3
/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
Packit 664db3
Packit 664db3
/** 32x32 multiplication, followed by a 32-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT32_32_Q32(a,b) ADD32(ADD32(MULT16_16(SHR((a),16),SHR((b),16)), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),16)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),16))
Packit 664db3
Packit 664db3
/** Compile-time conversion of float constant to 16-bit value */
Packit 664db3
#define QCONST16(x,bits) ((celt_word16_t)(.5+(x)*(((celt_word32_t)1)<<(bits))))
Packit 664db3
/** Compile-time conversion of float constant to 32-bit value */
Packit 664db3
#define QCONST32(x,bits) ((celt_word32_t)(.5+(x)*(((celt_word32_t)1)<<(bits))))
Packit 664db3
Packit 664db3
/** Negate a 16-bit value */
Packit 664db3
#define NEG16(x) (-(x))
Packit 664db3
/** Negate a 32-bit value */
Packit 664db3
#define NEG32(x) (-(x))
Packit 664db3
Packit 664db3
/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */
Packit 664db3
#define EXTRACT16(x) ((celt_word16_t)(x))
Packit 664db3
/** Change a 16-bit value into a 32-bit value */
Packit 664db3
#define EXTEND32(x) ((celt_word32_t)(x))
Packit 664db3
Packit 664db3
/** Arithmetic shift-right of a 16-bit value */
Packit 664db3
#define SHR16(a,shift) ((a) >> (shift))
Packit 664db3
/** Arithmetic shift-left of a 16-bit value */
Packit 664db3
#define SHL16(a,shift) ((a) << (shift))
Packit 664db3
/** Arithmetic shift-right of a 32-bit value */
Packit 664db3
#define SHR32(a,shift) ((a) >> (shift))
Packit 664db3
/** Arithmetic shift-left of a 32-bit value */
Packit 664db3
#define SHL32(a,shift) ((celt_word32_t)(a) << (shift))
Packit 664db3
Packit 664db3
/** 16-bit arithmetic shift right with rounding-to-nearest instead of rounding down */
Packit 664db3
#define PSHR16(a,shift) (SHR16((a)+((1<<((shift))>>1)),shift))
Packit 664db3
/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */
Packit 664db3
#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift))
Packit 664db3
/** 32-bit arithmetic shift right where the argument can be negative */
Packit 664db3
#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
Packit 664db3
Packit 664db3
/** Saturates 16-bit value to +/- a */
Packit 664db3
#define SATURATE16(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
Packit 664db3
/** Saturates 32-bit value to +/- a */
Packit 664db3
#define SATURATE32(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
Packit 664db3
Packit 664db3
/** "RAW" macros, should not be used outside of this header file */
Packit 664db3
#define SHR(a,shift) ((a) >> (shift))
Packit 664db3
#define SHL(a,shift) ((celt_word32_t)(a) << (shift))
Packit 664db3
#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift))
Packit 664db3
#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x)))
Packit 664db3
Packit 664db3
/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */
Packit 664db3
#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a))))
Packit 664db3
/** Divide by two */
Packit 664db3
#define HALF32(x)  (SHR32(x,1))
Packit 664db3
Packit 664db3
/** Add two 16-bit values */
Packit 664db3
#define ADD16(a,b) ((celt_word16_t)((celt_word16_t)(a)+(celt_word16_t)(b)))
Packit 664db3
/** Subtract two 16-bit values */
Packit 664db3
#define SUB16(a,b) ((celt_word16_t)(a)-(celt_word16_t)(b))
Packit 664db3
/** Add two 32-bit values */
Packit 664db3
#define ADD32(a,b) ((celt_word32_t)(a)+(celt_word32_t)(b))
Packit 664db3
/** Subtract two 32-bit values */
Packit 664db3
#define SUB32(a,b) ((celt_word32_t)(a)-(celt_word32_t)(b))
Packit 664db3
Packit 664db3
Packit 664db3
/** 16x16 multiplication where the result fits in 16 bits */
Packit 664db3
#define MULT16_16_16(a,b)     ((((celt_word16_t)(a))*((celt_word16_t)(b))))
Packit 664db3
Packit 664db3
/* (celt_word32_t)(celt_word16_t) gives TI compiler a hint that it's 16x16->32 multiply */
Packit 664db3
/** 16x16 multiplication where the result fits in 32 bits */
Packit 664db3
#define MULT16_16(a,b)     (((celt_word32_t)(celt_word16_t)(a))*((celt_word32_t)(celt_word16_t)(b)))
Packit 664db3
Packit 664db3
/** 16x16 multiply-add where the result fits in 32 bits */
Packit 664db3
#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b))))
Packit 664db3
/** 16x32 multiplication, followed by a 12-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT16_32_Q12(a,b) ADD32(MULT16_16((a),SHR((b),12)), SHR(MULT16_16((a),((b)&0x00000fff)),12))
Packit 664db3
/** 16x32 multiplication, followed by a 13-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT16_32_Q13(a,b) ADD32(MULT16_16((a),SHR((b),13)), SHR(MULT16_16((a),((b)&0x00001fff)),13))
Packit 664db3
/** 16x32 multiplication, followed by a 14-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT16_32_Q14(a,b) ADD32(MULT16_16((a),SHR((b),14)), SHR(MULT16_16((a),((b)&0x00003fff)),14))
Packit 664db3
Packit 664db3
/** 16x32 multiplication, followed by an 11-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MULT16_32_Q11(a,b) ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11))
Packit 664db3
/** 16x32 multiply-add, followed by an 11-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MAC16_32_Q11(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),11)), SHR(MULT16_16((a),((b)&0x000007ff)),11)))
Packit 664db3
Packit 664db3
/** 16x32 multiplication, followed by a 15-bit shift right (round-to-nearest). Results fits in 32 bits */
Packit 664db3
#define MULT16_32_P15(a,b) ADD32(MULT16_16((a),SHR((b),15)), PSHR(MULT16_16((a),((b)&0x00007fff)),15))
Packit 664db3
/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */
Packit 664db3
#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15)))
Packit 664db3
Packit 664db3
Packit 664db3
#define MAC16_16_Q11(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),11)))
Packit 664db3
#define MAC16_16_Q13(c,a,b)     (ADD32((c),SHR(MULT16_16((a),(b)),13)))
Packit 664db3
#define MAC16_16_P13(c,a,b)     (ADD32((c),SHR(ADD32(4096,MULT16_16((a),(b))),13)))
Packit 664db3
Packit 664db3
#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11))
Packit 664db3
#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13))
Packit 664db3
#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14))
Packit 664db3
#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15))
Packit 664db3
Packit 664db3
#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13))
Packit 664db3
#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14))
Packit 664db3
#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15))
Packit 664db3
Packit 664db3
/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */
Packit 664db3
#define DIV32_16(a,b) ((celt_word16_t)(((celt_word32_t)(a))/((celt_word16_t)(b))))
Packit 664db3
/** Divide a 32-bit value by a 16-bit value and round to nearest. Result fits in 16 bits */
Packit 664db3
#define PDIV32_16(a,b) ((celt_word16_t)(((celt_word32_t)(a)+((celt_word16_t)(b)>>1))/((celt_word16_t)(b))))
Packit 664db3
/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */
Packit 664db3
#define DIV32(a,b) (((celt_word32_t)(a))/((celt_word32_t)(b)))
Packit 664db3
/** Divide a 32-bit value by a 32-bit value and round to nearest. Result fits in 32 bits */
Packit 664db3
#define PDIV32(a,b) (((celt_word32_t)(a)+((celt_word16_t)(b)>>1))/((celt_word32_t)(b)))
Packit 664db3
Packit 664db3
#endif