diff options
author | Dave Burke <daveburke@google.com> | 2012-04-17 09:51:45 -0700 |
---|---|---|
committer | Dave Burke <daveburke@google.com> | 2012-04-17 23:04:43 -0700 |
commit | 9bf37cc9712506b2483650c82d3c41152337ef7e (patch) | |
tree | 77db44e2bae06e3d144b255628be2b7a55c581d3 /libFDK/include | |
parent | a37315fe10ee143d6d0b28c19d41a476a23e63ea (diff) | |
download | fdk-aac-dabplus-9bf37cc9712506b2483650c82d3c41152337ef7e.tar.gz fdk-aac-dabplus-9bf37cc9712506b2483650c82d3c41152337ef7e.tar.bz2 fdk-aac-dabplus-9bf37cc9712506b2483650c82d3c41152337ef7e.zip |
Fraunhofer AAC codec.
License boilerplate update to follow.
Change-Id: I2810460c11a58b6d148d84673cc031f3685e79b5
Diffstat (limited to 'libFDK/include')
38 files changed, 5258 insertions, 0 deletions
diff --git a/libFDK/include/FDK_archdef.h b/libFDK/include/FDK_archdef.h new file mode 100644 index 0000000..eecc990 --- /dev/null +++ b/libFDK/include/FDK_archdef.h @@ -0,0 +1,184 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __ARCH_H__ +#define __ARCH_H__ + +/* Performance / Quality profile selector */ + #define FDK_HIGH_PERFORMANCE + +/* Unify some few toolchain specific defines to avoid having large "or" macro contraptions all over the source code. */ + +/* Take action against VisualStudio 2005 crosscompile problems. */ + +/* Use single macro (the GCC built in macro) for architecture identification independent of the particular toolchain */ +#if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || (defined(_MSC_VER) && defined(_M_IX86)) || defined (__x86_64__) +#define __x86__ +#endif + +#if (defined(_M_ARM) || defined(__CC_ARM)) && !defined(__arm__) || defined(__TI_TMS470_V5__) && !defined(__arm__) +#define __arm__ +#endif + + + +/* Define __ARM_ARCH_5TE__ if armv5te features are supported */ +#if (__TARGET_ARCH_ARM == 5) || defined(__TARGET_FEATURE_DSPMUL) || (_M_ARM == 5) || defined(__ARM_ARCH_5TEJ__) || defined(__TI_TMS470_V5__) || defined(__ARM_ARCH_7EM__) +#define __ARM_ARCH_5TE__ +#endif + +/* Define __ARM_ARCH_6__ if the armv6 intructions are being supported. */ +#if (__TARGET_ARCH_ARM == 6) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6ZK__) +#define __ARM_ARCH_5TE__ +#define __ARM_ARCH_6__ +#endif + +/* Define __ARM_ARCH_7_A__ if the armv7 intructions are being supported. */ +#if defined(__TARGET_ARCH_7_R) || defined(__ARM_ARCH_7R__) +#define __ARM_ARCH_5TE__ +#define __ARM_ARCH_6__ +#define __ARM_ARCH_7_R__ +#endif + +/* Define __ARM_ARCH_7_A__ if the armv7 intructions are being supported. */ +#if defined(__TARGET_ARCH_7_A) || defined(__ARM_ARCH_7A__) +#define __ARM_ARCH_5TE__ +#define __ARM_ARCH_6__ +#define __ARM_ARCH_7_A__ +#endif + +/* Define __ARM_ARCH_7M__ if the ARMv7-M instructions are being supported, e.g. Cortex-M3. */ +#if defined(__TARGET_ARCH_7_M) || defined(__ARM_ARCH_7_M__) +#define __ARM_ARCH_7M__ +#endif + +/* Define __ARM_ARCH_7EM__ if the ARMv7-ME instructions are being supported, e.g. Cortex-M4. */ +#if defined(__TARGET_ARCH_7E_M) || defined(__ARM_ARCH_7E_M__) +#define __ARM_ARCH_7EM__ +#endif + +/* Detect and unify macros for neon feature. */ +#if defined(__TARGET_FEATURE_NEON) && !defined(__ARM_NEON__) +#define __ARM_NEON__ +#endif + +#ifdef _M_ARM +#include "cmnintrin.h" +#include "armintr.h" +#endif + + + +/* Define preferred Multiplication type */ +#if defined(FDK_HIGH_PERFORMANCE) && !defined(FDK_HIGH_QUALITY) /* FDK_HIGH_PERFORMANCE */ + +#if defined(__mips__) || defined(__powerpc__) || defined(__sh__) +#define ARCH_PREFER_MULT_16x16 +#undef SINETABLE_16BIT +#undef POW2COEFF_16BIT +#undef LDCOEFF_16BIT +#undef WINDOWTABLE_16BIT + +#elif defined(__arm__) && defined(__ARM_ARCH_5TE__) /* cppp replaced: elif */ /* cppp replaced: elif */ +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__arm__) && defined(__ARM_ARCH_7M__) +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__arm__) && defined(__ARM_ARCH_7EM__) +#define ARCH_PREFER_MULT_32x32 +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT +#define WINDOWTABLE_16BIT + +#elif defined(__arm__) && !defined(__ARM_ARCH_5TE__) +#define ARCH_PREFER_MULT_16x16 +#undef SINETABLE_16BIT +#undef WINDOWTABLE_16BIT +#undef POW2COEFF_16BIT +#undef LDCOEFF_16BIT + +#elif defined(__x86__) /* cppp replaced: elif */ +#define ARCH_PREFER_MULT_32x16 +#define SINETABLE_16BIT +#define WINDOWTABLE_16BIT +#define POW2COEFF_16BIT +#define LDCOEFF_16BIT + +#else + + #error >>>> Please set architecture characterization defines for your platform (FDK_HIGH_PERFORMANCE)! <<<< + +#endif /* Architecture switches */ + +#else /* neither FDK_HIGH_QUALITY or FDK_HIGH_PERFORMANCE */ + +#error Either set FDK_HIGH_QUALITY or FDK_HIGH_PERFORMANCE, but not both nor none of them. + +#endif /* End of quality/complexity tradeoff */ + +#define FDKTOOLS_PACKED_TABLES + + +#ifdef SINETABLE_16BIT + #define FIXP_STB FIXP_SGL /* STB sinus Tab used in transformation */ + #define FIXP_STP FIXP_SPK + #define STC(a) (FX_DBL2FXCONST_SGL(a)) +#else + #define FIXP_STB FIXP_DBL + #define FIXP_STP FIXP_DPK + #define STC(a) ((FIXP_DBL)(LONG)(a)) +#endif /* defined(SINETABLE_16BIT) */ + +#define STCP(cos,sin) { { STC(cos), STC(sin) } } + + +#ifdef WINDOWTABLE_16BIT + #define FIXP_WTB FIXP_SGL /* single FIXP_SGL values */ + #define FIXP_WTP FIXP_SPK /* packed FIXP_SGL values */ + #define WTC(a) FX_DBL2FXCONST_SGL(a) +#else /* SINETABLE_16BIT */ + #define FIXP_WTB FIXP_DBL + #define FIXP_WTP FIXP_DPK + #define WTC(a) (FIXP_DBL)(a) +#endif /* SINETABLE_16BIT */ + +#define WTCP(a,b) { { WTC(a), WTC(b) } } + + +#endif /* __ARCH_H__ */ diff --git a/libFDK/include/FDK_bitbuffer.h b/libFDK/include/FDK_bitbuffer.h new file mode 100644 index 0000000..3b6afd7 --- /dev/null +++ b/libFDK/include/FDK_bitbuffer.h @@ -0,0 +1,104 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2005) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser + Description: common bitbuffer read/write routines + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __FDK_BITBUFFER_H__ +#define __FDK_BITBUFFER_H__ + + + +#include "machine_type.h" + +typedef struct +{ + UINT ValidBits; + UINT ReadOffset; + UINT WriteOffset; + UINT BitCnt; + UINT BitNdx; + + UCHAR *Buffer; + UINT bufSize; + UINT bufBits; +} FDK_BITBUF; + +typedef FDK_BITBUF *HANDLE_FDK_BITBUF; + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern const UINT BitMask [32+1]; + +/** The BitBuffer Functions are called straight from FDK_bitstream Interface. + For Functions functional survey look there. +*/ + +void FDK_CreateBitBuffer (HANDLE_FDK_BITBUF *hBitBuffer, UCHAR *pBuffer, UINT bufSize) ; + +void FDK_InitBitBuffer (HANDLE_FDK_BITBUF hBitBuffer, UCHAR *pBuffer, + UINT bufSize, UINT validBits) ; + +void FDK_ResetBitBuffer (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_DeleteBitBuffer (HANDLE_FDK_BITBUF hBitBuffer) ; + +INT FDK_get (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits) ; + +INT FDK_get32 (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_put (HANDLE_FDK_BITBUF hBitBuffer, UINT value, const UINT numberOfBits) ; + +INT FDK_getBwd (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits); +void FDK_putBwd (HANDLE_FDK_BITBUF hBitBuffer, UINT value, const UINT numberOfBits) ; + +void FDK_pushBack (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits, UCHAR config) ; +void FDK_pushForward (HANDLE_FDK_BITBUF hBitBuffer, const UINT numberOfBits, UCHAR config) ; + +void FDK_byteAlign (HANDLE_FDK_BITBUF hBitBuffer, UCHAR config) ; + +UINT FDK_getValidBits (HANDLE_FDK_BITBUF hBitBuffer) ; +INT FDK_getFreeBits (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_setBitCnt (HANDLE_FDK_BITBUF hBitBuffer, const UINT value) ; +INT FDK_getBitCnt (HANDLE_FDK_BITBUF hBitBuffer) ; + +void FDK_Feed (HANDLE_FDK_BITBUF hBitBuffer, UCHAR inputBuffer [], + const UINT bufferSize, UINT *bytesValid) ; + +void FDK_Copy (HANDLE_FDK_BITBUF hBitBufDst, HANDLE_FDK_BITBUF hBitBufSrc, UINT *bytesValid) ; + +void FDK_Fetch (HANDLE_FDK_BITBUF hBitBuffer, UCHAR outBuf[], UINT *writeBytes); + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/libFDK/include/FDK_bitstream.h b/libFDK/include/FDK_bitstream.h new file mode 100644 index 0000000..81c4e93 --- /dev/null +++ b/libFDK/include/FDK_bitstream.h @@ -0,0 +1,556 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2009) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser + Description: bitstream interface to bitbuffer routines + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __FDK_BITSTREAM_H__ +#define __FDK_BITSTREAM_H__ + + + +#include "FDK_bitbuffer.h" +#include "machine_type.h" + +#include "genericStds.h" + +#define CACHE_BITS 32 + +typedef enum { + BS_READER, + BS_WRITER +} FDK_BS_CFG; + + +typedef struct +{ + UINT CacheWord ; + UINT BitsInCache ; + FDK_BITBUF hBitBuf; + UINT ConfigCache ; +} FDK_BITSTREAM; + +typedef FDK_BITSTREAM* HANDLE_FDK_BITSTREAM; + +/** + * \brief CreateBitStream Function. + * + * Create and initialize bitstream with extern allocated buffer. + * + * \param pBuffer Pointer to BitBuffer array. + * \param bufSize Length of BitBuffer array. (awaits size 2^n) + * \param config Initialize BitStream as Reader or Writer. + */ +FDK_INLINE +HANDLE_FDK_BITSTREAM FDKcreateBitStream (UCHAR *pBuffer, + UINT bufSize, + FDK_BS_CFG config = BS_READER) +{ + HANDLE_FDK_BITSTREAM hBitStream = (HANDLE_FDK_BITSTREAM) FDKcalloc(1, sizeof(FDK_BITSTREAM)); + FDK_InitBitBuffer(&hBitStream->hBitBuf, pBuffer, bufSize, 0) ; + + /* init cache */ + hBitStream->CacheWord = hBitStream->BitsInCache = 0 ; + hBitStream->ConfigCache = config ; + + return hBitStream ; +} + + +/** + * \brief Initialize BistreamBuffer. BitBuffer can point to filled BitBuffer array . + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param pBuffer Pointer to BitBuffer array. + * \param bufSize Length of BitBuffer array. (awaits size 2^n) + * \param validBits Number of valid BitBuffer filled Bits. + * \param config Initialize BitStream as Reader or Writer. + * \return void + */ +FDK_INLINE +void FDKinitBitStream (HANDLE_FDK_BITSTREAM hBitStream, + UCHAR *pBuffer, + UINT bufSize, + UINT validBits, + FDK_BS_CFG config = BS_READER) +{ + FDK_InitBitBuffer(&hBitStream->hBitBuf, pBuffer, bufSize, validBits) ; + + /* init cache */ + hBitStream->CacheWord = hBitStream->BitsInCache = 0 ; + hBitStream->ConfigCache = config ; +} + + +/** + * \brief ResetBitbuffer Function. Reset states in BitBuffer and Cache. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param config Initialize BitStream as Reader or Writer. + * \return void + */ +FDK_INLINE void FDKresetBitbuffer( HANDLE_FDK_BITSTREAM hBitStream, FDK_BS_CFG config = BS_READER) +{ + FDK_ResetBitBuffer( &hBitStream->hBitBuf ) ; + + /* init cache */ + hBitStream->CacheWord = hBitStream->BitsInCache = 0 ; + hBitStream->ConfigCache = config ; +} + + +/** DeleteBitStream. + + Deletes the in Create Bitstream allocated BitStream and BitBuffer. +*/ +FDK_INLINE void FDKdeleteBitStream (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDK_DeleteBitBuffer(&hBitStream->hBitBuf) ; + FDKfree(hBitStream) ; +} + + +/** + * \brief ReadBits Function (forward). This function returns a number of sequential + * bits from the input bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numberOfBits The number of bits to be retrieved. + * \return the requested bits, right aligned + * \return + */ +#define OPTIMIZE_FDKREADBITS + +FDK_INLINE UINT FDKreadBits(HANDLE_FDK_BITSTREAM hBitStream, + const UINT numberOfBits) +{ +#ifdef noOPTIMIZE_FDKREADBITS + INT missingBits = numberOfBits - hBitStream->BitsInCache; + if (missingBits > 0) + { + UINT bits = hBitStream->CacheWord << missingBits; + hBitStream->CacheWord = FDK_get32 (&hBitStream->hBitBuf) ; + hBitStream->BitsInCache = CACHE_BITS - missingBits; + return ( bits | (hBitStream->CacheWord >> hBitStream->BitsInCache)) & BitMask[numberOfBits]; + } + + hBitStream->BitsInCache -= numberOfBits; + return ( hBitStream->CacheWord >> hBitStream->BitsInCache) & BitMask[numberOfBits]; + +#else + const UINT validMask = BitMask [numberOfBits] ; + + if (hBitStream->BitsInCache <= numberOfBits) + { + const INT freeBits = (CACHE_BITS-1) - hBitStream->BitsInCache ; + + hBitStream->CacheWord = (hBitStream->CacheWord << freeBits) | FDK_get (&hBitStream->hBitBuf,freeBits) ; + hBitStream->BitsInCache += freeBits ; + } + + hBitStream->BitsInCache -= numberOfBits ; + + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & validMask ; +#endif +} + +FDK_INLINE UINT FDKreadBit(HANDLE_FDK_BITSTREAM hBitStream) +{ +#ifdef OPTIMIZE_FDKREADBITS + if (!hBitStream->BitsInCache) + { + hBitStream->CacheWord = FDK_get32 (&hBitStream->hBitBuf); + hBitStream->BitsInCache = CACHE_BITS; + } + hBitStream->BitsInCache--; + + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & 1; +#else + return FDKreadBits(hBitStream,1); +#endif +} + +/** + * \brief Read2Bits Function (forward). This function 2 sequential + * bits from the input bitstream. It is the optimized version + of FDKreadBits() for readign 2 bits. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return the requested bits, right aligned + * \return + */ +inline UINT FDKread2Bits(HANDLE_FDK_BITSTREAM hBitStream) +{ + UINT BitsInCache = hBitStream->BitsInCache; + if (BitsInCache < 2) /* Comparison changed from 'less-equal' to 'less' */ + { + const INT freeBits = (CACHE_BITS-1) - BitsInCache ; + + hBitStream->CacheWord = (hBitStream->CacheWord << freeBits) | FDK_get (&hBitStream->hBitBuf,freeBits) ; + BitsInCache += freeBits; + } + hBitStream->BitsInCache = BitsInCache - 2; + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & 0x3; +} + +/** + * \brief ReadBits Function (backward). This function returns a number of sequential bits + * from the input bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numberOfBits The number of bits to be retrieved. + * \return the requested bits, right aligned + */ +FDK_INLINE UINT FDKreadBitsBwd(HANDLE_FDK_BITSTREAM hBitStream, + const UINT numberOfBits) +{ + const UINT validMask = BitMask [numberOfBits] ; + + if (hBitStream->BitsInCache <= numberOfBits) + { + const INT freeBits = (CACHE_BITS-1) - hBitStream->BitsInCache ; + + hBitStream->CacheWord = (hBitStream->CacheWord << freeBits) | FDK_getBwd (&hBitStream->hBitBuf,freeBits) ; + hBitStream->BitsInCache += freeBits ; + } + + hBitStream->BitsInCache -= numberOfBits ; + + return (hBitStream->CacheWord >> hBitStream->BitsInCache) & validMask ; +} + + +/** + * \brief return a number of bits from the bitBuffer. + * You have to know what you do! Cache has to be synchronized before using this + * function. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numBits The number of bits to be retrieved. + * \return the requested bits, right aligned + */ +FDK_INLINE UINT FDKgetBits (HANDLE_FDK_BITSTREAM hBitStream, UINT numBits) +{ + return FDK_get (&hBitStream->hBitBuf, numBits) ; +} + + +/** + * \brief WriteBits Function. This function writes numberOfBits of value into bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param value Variable holds data to be written. + * \param numberOfBits The number of bits to be written. + * \return number of bits written + */ +FDK_INLINE UCHAR FDKwriteBits(HANDLE_FDK_BITSTREAM hBitStream, UINT value, + const UINT numberOfBits) +{ + const UINT validMask = BitMask [numberOfBits] ; + + if ((hBitStream->BitsInCache+numberOfBits) < CACHE_BITS) + { + hBitStream->BitsInCache += numberOfBits ; + hBitStream->CacheWord = (hBitStream->CacheWord << numberOfBits) | (value & validMask); + } + else + { + FDK_put(&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + hBitStream->BitsInCache = numberOfBits ; + hBitStream->CacheWord = (value & validMask) ; + } + + return numberOfBits; +} + + +/** + * \brief WriteBits Function (backward). This function writes numberOfBits of value into bitstream. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param value Variable holds data to be written. + * \param numberOfBits The number of bits to be written. + * \return number of bits written + */ +FDK_INLINE UCHAR FDKwriteBitsBwd(HANDLE_FDK_BITSTREAM hBitStream, UINT value, + const UINT numberOfBits) +{ + const UINT validMask = BitMask [numberOfBits] ; + + if ((hBitStream->BitsInCache+numberOfBits) <= CACHE_BITS) + { + hBitStream->BitsInCache += numberOfBits ; + hBitStream->CacheWord = (hBitStream->CacheWord << numberOfBits) | (value & validMask); + } + else + { + FDK_putBwd(&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + hBitStream->BitsInCache = numberOfBits ; + hBitStream->CacheWord = (value & validMask) ; + } + + return numberOfBits; +} + + +/** + * \brief SyncCache Function. Clear cache after read forward. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKsyncCache (HANDLE_FDK_BITSTREAM hBitStream) +{ + if (hBitStream->ConfigCache == BS_READER) + FDK_pushBack (&hBitStream->hBitBuf,hBitStream->BitsInCache,hBitStream->ConfigCache) ; + else /* BS_WRITER */ + FDK_put(&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + + hBitStream->BitsInCache = 0 ; + hBitStream->CacheWord = 0 ; +} + + +/** + * \brief SyncCache Function. Clear cache after read backwards. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKsyncCacheBwd (HANDLE_FDK_BITSTREAM hBitStream) +{ + if (hBitStream->ConfigCache == BS_READER) { + FDK_pushForward (&hBitStream->hBitBuf,hBitStream->BitsInCache,hBitStream->ConfigCache) ; + } else { /* BS_WRITER */ + FDK_putBwd (&hBitStream->hBitBuf, hBitStream->CacheWord, hBitStream->BitsInCache) ; + } + + hBitStream->BitsInCache = 0 ; + hBitStream->CacheWord = 0 ; +} + + +/** + * \brief Byte Alignment Function. + * This function performs the byte_alignment() syntactic function on the input stream, + * i.e. some bits will be discarded/padded so that the next bits to be read/written will + * be aligned on a byte boundary with respect to the bit position 0. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKbyteAlign (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache (hBitStream) ; + FDK_byteAlign (&hBitStream->hBitBuf, (UCHAR)hBitStream->ConfigCache) ; +} + + +/** + * \brief Byte Alignment Function with anchor + * This function performs the byte_alignment() syntactic function on the input stream, + * i.e. some bits will be discarded so that the next bits to be read/written would be aligned + * on a byte boundary with respect to the given alignment anchor. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param alignmentAnchor bit position to be considered as origin for byte alignment + * \return void + */ +FDK_INLINE void FDKbyteAlign (HANDLE_FDK_BITSTREAM hBitStream, UINT alignmentAnchor) +{ + FDKsyncCache (hBitStream) ; + if (hBitStream->ConfigCache == BS_READER) { + FDK_pushForward (&hBitStream->hBitBuf, + (8 - ((alignmentAnchor - FDK_getValidBits(&hBitStream->hBitBuf)) & 0x07)) & 0x07, + hBitStream->ConfigCache) ; + } + else { + FDK_put (&hBitStream->hBitBuf, + 0, + (8 - ((FDK_getValidBits(&hBitStream->hBitBuf)-alignmentAnchor) & 0x07)) & 0x07 ); + } +} + + +/** + * \brief Push Back(Cache) / For / BiDirectional Function. + * PushBackCache function ungets a number of bits erroneously read/written by the last Get() call. + * NB: The number of bits to be stuffed back into the stream may never exceed the + * number of bits returned by the immediately preceding Get() call. + * + * PushBack function ungets a number of bits (combines cache and bitbuffer indices) + * PushFor function gets a number of bits (combines cache and bitbuffer indices) + * PushBiDirectional gets/ungets number of bits as defined in PusBack/For function + * NB: The sign of bits is not known, so the function checks direction and calls + * appropriate function. (positive sign pushFor, negative sign pushBack ) + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param numberOfBits The number of bits to be pushed back/for. + * \return void + */ +FDK_INLINE void FDKpushBackCache (HANDLE_FDK_BITSTREAM hBitStream, const UINT numberOfBits) +{ + FDK_ASSERT ((hBitStream->BitsInCache+numberOfBits)<=CACHE_BITS); + hBitStream->BitsInCache += numberOfBits ; +} + +FDK_INLINE void FDKpushBack (HANDLE_FDK_BITSTREAM hBitStream, const UINT numberOfBits) +{ + if ((hBitStream->BitsInCache+numberOfBits)<CACHE_BITS && (hBitStream->ConfigCache == BS_READER) ) { + hBitStream->BitsInCache += numberOfBits ; + FDKsyncCache(hBitStream) ; /* sync cache to avoid invalid cache */ + } + else { + FDKsyncCache(hBitStream) ; + FDK_pushBack(&hBitStream->hBitBuf,numberOfBits,hBitStream->ConfigCache); + } +} + +FDK_INLINE void FDKpushFor (HANDLE_FDK_BITSTREAM hBitStream, const UINT numberOfBits) +{ + if ( (hBitStream->BitsInCache>numberOfBits) && (hBitStream->ConfigCache == BS_READER) ) { + hBitStream->BitsInCache -= numberOfBits; + } + else { + FDKsyncCache(hBitStream) ; + FDK_pushForward(&hBitStream->hBitBuf,numberOfBits,hBitStream->ConfigCache); + } +} + +FDK_INLINE void FDKpushBiDirectional (HANDLE_FDK_BITSTREAM hBitStream, const INT numberOfBits) +{ + if(numberOfBits>=0) FDKpushFor(hBitStream, numberOfBits) ; + else FDKpushBack(hBitStream, -numberOfBits) ; +} + + +/** + * \brief GetValidBits Function. Clear cache and return valid Bits from Bitbuffer. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return amount of valid bits that still can be read or were already written. + * + */ +FDK_INLINE UINT FDKgetValidBits (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache(hBitStream) ; + return FDK_getValidBits(&hBitStream->hBitBuf) ; +} + + +/** + * \brief return amount of unused Bits from Bitbuffer. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return amount of free bits that still can be written into the bitstream + */ +FDK_INLINE INT FDKgetFreeBits (HANDLE_FDK_BITSTREAM hBitStream) +{ + return FDK_getFreeBits (&hBitStream->hBitBuf) ; +} + +/** + * \brief reset bitcounter in bitBuffer to zero. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return void + */ +FDK_INLINE void FDKresetBitCnt (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache (hBitStream) ; + FDK_setBitCnt (&hBitStream->hBitBuf, 0) ; +} + +/** + * \brief set bitcoutner in bitBuffer to given value. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param value new value to be assigned to the bit counter + * \return void + */ +FDK_INLINE void FDKsetBitCnt (HANDLE_FDK_BITSTREAM hBitStream, UINT value) +{ + FDKsyncCache (hBitStream) ; + FDK_setBitCnt (&hBitStream->hBitBuf, value) ; +} + +/** + * \brief get bitcounter state from bitBuffer. + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \return current bit counter value + */ +FDK_INLINE INT FDKgetBitCnt (HANDLE_FDK_BITSTREAM hBitStream) +{ + FDKsyncCache(hBitStream) ; + return FDK_getBitCnt(&hBitStream->hBitBuf) ; +} + + +/** + * \brief Fill the BitBuffer with a number of input bytes from external source. + * The bytesValid variable returns the number of ramaining valid bytes in extern inputBuffer. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param inputBuffer Pointer to input buffer with bitstream data. + * \param bufferSize Total size of inputBuffer array. + * \param bytesValid Input: number of valid bytes in inputBuffer. Output: bytes still left unread in inputBuffer. + * \return void + */ +FDK_INLINE void FDKfeedBuffer (HANDLE_FDK_BITSTREAM hBitStream, const UCHAR inputBuffer [], const UINT bufferSize, UINT *bytesValid) +{ + FDKsyncCache (hBitStream) ; + FDK_Feed(&hBitStream->hBitBuf, (UCHAR*)inputBuffer, bufferSize, bytesValid ) ; +} + + +/** + * \brief fill destination BitBuffer with a number of bytes from source BitBuffer. The + * bytesValid variable returns the number of ramaining valid bytes in source BitBuffer. + * + * \param hBSDst HANDLE_FDK_BITSTREAM handle to write data into + * \param hBSSrc HANDLE_FDK_BITSTREAM handle to read data from + * \param bytesValid Input: number of valid bytes in inputBuffer. Output: bytes still left unread in inputBuffer. + * \return void + */ +FDK_INLINE void FDKcopyBuffer (HANDLE_FDK_BITSTREAM hBSDst, HANDLE_FDK_BITSTREAM hBSSrc, UINT *bytesValid) +{ + FDKsyncCache (hBSSrc) ; + FDK_Copy (&hBSDst->hBitBuf, &hBSSrc->hBitBuf, bytesValid) ; +} + + +/** + * \brief fill the outputBuffer with all valid bytes hold in BitBuffer. The WriteBytes + * variable returns the number of written Bytes. + * + * \param hBitStream HANDLE_FDK_BITSTREAM handle + * \param outputBuffer Pointer to output buffer. + * \param writeBytes Number of bytes write to output buffer. + * \return void + */ +FDK_INLINE void FDKfetchBuffer(HANDLE_FDK_BITSTREAM hBitStream, UCHAR *outputBuffer, UINT *writeBytes) +{ + FDKsyncCache (hBitStream) ; + FDK_Fetch(&hBitStream->hBitBuf, outputBuffer, writeBytes); +} + + +#endif diff --git a/libFDK/include/FDK_core.h b/libFDK/include/FDK_core.h new file mode 100644 index 0000000..ce77882 --- /dev/null +++ b/libFDK/include/FDK_core.h @@ -0,0 +1,47 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Manuel Jander + Description: FDK tools versioning support + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef FDK_CORE_H +#define FDK_CORE_H + +#include "FDK_audio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Get FDK_tools library information. + * @return Return 0 on success and a negative errorcode on failure (see errorcodes.h). + */ +int FDK_toolsGetLibInfo(LIB_INFO *info); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libFDK/include/FDK_crc.h b/libFDK/include/FDK_crc.h new file mode 100644 index 0000000..29ae6c5 --- /dev/null +++ b/libFDK/include/FDK_crc.h @@ -0,0 +1,169 @@ +/******************************** MPEG Audio Encoder ************************** + + (C) copyright Fraunhofer-IIS (1999) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + + $Id$ + Initial author: + contents/description: CRC calculation + +******************************************************************************/ + +#ifndef FDK_CRC_H +#define FDK_CRC_H + + + +#include "FDK_bitstream.h" + + +#define MAX_CRC_REGS 3 /*!< Maximal number of overlapping crc region in ADTS channel pair element is two. + Select three independent regions preventively. */ + +/** + * This structure describes single crc region used for crc calculation. + */ +typedef struct +{ + UCHAR isActive; + INT maxBits; + UINT bitBufCntBits; + UINT validBits; + +} CCrcRegData; + +/** + * CRC info structure. + */ +typedef struct +{ + CCrcRegData crcRegData[MAX_CRC_REGS]; /*!< Multiple crc region description. */ + const USHORT *pCrcLookup; /*!< Pointer to lookup table filled in FDK_crcInit(). */ + + USHORT crcPoly; /*!< CRC generator polynom. */ + USHORT crcMask; /*!< CRC mask. */ + USHORT startValue; /*!< CRC start value. */ + UCHAR crcLen; /*!< CRC length. */ + + UINT regStart; /*!< Start region marker for synchronization. */ + UINT regStop; /*!< Stop region marker for synchronization. */ + + USHORT crcValue; /*!< Crc value to be calculated. */ + +} FDK_CRCINFO; + +/** + * CRC info handle. + */ +typedef FDK_CRCINFO* HANDLE_FDK_CRCINFO; + + +/** + * \brief Initialize CRC structure. + * + * The function initializes existing crc info structure with denoted configuration. + * + * \param hCrcInfo Pointer to an outlying allocated crc info structure. + * \param crcPoly Configure crc polynom. + * \param crcStartValue Configure crc start value. + * \param crcLen Configure crc length. + * + * \return none + */ +void FDKcrcInit( + HANDLE_FDK_CRCINFO hCrcInfo, + const UINT crcPoly, + const UINT crcStartValue, + const UINT crcLen + ); + +/** + * \brief Reset CRC info structure. + * + * This function clears all intern states of the crc structure. + * + * \param hCrcInfo Pointer to crc info stucture. + * + * \return none + */ +void FDKcrcReset( + HANDLE_FDK_CRCINFO hCrcInfo + ); + + +/** + * \brief Start CRC region with maximum number of bits. + * + * This function marks position in bitstream to be used as start point for crc calculation. + * Bitstream range for crc calculation can be limited or kept dynamic depending on mBits parameter. + * The crc region has to be terminated with FDKcrcEndReg() in each case. + * + * \param hCrcInfo Pointer to crc info stucture. + * \param hBs Pointer to current bit buffer structure. + * \param mBits Number of bits in crc region to be calculated. + * - mBits > 0: Zero padding will be used for CRC calculation, if there + * are less than mBits bits available. + * - mBits < 0: No zero padding is done. + * - mBits = 0: The number of bits used in crc calculation is dynamically, + * depending on bitstream position between FDKcrcStartReg() and + * FDKcrcEndReg() call. + * + * \return ID for the created region, -1 in case of an error + */ +INT FDKcrcStartReg( + HANDLE_FDK_CRCINFO hCrcInfo, + const HANDLE_FDK_BITSTREAM hBs, + const INT mBits + ); + + +/** + * \brief Ends CRC region. + * + * This function terminates crc region specified with FDKcrcStartReg(). The number of bits in crc region depends + * on mBits parameter of FDKcrcStartReg(). + * This function calculates and updates crc in info structure. + * + * \param hCrcInfo Pointer to crc info stucture. + * \param hBs Pointer to current bit buffer structure. + * \param reg Crc region ID created in FDKcrcStartReg(). + * + * \return 0 on success + */ +INT FDKcrcEndReg( + HANDLE_FDK_CRCINFO hCrcInfo, + const HANDLE_FDK_BITSTREAM hBs, + const INT reg + ); + + +/** + * \brief This function returns crc value from info struct. + * + * \param hCrcInfo Pointer to crc info stucture. + * + * \return CRC value masked with crc length. + */ +USHORT FDKcrcGetCRC( + const HANDLE_FDK_CRCINFO hCrcInfo + ); + + +#endif /* FDK_CRC_H */ diff --git a/libFDK/include/FDK_tools_rom.h b/libFDK/include/FDK_tools_rom.h new file mode 100644 index 0000000..6425e49 --- /dev/null +++ b/libFDK/include/FDK_tools_rom.h @@ -0,0 +1,205 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2008) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Oliver Moser + Description: ROM tables used by FDK tools + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __FDK_TOOLS_ROM_H__ +#define __FDK_TOOLS_ROM_H__ + +#include "common_fix.h" +#include "FDK_audio.h" + + +/* None radix2 rotation vectors */ +extern const FIXP_STB RotVectorReal60[60]; +extern const FIXP_STB RotVectorImag60[60]; +extern const FIXP_STB RotVectorReal240[240]; +extern const FIXP_STB RotVectorImag240[240]; +extern const FIXP_STB RotVectorReal480[480]; +extern const FIXP_STB RotVectorImag480[480]; + + +/* Regular sine tables */ +extern const FIXP_STP SineTable512[]; +extern const FIXP_STP SineTable480[]; + +/* AAC-LC windows */ +extern const FIXP_WTP SineWindow1024[]; +extern const FIXP_WTP KBDWindow1024[]; +extern const FIXP_WTP SineWindow128[]; +extern const FIXP_WTP KBDWindow128[]; + +extern const FIXP_WTP SineWindow960[]; +extern const FIXP_WTP KBDWindow960[]; +extern const FIXP_WTP SineWindow120[]; +extern const FIXP_WTP KBDWindow120[]; + +/* AAC-LD windows */ +extern const FIXP_WTP SineWindow512[]; +#define LowOverlapWindow512 SineWindow128 +extern const FIXP_WTP SineWindow480[]; +#define LowOverlapWindow480 SineWindow120 + + + +extern const FIXP_WTP SineWindow64[]; +extern const FIXP_WTP SineWindow32[]; + +/** + * \brief Helper table for window slope mapping. You should prefer the usage of the + * function FDKgetWindowSlope(), this table is only made public for some optimized + * access inside dct.cpp. + */ +extern const FIXP_WTP *const windowSlopes[2][3][9]; + +/** + * \brief Window slope access helper. Obtain a window of given length and shape. + * \param length Length of the window slope. + * \param shape Shape index of the window slope. 0: sine window, 1: Kaiser-Bessel. Any other + * value is applied a mask of 1 to, mapping it to either 0 or 1. + * \param Pointer to window slope or NULL if the requested window slope is not available. + */ +const FIXP_WTP * FDKgetWindowSlope(int length, int shape); + +extern const FIXP_WTP sin_twiddle_L64[]; + +/* + * Filter coefficient type definition + */ + +#if defined(ARCH_PREFER_MULT_16x16) || defined(ARCH_PREFER_MULT_32x16) + #define QMF_COEFF_16BIT +#endif + +#define QMF_FILTER_PROTOTYPE_SIZE 640 +#define QMF_NO_POLY 5 + +#ifdef QMF_COEFF_16BIT + #define FIXP_PFT FIXP_SGL + #define FIXP_QTW FIXP_SGL +#else + #define FIXP_PFT FIXP_DBL + #define FIXP_QTW FIXP_DBL +#endif + +#define QMF640_PFT_TABLE_SIZE (640/2 + QMF_NO_POLY) + +extern const FIXP_QTW qmf_phaseshift_cos32[32]; +extern const FIXP_QTW qmf_phaseshift_sin32[32]; +extern const FIXP_QTW qmf_phaseshift_cos64[64]; +extern const FIXP_QTW qmf_phaseshift_sin64[64]; + +extern const FIXP_PFT qmf_64[QMF640_PFT_TABLE_SIZE+QMF_NO_POLY]; + + + + + +#define QMF640_CLDFB_PFT_TABLE_SIZE (640) +#define QMF320_CLDFB_PFT_TABLE_SIZE (320) +#define QMF_CLDFB_PFT_SCALE 1 + +extern const FIXP_QTW qmf_phaseshift_cos32_cldfb[32]; +extern const FIXP_QTW qmf_phaseshift_sin32_cldfb[32]; +extern const FIXP_QTW qmf_phaseshift_cos64_cldfb[64]; +extern const FIXP_QTW qmf_phaseshift_sin64_cldfb[64]; + +extern const FIXP_PFT qmf_cldfb_640[QMF640_CLDFB_PFT_TABLE_SIZE]; +extern const FIXP_PFT qmf_cldfb_320[QMF320_CLDFB_PFT_TABLE_SIZE]; + + + + + +/* + * Raw Data Block list stuff. + */ +typedef enum { + element_instance_tag, + common_window, + global_gain, + ics_info, /* ics_reserved_bit, window_sequence, window_shape, max_sfb, scale_factor_grouping, predictor_data_present, ltp_data_present, ltp_data */ + max_sfb, + ms, /* ms_mask_present, ms_used */ + /*predictor_data_present,*/ /* part of ics_info */ + ltp_data_present, + ltp_data, + section_data, + scale_factor_data, + pulse, /* pulse_data_present, pulse_data */ + tns_data_present, + tns_data, + gain_control_data_present, + gain_control_data, + esc1_hcr, + esc2_rvlc, + spectral_data, + + scale_factor_data_usac, + core_mode, + common_tw, + lpd_channel_stream, + tw_data, + noise, + ac_spectral_data, + fac_data, + tns_active, /* introduced in MPEG-D usac CD */ + tns_data_present_usac, + common_max_sfb, + + + /* Non data list items */ + adtscrc_start_reg1, + adtscrc_start_reg2, + adtscrc_end_reg1, + adtscrc_end_reg2, + drmcrc_start_reg, + drmcrc_end_reg, + next_channel, + next_channel_loop, + link_sequence, + end_of_sequence +} rbd_id_t; + +struct element_list { + const rbd_id_t *id; + const struct element_list *next[2]; +}; + +typedef struct element_list element_list_t; +/** + * \brief get elementary stream pieces list for given parameters. + * \param aot audio object type + * \param epConfig the epConfig value from the current Audio Specific Config + * \param nChannels amount of channels contained in the current element. + * \param layer the layer of the current element. + * \return element_list_t parser guidance structure. + */ +const element_list_t * getBitstreamElementList(AUDIO_OBJECT_TYPE aot, SCHAR epConfig, UCHAR nChannels, UCHAR layer); + + +#endif + diff --git a/libFDK/include/FDK_trigFcts.h b/libFDK/include/FDK_trigFcts.h new file mode 100644 index 0000000..19ab0b8 --- /dev/null +++ b/libFDK/include/FDK_trigFcts.h @@ -0,0 +1,169 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2005) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Haricharan Lakshman, Manuel Jander + Description: Trigonometric functions fixed point fractional implementation. + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + + + +#include "common_fix.h" + +#include "FDK_tools_rom.h" + +/* Fixed point precision definitions */ +#define Q(format) ((FIXP_DBL)(((LONG)1) << (format))) + +#ifndef M_PI +#define M_PI (3.14159265358979323846f) +#endif + +/*! + * Inverse tangent function. + */ + +// --- fixp_atan() ---- +#define Q_ATANINP (25) // Input in q25, Output in q30 +#define Q_ATANOUT (30) +#define ATI_SF ((DFRACT_BITS-1)-Q_ATANINP) // 6 +#define ATI_SCALE ((float)(1<<ATI_SF)) // +#define ATO_SF ((DFRACT_BITS-1)-Q_ATANOUT) // 1 ] -pi/2 .. pi/2 [ +#define ATO_SCALE ((float)(1<<ATO_SF)) // +// --- fixp_atan2() --- +#define Q_ATAN2OUT (29) +#define AT2O_SF ((DFRACT_BITS-1)-Q_ATAN2OUT) // 2 ] -pi .. pi ] +#define AT2O_SCALE ((float)(1<<AT2O_SF)) // +// -------------------- + +FIXP_DBL fixp_atan(FIXP_DBL x); +FIXP_DBL fixp_atan2(FIXP_DBL y, FIXP_DBL x); + +FIXP_DBL fixp_cos(FIXP_DBL x, int scale); +FIXP_DBL fixp_sin(FIXP_DBL x, int scale); + +#define FIXP_COS_SIN + +#ifndef CORDIC_SINCOS + +#include "FDK_tools_rom.h" + +#define SINETAB SineTable512 +#define LD 9 + +#endif + +#ifndef FUNCTION_inline_fixp_cos_sin + +#define FUNCTION_inline_fixp_cos_sin + +/* + * Calculates coarse lookup index and sign for sine. + * Returns delta x residual. + */ +static inline FIXP_DBL fixp_sin_cos_residual_inline(FIXP_DBL x, int scale, FIXP_DBL *sine, FIXP_DBL *cosine) +{ + FIXP_DBL residual; + int s; + int shift = (31-scale-LD-1); + int ssign = 1; + int csign = 1; + + residual = fMult(x, FL2FXCONST_DBL(1.0/M_PI)); + s = ((LONG)residual) >> shift; + + residual &= ( (1<<shift) - 1 ); + residual = fMult(residual, FL2FXCONST_DBL(M_PI/4.0)) << 2; + residual <<= scale; + + /* Sine sign symmetry */ + if (s & ((1<<LD)<<1) ) { + ssign = -ssign; + } + /* Cosine sign symmetry */ + if ( (s + (1<<LD)) & ((1<<LD)<<1) ) { + csign = -csign; + } + + s = fAbs(s); + + s &= (((1<<LD)<<1)-1); /* Modulo PI */ + + if (s > (1<<LD)) { + s = ((1<<LD)<<1) - s; + } + + { + LONG sl, cl; + /* Because of packed table */ + if (s > (1<<(LD-1))) { + FIXP_STP tmp; + /* Cosine/Sine simetry for angles greater than PI/4 */ + s = (1<<LD)-s; + tmp = SINETAB[s]; + sl = (LONG)tmp.v.re; + cl = (LONG)tmp.v.im; + } else { + FIXP_STP tmp; + tmp = SINETAB[s]; + sl = (LONG)tmp.v.im; + cl = (LONG)tmp.v.re; + } + +#ifdef SINETABLE_16BIT + *sine = (FIXP_DBL)((sl * ssign) << (DFRACT_BITS-FRACT_BITS)); + *cosine = (FIXP_DBL)((cl * csign) << (DFRACT_BITS-FRACT_BITS)); +#else + *sine = (FIXP_DBL)(sl * ssign); + *cosine = (FIXP_DBL)(cl * csign); +#endif + } + + return residual; +} + +/** + * \brief Calculate cosine and sine value each of 2 angles different angle values. + * \param x1 first angle value + * \param x2 second angle value + * \param scale exponent of x1 and x2 + * \param out pointer to 4 FIXP_DBL locations, were the values cos(x1), sin(x1), cos(x2), sin(x2) + * will be stored into. + */ +static inline void inline_fixp_cos_sin (FIXP_DBL x1, FIXP_DBL x2, const int scale, FIXP_DBL *out) +{ + FIXP_DBL residual, error0, error1, sine, cosine; + residual = fixp_sin_cos_residual_inline(x1, scale, &sine, &cosine); + error0 = fMultDiv2(sine, residual); + error1 = fMultDiv2(cosine, residual); + *out++ = cosine - (error0<<1); + *out++ = sine + (error1<<1); + + residual = fixp_sin_cos_residual_inline(x2, scale, &sine, &cosine); + error0 = fMultDiv2(sine, residual); + error1 = fMultDiv2(cosine, residual); + *out++ = cosine - (error0<<1); + *out++ = sine + (error1<<1); +} +#endif + diff --git a/libFDK/include/abs.h b/libFDK/include/abs.h new file mode 100644 index 0000000..69b6be3 --- /dev/null +++ b/libFDK/include/abs.h @@ -0,0 +1,59 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2005) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser + Description: fixed point abs definitions + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#if !defined(__ABS_H__) +#define __ABS_H__ + + +#if defined(__mips__) /* cppp replaced: elif */ +#include "mips/abs_mips.h" + +#elif defined(__x86__) /* cppp replaced: elif */ +#include "x86/abs_x86.h" + +#endif /* all cores */ + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions +************************************************************************** +**************************************************************************/ + +#if !defined(FUNCTION_fixabs_D) +inline FIXP_DBL fixabs_D(FIXP_DBL x) { return ((x) > (FIXP_DBL)(0)) ? (x) : -(x) ; } +#endif + +#if !defined(FUNCTION_fixabs_I) +inline INT fixabs_I(INT x) { return ((x) > (INT)(0)) ? (x) : -(x) ; } +#endif + +#if !defined(FUNCTION_fixabs_S) +inline FIXP_SGL fixabs_S(FIXP_SGL x) { return ((x) > (FIXP_SGL)(0)) ? (x) : -(x) ; } +#endif + +#endif /* __ABS_H__ */ diff --git a/libFDK/include/arm/clz_arm.h b/libFDK/include/arm/clz_arm.h new file mode 100644 index 0000000..d3c3e04 --- /dev/null +++ b/libFDK/include/arm/clz_arm.h @@ -0,0 +1,59 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__arm__) + +#if defined(__GNUC__) && defined(__ARM_ARCH_5TE__) /* cppp replaced: elif */ + /* ARM gcc*/ + + #define FUNCTION_fixnormz_D + #define FUNCTION_fixnorm_D + + inline INT fixnormz_D(LONG value) + { + INT result; + asm("clz %0, %1 ": "=r"(result) : "r"(value) ); + return result; + } + + inline INT fixnorm_D(LONG value) + { + INT result; + if (value < 0) { + value = ~value; + } + if (value == 0) { + return 0; + } + result = fixnormz_D(value); + return result - 1; + } + +#endif /* arm toolchain */ + +#endif /* __arm__ */ + diff --git a/libFDK/include/arm/cplx_mul.h b/libFDK/include/arm/cplx_mul.h new file mode 100644 index 0000000..dba2a9f --- /dev/null +++ b/libFDK/include/arm/cplx_mul.h @@ -0,0 +1,153 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + + +#if defined(__arm__) && defined(__GNUC__) /* cppp replaced: elif */ + +#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) + #define FUNCTION_cplxMultDiv2_32x16 + #define FUNCTION_cplxMultDiv2_32x16X2 + //#define FUNCTION_cplxMult_32x16 + //#define FUNCTION_cplxMult_32x16X2 +#endif + +#define FUNCTION_cplxMultDiv2_32x32X2 +//#define FUNCTION_cplxMult_32x32X2 + +#ifdef FUNCTION_cplxMultDiv2_32x16 +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SPK wpk ) +{ + LONG tmp1,tmp2; + const LONG w = wpk.w; + + asm("smulwt %0, %3, %4;\n" + "rsb %1,%0,#0;\n" + "smlawb %0, %2, %4, %1;\n" + "smulwt %1, %2, %4;\n" + "smlawb %1, %3, %4, %1;\n" + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(w) + ); + + *c_Re = tmp1; + *c_Im = tmp2; +} +#endif /* FUNCTION_cplxMultDiv2_32x16 */ + +#ifdef FUNCTION_cplxMultDiv2_32x16X2 +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + LONG tmp1, tmp2; + + asm("smulwb %0, %3, %5;\n" /* %7 = -a_Im * b_Im */ + "rsb %1,%0,#0;\n" + "smlawb %0, %2, %4, %1;\n" /* tmp1 = a_Re * b_Re - a_Im * b_Im */ + "smulwb %1, %2, %5;\n" /* %7 = a_Re * b_Im */ + "smlawb %1, %3, %4, %1;\n" /* tmp2 = a_Im * b_Re + a_Re * b_Im */ + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im) + ); + + *c_Re = tmp1; + *c_Im = tmp2; +} +#endif /* FUNCTION_cplxMultDiv2_32x16X2 */ + +#ifdef FUNCTION_cplxMultAddDiv2_32x16X2 +inline void cplxMultAddDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + LONG tmp1, tmp2; + + asm("smulwb %0, %3, %5;\n" + "rsb %1,%0,#0;\n" + "smlawb %0, %2, %4, %1;\n" + "smulwb %1, %2, %5;\n" + "smlawb %1, %3, %4, %1;\n" + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im) + ); + + *c_Re += tmp1; + *c_Im += tmp2; +} +#endif /* FUNCTION_cplxMultAddDiv2_32x16X2 */ + + +#ifdef FUNCTION_cplxMultDiv2_32x32X2 +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + LONG tmp1, tmp2; + +#ifdef __ARM_ARCH_6__ + asm( + "smmul %0, %2, %4;\n" /* tmp1 = a_Re * b_Re */ + "smmls %0, %3, %5, %0;\n" /* tmp1 -= a_Im * b_Im */ + "smmul %1, %2, %5;\n" /* tmp2 = a_Re * b_Im */ + "smmla %1, %3, %4, %1;\n" /* tmp2 += a_Im * b_Re */ + : "=&r"(tmp1), "=&r"(tmp2) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im) + : "r0" + ); +#else + LONG discard; + asm( + "smull %2, %0, %7, %6;\n" /* tmp1 = -a_Im * b_Im */ + "smlal %2, %0, %3, %5;\n" /* tmp1 += a_Re * b_Re */ + "smull %2, %1, %3, %6;\n" /* tmp2 = a_Re * b_Im */ + "smlal %2, %1, %4, %5;\n" /* tmp2 += a_Im * b_Re */ + : "=&r"(tmp1), "=&r"(tmp2), "=&r"(discard) + : "r"(a_Re), "r"(a_Im), "r"(b_Re), "r"(b_Im), "r"(-a_Im) + ); + #endif + *c_Re = tmp1; + *c_Im = tmp2; +} +#endif /* FUNCTION_cplxMultDiv2_32x32X2 */ + + +#endif + diff --git a/libFDK/include/arm/fixmadd_arm.h b/libFDK/include/arm/fixmadd_arm.h new file mode 100644 index 0000000..15308f7 --- /dev/null +++ b/libFDK/include/arm/fixmadd_arm.h @@ -0,0 +1,97 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__arm__) + + /* ############################################################################# */ + #if defined(__GNUC__) && defined(__arm__) && !defined(__SYMBIAN32__) /* cppp replaced: elif */ + /* ############################################################################# */ + /* ARM GNU GCC */ + + #define FUNCTION_fixmadddiv2_DD + + #ifdef __ARM_ARCH_6__ + inline FIXP_DBL fixmadddiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + INT result; + asm ("smmla %0, %1, %2, %3;\n" + : "=r" (result) + : "r" (a), "r" (b), "r"(x) ); + return result ; + } + #define FUNCTION_fixmsubdiv2_DD + inline FIXP_DBL fixmsubdiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + INT result; + asm ("smmls %0, %1, %2, %3;\n" + : "=r" (result) + : "r" (a), "r" (b), "r"(x) ); + return result ; + } + #else /* __ARM_ARCH_6__ */ + inline FIXP_DBL fixmadddiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + INT discard, result = x; + asm ("smlal %0, %1, %2, %3;\n" + : "=r" (discard), "+r" (result) + : "r" (a), "r" (b) ); + return result ; + } + #endif /* __ARM_ARCH_6__ */ + + #if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) + + #define FUNCTION_fixmadddiv2_DS + + inline FIXP_DBL fixmadddiv2_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { + INT result; + asm("smlawb %0, %1, %2, %3 " + : "=r" (result) + : "r" (a), "r" (b), "r" (x) ); + return result ; + } + + #endif /* defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) */ + + #define FUNCTION_fixmadddiv2BitExact_DD + #define fixmadddiv2BitExact_DD(a, b, c) fixmadddiv2_DD(a, b, c) + + #define FUNCTION_fixmsubdiv2BitExact_DD + inline FIXP_DBL fixmsubdiv2BitExact_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + return x - fixmuldiv2BitExact_DD(a, b); + } + + #define FUNCTION_fixmadddiv2BitExact_DS + #define fixmadddiv2BitExact_DS(a, b, c) fixmadddiv2_DS(a, b, c) + + #define FUNCTION_fixmsubdiv2BitExact_DS + inline FIXP_DBL fixmsubdiv2BitExact_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { + return x - fixmuldiv2BitExact_DS(a, b); + } + /* ############################################################################# */ + #endif /* toolchain */ + /* ############################################################################# */ + +#endif /* __arm__ */ + diff --git a/libFDK/include/arm/fixmul_arm.h b/libFDK/include/arm/fixmul_arm.h new file mode 100644 index 0000000..8cc448d --- /dev/null +++ b/libFDK/include/arm/fixmul_arm.h @@ -0,0 +1,79 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__arm__) + +#if defined(__GNUC__) && defined(__arm__) /* cppp replaced: elif */ +/* ARM with GNU compiler */ + +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + +#if defined(__ARM_ARCH_6__) || defined(__TARGET_ARCH_7E_M) +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT result ; + __asm__ ("smmul %0, %1, %2" : "=r" (result) + : "r" (a), "r" (b)) ; + return result ; +} +#else +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT discard, result ; + __asm__ ("smull %0, %1, %2, %3" : "=&r" (discard), "=r" (result) + : "r" (a), "r" (b)) ; + return result ; +} +#endif + +#if defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_6__) +#define FUNCTION_fixmuldiv2_SD +inline INT fixmuldiv2_SD (const SHORT a, const INT b) +{ + INT result ; + __asm__ ("smulwb %0, %1, %2" + : "=r" (result) + : "r" (b), "r" (a)) ; + return result ; +} +#endif + +#endif /* defined(__GNUC__) && defined(__arm__) */ + +#endif /* __arm__ */ + diff --git a/libFDK/include/arm/scale.h b/libFDK/include/arm/scale.h new file mode 100644 index 0000000..11d18fb --- /dev/null +++ b/libFDK/include/arm/scale.h @@ -0,0 +1,90 @@ +/******************************** Fraunhofer IIS *************************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id: + Author(s): + Description: ARM scaling operations + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#if defined(__GNUC__) /* GCC Compiler */ /* cppp replaced: elif */ + +#if defined(__ARM_ARCH_6__) + +inline static INT shiftRightSat(INT src, int scale) +{ + INT result; + asm( + "ssat %0,%2,%0;\n" + + : "=&r"(result) + : "r"(src>>scale), "M"(SAMPLE_BITS) + ); + + return result; +} + + #define SATURATE_INT_PCM_RIGHT_SHIFT(src, scale) shiftRightSat(src, scale) + +inline static INT shiftLeftSat(INT src, int scale) +{ + INT result; + asm( + "ssat %0,%2,%0;\n" + + : "=&r"(result) + : "r"(src<<scale), "M"(SAMPLE_BITS) + ); + + return result; +} + + #define SATURATE_INT_PCM_LEFT_SHIFT(src, scale) shiftLeftSat(src, scale) + +#endif /* __ARM_ARCH_6__ */ + +#endif /* compiler selection */ + +#define FUNCTION_scaleValueInPlace +inline +void scaleValueInPlace(FIXP_DBL *value, /*!< Value */ + INT scalefactor /*!< Scalefactor */ + ) +{ + INT newscale; + if ((newscale = scalefactor) >= 0) + *value <<= newscale; + else + *value >>= -newscale; +} + + + #define SATURATE_RIGHT_SHIFT(src, scale, dBits) \ + ( (((LONG)(src) ^ ((LONG)(src) >> (DFRACT_BITS-1)))>>(scale)) > (LONG)(((1U)<<((dBits)-1))-1)) \ + ? ((LONG)(src) >> (DFRACT_BITS-1)) ^ (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) >> (scale)) + + #define SATURATE_LEFT_SHIFT(src, scale, dBits) \ + ( ((LONG)(src) ^ ((LONG)(src) >> (DFRACT_BITS-1))) > ((LONG)(((1U)<<((dBits)-1))-1) >> (scale)) ) \ + ? ((LONG)(src) >> (DFRACT_BITS-1)) ^ (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) << (scale)) + diff --git a/libFDK/include/arm/scramble.h b/libFDK/include/arm/scramble.h new file mode 100644 index 0000000..9143155 --- /dev/null +++ b/libFDK/include/arm/scramble.h @@ -0,0 +1,98 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2005) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: bitreversal of input data + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + + + +#if defined(FUNCTION_scramble) +#if defined(__GNUC__) /* cppp replaced: elif */ + +#define FUNCTION_scramble + +#if defined(__ARM_ARCH_5TE__) +#define USE_LDRD_STRD /* LDRD requires 8 byte data alignment. */ +#endif + +inline void scramble(FIXP_DBL x [], INT n) { + FDK_ASSERT(!(((INT)x)&(ALIGNMENT_DEFAULT-1))); + asm("mov r2, #1;\n" /* r2(m) = 1; */ + "sub r3, %1, #1;\n" /* r3 = n-1; */ + "mov r4, #0;\n" /* r4(j) = 0; */ + +"scramble_m_loop%=:\n" /* { */ + "mov r5, %1;\n" /* r5(k) = 1; */ + +"scramble_k_loop%=:\n" /* { */ + "mov r5, r5, lsr #1;\n" /* k >>= 1; */ + "eor r4, r4, r5;\n" /* j ^=k; */ + "ands r10, r4, r5;\n" /* r10 = r4 & r5; */ + "beq scramble_k_loop%=;\n" /* } while (r10 == 0); */ + + "cmp r4, r2;\n" /* if (r4 < r2) break; */ + "bcc scramble_m_loop_end%=;\n" + +#ifdef USE_LDRD_STRD + "mov r5, r2, lsl #3;\n" /* m(r5) = r2*4*2 */ + "ldrd r10, [%0, r5];\n" /* r10 = x[r5], x7 = x[r5+1] */ + "mov r6, r4, lsl #3;\n" /* j(r6) = r4*4*2 */ + "ldrd r8, [%0, r6];\n" /* r8 = x[r6], r9 = x[r6+1]; */ + "strd r10, [%0, r6];\n" /* x[r6,r6+1] = r10,r11; */ + "strd r8, [%0, r5];\n" /* x[r5,r5+1] = r8,r9; */ +#else + "mov r5, r2, lsl #3;\n" /* m(r5) = r2*4*2 */ + "ldr r10, [%0, r5];\n" + "mov r6, r4, lsl #3;\n" /* j(r6) = r4*4*2 */ + "ldr r11, [%0, r6];\n" + + "str r10, [%0, r6];\n" + "str r11, [%0, r5];\n" + + "add r5, r5, #4;" + "ldr r10, [%0, r5];\n" + "add r6, r6, #4;" + "ldr r11, [%0, r6];\n" + "str r10, [%0, r6];\n" + "str r11, [%0, r5];\n" +#endif +"scramble_m_loop_end%=:\n" + "add r2, r2, #1;\n" /* r2++; */ + "cmp r2, r3;\n" + "bcc scramble_m_loop%=;\n" /* } while (r2(m) < r3(n-1)); */ + : + : "r"(x), "r"(n) +#ifdef USE_LDRD_STRD + : "r2","r3", "r4","r5", "r10","r11", "r8","r9", "r6" ); +#else + : "r2","r3", "r4","r5", "r10","r11", "r6" ); +#endif +} +#else +/* Force C implementation if no assembler version available. */ +#undef FUNCTION_scramble +#endif /* Toolchain selection. */ + +#endif /* defined(FUNCTION_scramble) */ diff --git a/libFDK/include/autocorr2nd.h b/libFDK/include/autocorr2nd.h new file mode 100644 index 0000000..896fc17 --- /dev/null +++ b/libFDK/include/autocorr2nd.h @@ -0,0 +1,66 @@ +/*************************** Fraunhofer IIS FDK Tools *********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser + Description: fixed point abs definitions + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef _AUTOCORR_2ND_H +#define _AUTOCORR_2ND_H + + + +#include "common_fix.h" + +typedef struct { + FIXP_DBL r00r; + FIXP_DBL r11r; + FIXP_DBL r22r; + FIXP_DBL r01r; + FIXP_DBL r02r; + FIXP_DBL r12r; + FIXP_DBL r01i; + FIXP_DBL r02i; + FIXP_DBL r12i; + FIXP_DBL det; + int det_scale; +} ACORR_COEFS; + +#define LPC_ORDER 2 + + +INT +autoCorr2nd_real (ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */ + const FIXP_DBL *reBuffer, /*!< Pointer to to real part of spectrum */ + const int len /*!< Number of qmf slots */ + ); +INT +autoCorr2nd_cplx (ACORR_COEFS *ac, /*!< Pointer to autocorrelation coeffs */ + const FIXP_DBL *reBuffer, /*!< Pointer to to real part of spectrum */ + const FIXP_DBL *imBuffer, /*!< Pointer to imag part of spectrum */ + const int len /*!< Number of qmf slots */ + ); + + +#endif /* _AUTOCORR_2ND_H */ diff --git a/libFDK/include/clz.h b/libFDK/include/clz.h new file mode 100644 index 0000000..42c1c53 --- /dev/null +++ b/libFDK/include/clz.h @@ -0,0 +1,127 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (1999) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Marc Gayer + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#if !defined(__CLZ_H__) +#define __CLZ_H__ + +#include "FDK_archdef.h" +#include "machine_type.h" + +#if defined(__arm__) +#include "arm/clz_arm.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/clz_mips.h" + +#endif /* all cores */ + + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions. +************************************************************************** +**************************************************************************/ + +#if !defined(FUNCTION_fixnormz_S) +#ifdef FUNCTION_fixnormz_D +inline INT fixnormz_S (SHORT a) +{ + return fixnormz_D((INT)(a)); +} +#else +inline INT fixnormz_S (SHORT a) +{ + int leadingBits = 0; + a = ~a; + while(a & 0x8000) { + leadingBits++; + a <<= 1; + } + + return (leadingBits); +} +#endif +#endif + +#if !defined(FUNCTION_fixnormz_D) +inline INT fixnormz_D (LONG a) +{ + INT leadingBits = 0; + a = ~a; + while(a & 0x80000000) { + leadingBits++; + a <<= 1; + } + + return (leadingBits); +} +#endif + + +/***************************************************************************** + + functionname: fixnorm_D + description: Count leading ones or zeros of operand val for dfract/LONG INT values. + Return this value minus 1. Return 0 if operand==0. +*****************************************************************************/ +#if !defined(FUNCTION_fixnorm_S) +#ifdef FUNCTION_fixnorm_D +inline INT fixnorm_S(FIXP_SGL val) +{ + return fixnorm_D((INT)(val)); +} +#else +inline INT fixnorm_S(FIXP_SGL val) +{ + INT leadingBits = 0; + if ( val != (FIXP_SGL)0 ) { + if ( val < (FIXP_SGL)0 ) { + val = ~val; + } + leadingBits = fixnormz_S(val) - 1; + } + return (leadingBits); +} +#endif +#endif + +#if !defined(FUNCTION_fixnorm_D) +inline INT fixnorm_D(FIXP_DBL val) +{ + INT leadingBits = 0; + if ( val != (FIXP_DBL)0 ) { + if ( val < (FIXP_DBL)0 ) { + val = ~val; + } + leadingBits = fixnormz_D(val) - 1; + } + return (leadingBits); +} +#endif + +#endif /* __CLZ_H__ */ diff --git a/libFDK/include/common_fix.h b/libFDK/include/common_fix.h new file mode 100644 index 0000000..c5cbd8a --- /dev/null +++ b/libFDK/include/common_fix.h @@ -0,0 +1,324 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2002) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser, M. Gayer + Description: Flexible fixpoint library configuration + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef _COMMON_FIX_H +#define _COMMON_FIX_H + +#include "FDK_archdef.h" +#include "machine_type.h" + +/* ***** Start of former fix.h ****** */ + +/* Configure fractional or integer arithmetic */ + #define FIX_FRACT 0 /* Define this to "1" to use fractional arithmetic simulation in class fract instead of integer arithmetic */ + /* 1 for debug with extra runtime overflow checking. */ + +/* Truncate -1.0 to -1.0 + 1/(D)FRACT_FIX_SCALE */ +//#define FRACT_TRUNC_MINUSONE + +/* Define bit sizes of integer fixpoint fractional data types */ +#define FRACT_BITS 16 /* single precision */ +#define DFRACT_BITS 32 /* double precision */ +#define ACCU_BITS 40 /* double precision plus overflow */ + +/* Fixpoint equivalent type fot PCM audio time domain data. */ +#if defined(SAMPLE_BITS) +#if (SAMPLE_BITS == DFRACT_BITS) + #define FIXP_PCM FIXP_DBL + #define FX_PCM2FX_DBL(x) ((FIXP_DBL)(x)) + #define FX_DBL2FX_PCM(x) ((INT_PCM)(x)) +#elif (SAMPLE_BITS == FRACT_BITS) + #define FIXP_PCM FIXP_SGL + #define FX_PCM2FX_DBL(x) FX_SGL2FX_DBL((FIXP_SGL)(x)) + #define FX_DBL2FX_PCM(x) FX_DBL2FX_SGL(x) +#else + #error SAMPLE_BITS different from FRACT_BITS or DFRACT_BITS not implemented! +#endif +#endif + +/* ****** End of former fix.h ****** */ + +#define SGL_MASK ((1UL<<FRACT_BITS)-1) /* 16bit: (2^16)-1 = 0xFFFF */ + +#define MAX_SHIFT_SGL (FRACT_BITS-1) /* maximum possible shift for FIXP_SGL values */ +#define MAX_SHIFT_DBL (DFRACT_BITS-1) /* maximum possible shift for FIXP_DBL values */ + +/* Scale factor from/to float/fixpoint values. DO NOT USE THESE VALUES AS SATURATION LIMITS !! */ +#define FRACT_FIX_SCALE ((INT64(1)<<(FRACT_BITS-1))) +#define DFRACT_FIX_SCALE ((INT64(1)<<(DFRACT_BITS-1))) + +/* Max and Min values for saturation purposes. DO NOT USE THESE VALUES AS SCALE VALUES !! */ +#define MAXVAL_SGL ((signed)0x00007FFF) /* this has to be synchronized to FRACT_BITS */ +#define MINVAL_SGL ((signed)0xFFFF8000) /* this has to be synchronized to FRACT_BITS */ +#define MAXVAL_DBL ((signed)0x7FFFFFFF) /* this has to be synchronized to DFRACT_BITS */ +#define MINVAL_DBL ((signed)0x80000000) /* this has to be synchronized to DFRACT_BITS */ + + +#define FX_DBL2FXCONST_SGL(val) ( ( ((((val) >> (DFRACT_BITS-FRACT_BITS-1)) + 1) > (((LONG)1<<FRACT_BITS)-1)) && ((LONG)(val) > 0) ) ? \ + (FIXP_SGL)(SHORT)(((LONG)1<<(FRACT_BITS-1))-1):(FIXP_SGL)(SHORT)((((val) >> (DFRACT_BITS-FRACT_BITS-1)) + 1) >> 1) ) + + + +#define shouldBeUnion union /* unions are possible */ + + typedef SHORT FIXP_SGL; + typedef LONG FIXP_DBL; + +/* macros for compile-time conversion of constant float values to fixedpoint */ +#define FL2FXCONST_SPC FL2FXCONST_DBL + +#ifdef FRACT_TRUNC_MINUSONE +#define MINVAL_DBL_CONST MINVAL_DBL+1 +#define MINVAL_SGL_CONST MINVAL_SGL+1 +#else +#define MINVAL_DBL_CONST MINVAL_DBL +#define MINVAL_SGL_CONST MINVAL_SGL +#endif + +#define FL2FXCONST_SGL(val) \ +(FIXP_SGL)( ( (val) >= 0) ? \ +((( (double)(val) * (FRACT_FIX_SCALE) + 0.5 ) >= (double)(MAXVAL_SGL) ) ? (SHORT)(MAXVAL_SGL) : (SHORT)( (double)(val) * (double)(FRACT_FIX_SCALE) + 0.5)) : \ +((( (double)(val) * (FRACT_FIX_SCALE) - 0.5) <= (double)(MINVAL_SGL_CONST) ) ? (SHORT)(MINVAL_SGL_CONST) : (SHORT)( (double)(val) * (double)(FRACT_FIX_SCALE) - 0.5)) ) + +#define FL2FXCONST_DBL(val) \ +(FIXP_DBL)( ( (val) >= 0) ? \ +((( (double)(val) * (DFRACT_FIX_SCALE) + 0.5 ) >= (double)(MAXVAL_DBL) ) ? (LONG)(MAXVAL_DBL) : (LONG)( (double)(val) * (double)(DFRACT_FIX_SCALE) + 0.5)) : \ +((( (double)(val) * (DFRACT_FIX_SCALE) - 0.5) <= (double)(MINVAL_DBL_CONST) ) ? (LONG)(MINVAL_DBL_CONST) : (LONG)( (double)(val) * (double)(DFRACT_FIX_SCALE) - 0.5)) ) + +/* macros for runtime conversion of float values to integer fixedpoint. NO OVERFLOW CHECK!!! */ +#define FL2FX_SPC FL2FX_DBL +#define FL2FX_SGL(val) ( (val)>0.0f ? (SHORT)( (val)*(float)(FRACT_FIX_SCALE)+0.5f ) : (SHORT)( (val)*(float)(FRACT_FIX_SCALE)-0.5f ) ) +#define FL2FX_DBL(val) ( (val)>0.0f ? (LONG)( (val)*(float)(DFRACT_FIX_SCALE)+0.5f ) : (LONG)( (val)*(float)(DFRACT_FIX_SCALE)-0.5f ) ) + +/* macros for runtime conversion of fixedpoint values to other fixedpoint. NO ROUNDING!!! */ +#define FX_ACC2FX_SGL(val) ((FIXP_SGL)((val)>>(ACCU_BITS-FRACT_BITS))) +#define FX_ACC2FX_DBL(val) ((FIXP_DBL)((val)>>(ACCU_BITS-DFRACT_BITS))) +#define FX_SGL2FX_ACC(val) ((FIXP_ACC)((LONG)(val)<<(ACCU_BITS-FRACT_BITS))) +#define FX_SGL2FX_DBL(val) ((FIXP_DBL)((LONG)(val)<<(DFRACT_BITS-FRACT_BITS))) +#define FX_DBL2FX_SGL(val) ((FIXP_SGL)((val)>>(DFRACT_BITS-FRACT_BITS))) + +/* ############################################################# */ + +/* macros for runtime conversion of integer fixedpoint values to float. */ +/* This is just for temporary use and should not be required in a final version! */ + +/* #define FX_DBL2FL(val) ((float)(pow(2.,-31.)*(float)val)) */ /* version #1 */ +#define FX_DBL2FL(val) ((float)((double)(val)/(double)DFRACT_FIX_SCALE)) /* version #2 - identical to class dfract cast from dfract to float */ + +/* ############################################################# */ +#include "fixmul.h" + +FDK_INLINE LONG fMult(SHORT a, SHORT b) { return fixmul_SS(a, b); } +FDK_INLINE LONG fMult(SHORT a, LONG b) { return fixmul_SD(a, b); } +FDK_INLINE LONG fMult(LONG a, SHORT b) { return fixmul_DS(a, b); } +FDK_INLINE LONG fMult(LONG a, LONG b) { return fixmul_DD(a, b); } +FDK_INLINE LONG fPow2(LONG a) { return fixpow2_D(a); } +FDK_INLINE LONG fPow2(SHORT a) { return fixpow2_S(a); } + +FDK_INLINE INT fMultI(LONG a, SHORT b) { return ( (INT)(((1<<(FRACT_BITS-2)) + + fixmuldiv2_DD(a,((INT)b<<FRACT_BITS)))>>(FRACT_BITS-1)) ); } + +FDK_INLINE INT fMultIfloor(LONG a, INT b) { return ( (INT)((1 + + fixmuldiv2_DD(a,(b<<FRACT_BITS))) >> (FRACT_BITS-1)) ); } + +FDK_INLINE INT fMultIceil(LONG a, INT b) { return ( (INT)(((INT)0x7fff + + fixmuldiv2_DD(a,(b<<FRACT_BITS))) >> (FRACT_BITS-1)) ); } + +FDK_INLINE LONG fMultDiv2(SHORT a, SHORT b) { return fixmuldiv2_SS(a, b); } +FDK_INLINE LONG fMultDiv2(SHORT a, LONG b) { return fixmuldiv2_SD(a, b); } +FDK_INLINE LONG fMultDiv2(LONG a, SHORT b) { return fixmuldiv2_DS(a, b); } +FDK_INLINE LONG fMultDiv2(LONG a, LONG b) { return fixmuldiv2_DD(a, b); } +FDK_INLINE LONG fPow2Div2(LONG a) { return fixpow2div2_D(a); } +FDK_INLINE LONG fPow2Div2(SHORT a) { return fixpow2div2_S(a); } + +FDK_INLINE LONG fMultDiv2BitExact(LONG a, LONG b) { return fixmuldiv2BitExact_DD(a, b); } +FDK_INLINE LONG fMultDiv2BitExact(SHORT a, LONG b) { return fixmuldiv2BitExact_SD(a, b); } +FDK_INLINE LONG fMultDiv2BitExact(LONG a, SHORT b) { return fixmuldiv2BitExact_DS(a, b); } +FDK_INLINE LONG fMultBitExact(LONG a, LONG b) { return fixmulBitExact_DD(a, b); } +FDK_INLINE LONG fMultBitExact(SHORT a, LONG b) { return fixmulBitExact_SD(a, b); } +FDK_INLINE LONG fMultBitExact(LONG a, SHORT b) { return fixmulBitExact_DS(a, b); } + +/* ******************************************************************************** */ +#include "abs.h" + +FDK_INLINE FIXP_DBL fAbs(FIXP_DBL x) + { return fixabs_D(x); } +FDK_INLINE FIXP_SGL fAbs(FIXP_SGL x) + { return fixabs_S(x); } + +/* workaround for TI C6x compiler but not for TI ARM9E compiler */ +#if (!defined(__TI_COMPILER_VERSION__) || defined(__TI_TMS470_V5__)) && !defined(__x86_64__) +FDK_INLINE INT fAbs(INT x) + { return fixabs_I(x); } +#endif + +/* ******************************************************************************** */ + +#include "clz.h" + +FDK_INLINE INT fNormz(FIXP_DBL x) + { return fixnormz_D(x); } +FDK_INLINE INT fNormz(FIXP_SGL x) + { return fixnormz_S(x); } +FDK_INLINE INT fNorm(FIXP_DBL x) + { return fixnorm_D(x); } +FDK_INLINE INT fNorm(FIXP_SGL x) + { return fixnorm_S(x); } + + +/* ******************************************************************************** */ +/* ******************************************************************************** */ +/* ******************************************************************************** */ + +#include "clz.h" +#define fixp_abs(x) fAbs(x) +#define fixMin(a,b) fMin(a,b) +#define fixMax(a,b) fMax(a,b) +#define CntLeadingZeros(x) fixnormz_D(x) +#define CountLeadingBits(x) fixnorm_D(x) + +#include "fixmadd.h" + +/* y = (x+0.5*a*b) */ +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmadddiv2_DD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmadddiv2_SD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmadddiv2_DS(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmadddiv2_SS(x, a, b); } + +FDK_INLINE FIXP_DBL fPow2AddDiv2(FIXP_DBL x, FIXP_DBL a) + { return fixpadddiv2_D(x, a); } +FDK_INLINE FIXP_DBL fPow2AddDiv2(FIXP_DBL x, FIXP_SGL a) + { return fixpadddiv2_S(x, a); } + + +/* y = 2*(x+0.5*a*b) = (2x+a*b) */ +FDK_INLINE FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmadd_DD(x, a, b); } +inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmadd_SD(x, a, b); } +inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmadd_DS(x, a, b); } +inline FIXP_DBL fMultAdd(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmadd_SS(x, a, b); } + +inline FIXP_DBL fPow2Add(FIXP_DBL x, FIXP_DBL a) + { return fixpadd_D(x, a); } +inline FIXP_DBL fPow2Add(FIXP_DBL x, FIXP_SGL a) + { return fixpadd_S(x, a); } + + +/* y = (x-0.5*a*b) */ +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmsubdiv2_DD(x, a, b); } +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmsubdiv2_SD(x, a, b); } +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmsubdiv2_DS(x, a, b); } +inline FIXP_DBL fMultSubDiv2(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmsubdiv2_SS(x, a, b); } + +/* y = 2*(x-0.5*a*b) = (2*x-a*b) */ +FDK_INLINE FIXP_DBL fMultSub(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmsub_DD(x, a, b); } +inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmsub_SD(x, a, b); } +inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmsub_DS(x, a, b); } +inline FIXP_DBL fMultSub(FIXP_DBL x, FIXP_SGL a, FIXP_SGL b) + { return fixmsub_SS(x, a, b); } + +FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmadddiv2BitExact_DD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmadddiv2BitExact_SD(x, a, b); } +FDK_INLINE FIXP_DBL fMultAddDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmadddiv2BitExact_DS(x, a, b); } +FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_DBL b) + { return fixmsubdiv2BitExact_DD(x, a, b); } +FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_SGL a, FIXP_DBL b) + { return fixmsubdiv2BitExact_SD(x, a, b); } +FDK_INLINE FIXP_DBL fMultSubDiv2BitExact(FIXP_DBL x, FIXP_DBL a, FIXP_SGL b) + { return fixmsubdiv2BitExact_DS(x, a, b); } + +#include "fixminmax.h" + +FDK_INLINE FIXP_DBL fMin(FIXP_DBL a, FIXP_DBL b) + { return fixmin_D(a,b); } +FDK_INLINE FIXP_DBL fMax(FIXP_DBL a, FIXP_DBL b) + { return fixmax_D(a,b); } + +FDK_INLINE FIXP_SGL fMin(FIXP_SGL a, FIXP_SGL b) + { return fixmin_S(a,b); } +FDK_INLINE FIXP_SGL fMax(FIXP_SGL a, FIXP_SGL b) + { return fixmax_S(a,b); } + +/* workaround for TI C6x compiler but not for TI ARM9E */ +#if ((!defined(__TI_COMPILER_VERSION__) || defined(__TI_TMS470_V5__)) && !defined(__x86_64__)) || (FIX_FRACT == 1) +FDK_INLINE INT fMax(INT a, INT b) + { return fixmax_I(a,b); } +FDK_INLINE INT fMin(INT a, INT b) + { return fixmin_I(a,b); } +#endif + +inline UINT fMax(UINT a, UINT b) + { return fixmax_UI(a,b); } +inline UINT fMin(UINT a, UINT b) + { return fixmin_UI(a,b); } + +/* Complex data types */ +typedef shouldBeUnion { + /* vector representation for arithmetic */ + struct { + FIXP_SGL re; + FIXP_SGL im; + } v; + /* word representation for memory move */ + LONG w; +} FIXP_SPK; + +typedef shouldBeUnion { + /* vector representation for arithmetic */ + struct { + FIXP_DBL re; + FIXP_DBL im; + } v; + /* word representation for memory move */ + INT64 w; +} FIXP_DPK; + +#include "fixmul.h" +#include "fixmadd.h" +#include "cplx_mul.h" +#include "scale.h" +#include "fixpoint_math.h" + +#endif diff --git a/libFDK/include/cplx_mul.h b/libFDK/include/cplx_mul.h new file mode 100644 index 0000000..42064d4 --- /dev/null +++ b/libFDK/include/cplx_mul.h @@ -0,0 +1,207 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#include "common_fix.h" + +#if !defined(__CPLX_Mult_H__) +#define __CPLX_Mult_H__ + +#if defined(__CC_ARM) || defined(__arm__) || defined(_M_ARM) /* cppp replaced: elif */ +#include "arm/cplx_mul.h" + +#elif defined(__GNUC__) && defined(__mips__) /* cppp replaced: elif */ +#include "mips/cplx_mul.h" + +#endif /* #if defined all cores: bfin, arm, etc. */ + +/* ############################################################################# */ + +/* Fallback generic implementations */ + +#if !defined(FUNCTION_cplxMultDiv2_32x16X2) +#define FUNCTION_cplxMultDiv2_32x16X2 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re = fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im = fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultDiv2_32x16) +#define FUNCTION_cplxMultDiv2_32x16 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SPK w ) +{ + cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +#if !defined(FUNCTION_cplxMultAddDiv2_32x16X2) +#define FUNCTION_cplxMultAddDiv2_32x16X2 + +inline void cplxMultAddDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re += fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im += fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultSubDiv2_32x16X2) +#define FUNCTION_cplxMultSubDiv2_32x16X2 + +inline void cplxMultSubDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re -= fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im -= fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultDiv2_32x32X2) +#define FUNCTION_cplxMultDiv2_32x32X2 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + *c_Re = fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im = fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMultDiv2_32x32) +#define FUNCTION_cplxMultDiv2_32x32 + +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DPK w) +{ + cplxMultDiv2(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +#if !defined(FUNCTION_cplxMultSubDiv2_32x32X2) +#define FUNCTION_cplxMultSubDiv2_32x32X2 + +inline void cplxMultSubDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + *c_Re -= fMultDiv2(a_Re,b_Re) - fMultDiv2(a_Im,b_Im); + *c_Im -= fMultDiv2(a_Re,b_Im) + fMultDiv2(a_Im,b_Re); +} +#endif + +/* ############################################################################# */ + +#if !defined(FUNCTION_cplxMult_32x16X2) +#define FUNCTION_cplxMult_32x16X2 + +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SGL b_Re, + const FIXP_SGL b_Im) +{ + *c_Re = fMult(a_Re,b_Re) - fMult(a_Im,b_Im); + *c_Im = fMult(a_Re,b_Im) + fMult(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMult_32x16) +#define FUNCTION_cplxMult_32x16 + +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_SPK w ) +{ + cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +#if !defined(FUNCTION_cplxMult_32x32X2) +#define FUNCTION_cplxMult_32x32X2 + +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DBL b_Re, + const FIXP_DBL b_Im) +{ + *c_Re = fMult(a_Re,b_Re) - fMult(a_Im,b_Im); + *c_Im = fMult(a_Re,b_Im) + fMult(a_Im,b_Re); +} +#endif + +#if !defined(FUNCTION_cplxMult_32x32) +#define FUNCTION_cplxMult_32x32 +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + const FIXP_DBL a_Re, + const FIXP_DBL a_Im, + const FIXP_DPK w) +{ + cplxMult(c_Re, c_Im, a_Re, a_Im, w.v.re, w.v.im); +} +#endif + +/* ############################################################################# */ + +#endif /* __CPLX_Mult_H__ */ + diff --git a/libFDK/include/dct.h b/libFDK/include/dct.h new file mode 100644 index 0000000..3ffacf5 --- /dev/null +++ b/libFDK/include/dct.h @@ -0,0 +1,85 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2009) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: Library functions to calculate standard DCTs. This will most + likely be replaced by hand-optimized functions for the specific + target processor. + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __dct_H +#define __dct_H + + + +#include "common_fix.h" + +/** + * \brief Calculate DCT type II of given length. The DCT IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * A factor of sqrt(2/(N-1)) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dct_II(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e); + +/** + * \brief Calculate DCT type III of given length. The DCT IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * Note that the factor 0.5 for the sum term x[0] is 1.0 instead of 0.5. + * A factor of sqrt(2/N) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dct_III(FIXP_DBL *pDat, FIXP_DBL *tmp, int size, int *pDat_e); + +/** + * \brief Calculate DCT type IV of given length. The DCT IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * A factor of sqrt(2/N) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dct_IV(FIXP_DBL *pDat,int size, int *pDat_e); + +/** + * \brief Calculate DST type IV of given length. The DST IV is + * calculated by a complex FFT, with some pre and post twiddeling. + * A factor of sqrt(2/N) is NOT applied. + * \param pDat pointer to input/output data (in place processing). + * \param size size of pDat. + * \param pDat_e pointer to an integer containing the exponent of the data + * referenced by pDat. The exponent is updated accordingly. + */ +void dst_IV(FIXP_DBL *pDat,int size, int *pDat_e); + + + +#endif diff --git a/libFDK/include/fft.h b/libFDK/include/fft.h new file mode 100644 index 0000000..95e7a05 --- /dev/null +++ b/libFDK/include/fft.h @@ -0,0 +1,191 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2001) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Josef Hoepfl, DSP Solutions + Description: Fix point FFT + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __FFT_H__ +#define __FFT_H__ + +#include "common_fix.h" + +/** + * \brief Perform an inplace complex valued FFT of length 2^n + * + * \param length Length of the FFT to be calculated. + * \param pInput Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param scalefactor Pointer to an INT, which contains the current scale of the input data, + * which is updated according to the FFT scale. + */ +void fft(int length, FIXP_DBL *pInput, INT *scalefactor); + +/** + * \brief Perform an inplace complex valued IFFT of length 2^n + * + * \param length Length of the FFT to be calculated. + * \param pInput Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param scalefactor Pointer to an INT, which contains the current scale of the input data, + * which is updated according to the IFFT scale. + */ +void ifft(int length, FIXP_DBL *pInput, INT *scalefactor); + + +/* + * Frequently used and fixed short length FFTs. + */ + +LNK_SECTION_CODE_L1 +static void FORCEINLINE fft_4(FIXP_DBL *x) +{ + FIXP_DBL a00, a10, a20, a30, tmp0, tmp1; + + a00 = (x[0] + x[4])>>1; /* Re A + Re B */ + a10 = (x[2] + x[6])>>1; /* Re C + Re D */ + a20 = (x[1] + x[5])>>1; /* Im A + Im B */ + a30 = (x[3] + x[7])>>1; /* Im C + Im D */ + + x[0] = a00 + a10; /* Re A' = Re A + Re B + Re C + Re D */ + x[1] = a20 + a30; /* Im A' = Im A + Im B + Im C + Im D */ + + tmp0 = a00 - x[4]; /* Re A - Re B */ + tmp1 = a20 - x[5]; /* Im A - Im B */ + + x[4] = a00 - a10; /* Re C' = Re A + Re B - Re C - Re D */ + x[5] = a20 - a30; /* Im C' = Im A + Im B - Im C - Im D */ + + a10 = a10 - x[6]; /* Re C - Re D */ + a30 = a30 - x[7]; /* Im C - Im D */ + + x[2] = tmp0 + a30; /* Re B' = Re A - Re B + Im C - Im D */ + x[6] = tmp0 - a30; /* Re D' = Re A - Re B - Im C + Im D */ + x[3] = tmp1 - a10; /* Im B' = Im A - Im B - Re C + Re D */ + x[7] = tmp1 + a10; /* Im D' = Im A - Im B + Re C - Re D */ +} + +LNK_SECTION_CODE_L1 +static void FORCEINLINE fft_8(FIXP_DBL *x) +{ + #define W_PiFOURTH STC(0x5a82799a) + + FIXP_DBL a00, a10, a20, a30; + FIXP_DBL y[16]; + + a00 = (x[0] + x[8])>>1; + a10 = x[4] + x[12]; + a20 = (x[1] + x[9])>>1; + a30 = x[5] + x[13]; + + y[0] = a00 + (a10>>1); + y[4] = a00 - (a10>>1); + y[1] = a20 + (a30>>1); + y[5] = a20 - (a30>>1); + + a00 = a00 - x[8]; + a10 = (a10>>1) - x[12]; + a20 = a20 - x[9]; + a30 = (a30>>1) - x[13]; + + y[2] = a00 + a30; + y[6] = a00 - a30; + y[3] = a20 - a10; + y[7] = a20 + a10; + + a00 = (x[2] + x[10])>>1; + a10 = x[6] + x[14]; + a20 = (x[3] + x[11])>>1; + a30 = x[7] + x[15]; + + y[8] = a00 + (a10>>1); + y[12] = a00 - (a10>>1); + y[9] = a20 + (a30>>1); + y[13] = a20 - (a30>>1); + + a00 = a00 - x[10]; + a10 = (a10>>1) - x[14]; + a20 = a20 - x[11]; + a30 = (a30>>1) - x[15]; + + y[10] = a00 + a30; + y[14] = a00 - a30; + y[11] = a20 - a10; + y[15] = a20 + a10; + + FIXP_DBL vr, vi, ur, ui; + + ur = y[0]>>1; + ui = y[1]>>1; + vr = y[8]; + vi = y[9]; + x[0] = ur + (vr>>1); + x[1] = ui + (vi>>1); + x[8] = ur - (vr>>1); + x[9] = ui - (vi>>1); + + ur = y[4]>>1; + ui = y[5]>>1; + vi = y[12]; + vr = y[13]; + x[4] = ur + (vr>>1); + x[5] = ui - (vi>>1); + x[12] = ur - (vr>>1); + x[13] = ui + (vi>>1); + + ur = y[10]; + ui = y[11]; + vr = fMultDiv2(ui+ur,W_PiFOURTH); + vi = fMultDiv2(ui-ur,W_PiFOURTH); + ur = y[2]; + ui = y[3]; + x[2] = (ur>>1) + vr; + x[3] = (ui>>1) + vi; + x[10] = (ur>>1) - vr; + x[11] = (ui>>1) - vi; + + ur = y[14]; + ui = y[15]; + vr = fMultDiv2(ui-ur,W_PiFOURTH); + vi = fMultDiv2(ui+ur,W_PiFOURTH); + ur = y[6]; + ui = y[7]; + x[6] = (ur>>1) + vr; + x[7] = (ui>>1) - vi; + x[14] = (ur>>1) - vr; + x[15] = (ui>>1) + vi; +} + +/** + * \brief FFT of fixed length 16 + */ +inline void fft_16(FIXP_DBL *x); + +/** + * \brief FFT of fixed length 32 + */ +inline void fft_32(FIXP_DBL *x); + + +#endif diff --git a/libFDK/include/fft_rad2.h b/libFDK/include/fft_rad2.h new file mode 100644 index 0000000..07efc83 --- /dev/null +++ b/libFDK/include/fft_rad2.h @@ -0,0 +1,72 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2003) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser, M. Gayer + Description: + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef _FFT_RAD2_H +#define _FFT_RAD2_H + + +#include "common_fix.h" + +/** + * \brief Performe an inplace complex valued FFT of 2^n length + * + * \param x Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param ldn log2 of FFT length + * \param trigdata Pointer to a sinetable of a length of at least (2^ldn)/2 sine values. + * \param trigDataSize length of the sinetable "trigdata". + */ +void dit_fft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata, const INT trigDataSize) ; + +/** + * \brief Performe an inplace complex valued inverse FFT of 2^n length + * + * \param x Input/Output data buffer. The input data must have at least 1 bit scale headroom. + * The values are interleaved, real/imag pairs. + * \param ldn log2 of FFT length + * \param trigdata Pointer to a sinetable of a length of at least (2^ldn)/2 sine values. + * \param trigDataSize length of the sinetable "trigdata". + */ +void dit_ifft(FIXP_DBL *x, const INT ldn, const FIXP_STP *trigdata, const INT trigDataSize) ; + +/* Rest of the world. */ + +#define SCALEFACTOR2048 10 +#define SCALEFACTOR1024 9 +#define SCALEFACTOR512 8 +#define SCALEFACTOR256 7 +#define SCALEFACTOR128 6 +#define SCALEFACTOR64 5 +#define SCALEFACTOR32 4 +#define SCALEFACTOR16 3 +#define SCALEFACTOR8 2 +#define SCALEFACTOR4 1 +#define SCALEFACTOR2 1 + +#endif /* _FFT_RAD2_H */ + diff --git a/libFDK/include/fixmadd.h b/libFDK/include/fixmadd.h new file mode 100644 index 0000000..65591a7 --- /dev/null +++ b/libFDK/include/fixmadd.h @@ -0,0 +1,244 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2003) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser, M. Gayer + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#if !defined(__FIXMADD_H__) +#define __FIXMADD_H__ + +#include "FDK_archdef.h" +#include "machine_type.h" +#include "fixmul.h" + +#if defined(__arm__) +#include "arm/fixmadd_arm.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/fixmadd_mips.h" + +#endif /* all cores */ + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions. +************************************************************************** +**************************************************************************/ + +/* Divide by two versions. */ + +#if !defined(FUNCTION_fixmadddiv2_DD) +inline FIXP_DBL fixmadddiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return (x + fMultDiv2 (a, b)); } +#endif + +#if !defined(FUNCTION_fixmadddiv2_SD) +inline FIXP_DBL fixmadddiv2_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmadddiv2_DS + return fixmadddiv2_DS(x, b, a); +#else + return fixmadddiv2_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif + +#if !defined(FUNCTION_fixmadddiv2_DS) +inline FIXP_DBL fixmadddiv2_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmadddiv2_SD + return fixmadddiv2_SD(x, b, a); +#else + return fixmadddiv2_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif + +#if !defined(FUNCTION_fixmadddiv2_SS) +inline FIXP_DBL fixmadddiv2_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return x + fMultDiv2(a,b); } +#endif + +#if !defined(FUNCTION_fixmsubdiv2_DD) +inline FIXP_DBL fixmsubdiv2_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return (x - fMultDiv2 (a, b)); } +#endif + +#if !defined(FUNCTION_fixmsubdiv2_SD) +inline FIXP_DBL fixmsubdiv2_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmsubdiv2_DS + return fixmsubdiv2_DS(x, b, a); +#else + return fixmsubdiv2_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif + +#if !defined(FUNCTION_fixmsubdiv2_DS) +inline FIXP_DBL fixmsubdiv2_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmsubdiv2_SD + return fixmsubdiv2_SD(x, b, a); +#else + return fixmsubdiv2_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif + +#if !defined(FUNCTION_fixmsubdiv2_SS) +inline FIXP_DBL fixmsubdiv2_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return x - fMultDiv2(a,b); } +#endif + + +#if !defined(FUNCTION_fixmadddiv2BitExact_DD) +#define FUNCTION_fixmadddiv2BitExact_DD +inline FIXP_DBL fixmadddiv2BitExact_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + return x + fMultDiv2BitExact(a, b); +} +#endif +#if !defined(FUNCTION_fixmadddiv2BitExact_SD) +#define FUNCTION_fixmadddiv2BitExact_SD +inline FIXP_DBL fixmadddiv2BitExact_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmadddiv2BitExact_DS + return fixmadddiv2BitExact_DS(x, b, a); +#else + return x + fMultDiv2BitExact(a, b); +#endif +} +#endif +#if !defined(FUNCTION_fixmadddiv2BitExact_DS) +#define FUNCTION_fixmadddiv2BitExact_DS +inline FIXP_DBL fixmadddiv2BitExact_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmadddiv2BitExact_SD + return fixmadddiv2BitExact_SD(x, b, a); +#else + return x + fMultDiv2BitExact(a, b); +#endif +} +#endif + +#if !defined(FUNCTION_fixmsubdiv2BitExact_DD) +#define FUNCTION_fixmsubdiv2BitExact_DD +inline FIXP_DBL fixmsubdiv2BitExact_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) { + return x - fMultDiv2BitExact(a, b); +} +#endif +#if !defined(FUNCTION_fixmsubdiv2BitExact_SD) +#define FUNCTION_fixmsubdiv2BitExact_SD +inline FIXP_DBL fixmsubdiv2BitExact_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmsubdiv2BitExact_DS + return fixmsubdiv2BitExact_DS(x, b, a); +#else + return x - fMultDiv2BitExact(a, b); +#endif +} +#endif +#if !defined(FUNCTION_fixmsubdiv2BitExact_DS) +#define FUNCTION_fixmsubdiv2BitExact_DS +inline FIXP_DBL fixmsubdiv2BitExact_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmsubdiv2BitExact_SD + return fixmsubdiv2BitExact_SD(x, b, a); +#else + return x - fMultDiv2BitExact(a, b); +#endif +} +#endif + +/* Normal versions */ + +#if !defined(FUNCTION_fixmadd_DD) +inline FIXP_DBL fixmadd_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return fixmadddiv2_DD(x,a,b)<<1; } +#endif +#if !defined(FUNCTION_fixmadd_SD) +inline FIXP_DBL fixmadd_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmadd_DS + return fixmadd_DS(x, b, a); +#else + return fixmadd_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif +#if !defined(FUNCTION_fixmadd_DS) +inline FIXP_DBL fixmadd_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmadd_SD + return fixmadd_SD(x, b, a); +#else + return fixmadd_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif +#if !defined(FUNCTION_fixmadd_SS) +inline FIXP_DBL fixmadd_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return (x + fMultDiv2(a,b))<<1; } +#endif + +#if !defined(FUNCTION_fixmsub_DD) +inline FIXP_DBL fixmsub_DD (FIXP_DBL x, const FIXP_DBL a, const FIXP_DBL b) + { return fixmsubdiv2_DD(x,a,b)<<1; } +#endif +#if !defined(FUNCTION_fixmsub_SD) +inline FIXP_DBL fixmsub_SD (FIXP_DBL x, const FIXP_SGL a, const FIXP_DBL b) { +#ifdef FUNCTION_fixmsub_DS + return fixmsub_DS(x, b, a); +#else + return fixmsub_DD(x, FX_SGL2FX_DBL(a), b); +#endif +} +#endif +#if !defined(FUNCTION_fixmsub_DS) +inline FIXP_DBL fixmsub_DS (FIXP_DBL x, const FIXP_DBL a, const FIXP_SGL b) { +#ifdef FUNCTION_fixmsub_SD + return fixmsub_SD(x, b, a); +#else + return fixmsub_DD(x, a, FX_SGL2FX_DBL(b)); +#endif +} +#endif +#if !defined(FUNCTION_fixmsub_SS) +inline FIXP_DBL fixmsub_SS (FIXP_DBL x, const FIXP_SGL a, const FIXP_SGL b) + { return (x - fMultDiv2(a,b))<<1; } +#endif + +#if !defined(FUNCTION_fixpow2adddiv2_D) +inline INT fixpadddiv2_D (FIXP_DBL x, const FIXP_DBL a) + { return (x + fPow2Div2(a)); } +#endif +#if !defined(FUNCTION_fixpow2add_D) +inline INT fixpadd_D (FIXP_DBL x, const FIXP_DBL a) + { return (x + fPow2(a)); } +#endif + +#if !defined(FUNCTION_fixpow2adddiv2_S) +inline INT fixpadddiv2_S (FIXP_DBL x, const FIXP_SGL a) + { return (x + fPow2Div2(a)); } +#endif +#if !defined(FUNCTION_fixpow2add_S) +inline INT fixpadd_S (FIXP_DBL x, const FIXP_SGL a) + { return (x + fPow2(a)); } +#endif + + + +#endif // __FIXMADD_H__ + diff --git a/libFDK/include/fixminmax.h b/libFDK/include/fixminmax.h new file mode 100644 index 0000000..5bbd53b --- /dev/null +++ b/libFDK/include/fixminmax.h @@ -0,0 +1,58 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Lohwasser, M. Gayer + Description: min/max inline functions and defines + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef FIXMINMAX__H +#define FIXMINMAX__H + +#include "FDK_archdef.h" +#include "machine_type.h" + +/* Inline Function to determine the smaller/bigger value of two values with same type. */ + + +template <class T> inline T fixmin (T a, T b) +{ + return (a < b ? a : b); +} + +template <class T> inline T fixmax (T a, T b) +{ + return (a > b ? a : b); +} + +#define fixmax_D(a,b) fixmax(a,b) +#define fixmin_D(a,b) fixmin(a,b) +#define fixmax_S(a,b) fixmax(a,b) +#define fixmin_S(a,b) fixmin(a,b) +#define fixmax_I(a,b) fixmax(a,b) +#define fixmin_I(a,b) fixmin(a,b) +#define fixmax_UI(a,b) fixmax(a,b) +#define fixmin_UI(a,b) fixmin(a,b) + + +#endif diff --git a/libFDK/include/fixmul.h b/libFDK/include/fixmul.h new file mode 100644 index 0000000..f9f35e2 --- /dev/null +++ b/libFDK/include/fixmul.h @@ -0,0 +1,223 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (1999) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Stefan Gewinner + Description: fixed point multiplication + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if !defined(__FIXMUL_H__) +#define __FIXMUL_H__ + +#include "FDK_archdef.h" +#include "machine_type.h" + + +#if defined(__arm__) +#include "arm/fixmul_arm.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/fixmul_mips.h" + +#elif defined(__x86__) /* cppp replaced: elif */ +#include "x86/fixmul_x86.h" + +#endif /* all cores */ + +/************************************************************************* + ************************************************************************* + Software fallbacks for missing functions +************************************************************************** +**************************************************************************/ + +#if !defined(FUNCTION_fixmuldiv2_DD) +#define FUNCTION_fixmuldiv2_DD +#if defined(_MSC_VER) || defined(__CC_ARM) || defined(__ANALOG_EXTENSIONS__) || defined(__TI_COMPILER_VERSION__) +#pragma message ("Extremely slow implementation of fixmuldiv2_DD !!") +#else +#warning Extremely slow implementation of fixmuldiv2_DD !! +#endif +inline LONG fixmuldiv2_DD (const LONG a, const LONG b) +{ + return (LONG) ((((INT64)a) * b) >> 32) ; +} +#endif + +#if !defined(FUNCTION_fixmuldiv2BitExact_DD) +#define FUNCTION_fixmuldiv2BitExact_DD +#if defined(_MSC_VER) || defined(__CC_ARM) || defined(__ANALOG_EXTENSIONS__) || defined(__TI_COMPILER_VERSION__) +#pragma message ("Extremely slow implementation of fixmuldiv2BitExact_DD !!") +#else +#warning Extremely slow implementation of fixmuldiv2BitExact_DD !! +#endif +inline LONG fixmuldiv2BitExact_DD (const LONG a, const LONG b) +{ + return (LONG) ((((INT64)a) * b) >> 32) ; +} +#endif + +#if !defined(FUNCTION_fixmul_DD) +#define FUNCTION_fixmul_DD +inline LONG fixmul_DD (const LONG a, const LONG b) + { return fixmuldiv2_DD (a, b) << 1 ; } +#endif + +#if !defined(FUNCTION_fixmulBitExact_DD) +#define FUNCTION_fixmulBitExact_DD +#if defined(_MSC_VER) || defined(__CC_ARM) || defined(__ANALOG_EXTENSIONS__) || defined(__TI_COMPILER_VERSION__) || defined(__XTENSA__) +#pragma message ("Extremely slow implementation of fixmulBitExact_DD !!") +#else +#warning Extremely slow implementation of fixmulBitExact_DD !! +#endif +inline LONG fixmulBitExact_DD (const LONG a, const LONG b) +{ + return ( (LONG) ((((INT64)a) * b) >> 32) ) << 1; +} +#endif + +#if !defined(FUNCTION_fixmuldiv2_SS) +#define FUNCTION_fixmuldiv2_SS +inline LONG fixmuldiv2_SS (const SHORT a, const SHORT b) + { return ((LONG)a*b); } +#endif + +#if !defined(FUNCTION_fixmul_SS) +#define FUNCTION_fixmul_SS +inline LONG fixmul_SS (const SHORT a, const SHORT b) + { return (a*b) <<1; } +#endif + +#if !defined(FUNCTION_fixmuldiv2_SD) +#define FUNCTION_fixmuldiv2_SD +inline LONG fixmuldiv2_SD (const SHORT a, const LONG b) +#ifdef FUNCTION_fixmuldiv2_DS + { return fixmuldiv2_DS(b, a); } +#else + { return fixmuldiv2_DD(FX_SGL2FX_DBL(a), b); } +#endif +#endif + +#if !defined(FUNCTION_fixmuldiv2_DS) +#define FUNCTION_fixmuldiv2_DS +inline LONG fixmuldiv2_DS (const LONG a, const SHORT b) +#ifdef FUNCTION_fixmuldiv2_SD + { return fixmuldiv2_SD(b, a); } +#else + { return fixmuldiv2_DD(a, FX_SGL2FX_DBL(b)); } +#endif +#endif + +#if !defined(FUNCTION_fixmuldiv2BitExact_SD) +#define FUNCTION_fixmuldiv2BitExact_SD +inline LONG fixmuldiv2BitExact_SD (const SHORT a, const LONG b) +#ifdef FUNCTION_fixmuldiv2BitExact_DS + { return fixmuldiv2BitExact_DS(b, a); } +#else + { return (LONG) ((((INT64)a) * b) >> 16) ; } +#endif +#endif + +#if !defined(FUNCTION_fixmuldiv2BitExact_DS) +#define FUNCTION_fixmuldiv2BitExact_DS +inline LONG fixmuldiv2BitExact_DS (const LONG a, const SHORT b) +#ifdef FUNCTION_fixmuldiv2BitExact_SD + { return fixmuldiv2BitExact_SD(b, a); } +#else + { return (LONG) ((((INT64)a) * b) >> 16) ; } +#endif +#endif + +#if !defined(FUNCTION_fixmul_SD) +#define FUNCTION_fixmul_SD +inline LONG fixmul_SD (const SHORT a, const LONG b) { +#ifdef FUNCTION_fixmul_DS + return fixmul_SD(b, a); +#else + return fixmuldiv2_SD (a, b) << 1 ; +#endif +} +#endif + +#if !defined(FUNCTION_fixmul_DS) +#define FUNCTION_fixmul_DS +inline LONG fixmul_DS (const LONG a, const SHORT b) { +#ifdef FUNCTION_fixmul_SD + return fixmul_SD(b, a); +#else + return fixmuldiv2_DS(a, b) << 1 ; +#endif +} +#endif + +#if !defined(FUNCTION_fixmulBitExact_SD) +#define FUNCTION_fixmulBitExact_SD +inline LONG fixmulBitExact_SD (const SHORT a, const LONG b) +#ifdef FUNCTION_fixmulBitExact_DS + { return fixmulBitExact_DS(b, a); } +#else + { return (LONG) (((((INT64)a) * b) >> 16) << 1); } +#endif +#endif + +#if !defined(FUNCTION_fixmulBitExact_DS) +#define FUNCTION_fixmulBitExact_DS +inline LONG fixmulBitExact_DS (const LONG a, const SHORT b) +#ifdef FUNCTION_fixmulBitExact_SD + { return fixmulBitExact_SD(b, a); } +#else + { return (LONG) (((((INT64)a) * b) >> 16) << 1); } +#endif +#endif + + +#if !defined(FUNCTION_fixpow2div2_D) +#ifdef ARCH_WA_16BITMULT +#error Fallback for fixpow2div2_D is not 16 bit safe ! +#endif +#define FUNCTION_fixpow2div2_D +inline LONG fixpow2div2_D (const LONG a) + { return fixmuldiv2_DD(a, a); } +#endif + +#if !defined(FUNCTION_fixpow2_D) +#ifdef ARCH_WA_16BITMULT +#error Fallback for fixpow2_D is not 16 bit safe ! +#endif +#define FUNCTION_fixpow2_D +inline LONG fixpow2_D (const LONG a) + { return fixpow2div2_D(a)<<1; } +#endif + +#if !defined(FUNCTION_fixpow2div2_S) +#define FUNCTION_fixpow2div2_S +inline LONG fixpow2div2_S (const SHORT a) + { return fixmuldiv2_SS(a, a); } +#endif + +#if !defined(FUNCTION_fixpow2_S) +#define FUNCTION_fixpow2_S +inline LONG fixpow2_S (const SHORT a) + { return fixpow2div2_S(a)<<1; } +#endif + + +#endif /* __FIXMUL_H__ */ diff --git a/libFDK/include/fixpoint_math.h b/libFDK/include/fixpoint_math.h new file mode 100644 index 0000000..0d0a059 --- /dev/null +++ b/libFDK/include/fixpoint_math.h @@ -0,0 +1,397 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (1999) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): M. Gayer + Description: Fixed point specific mathematical functions + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __fixpoint_math_H +#define __fixpoint_math_H + + +#include "common_fix.h" + + +#define LD_DATA_SCALING (64.0f) +#define LD_DATA_SHIFT 6 /* pow(2, LD_DATA_SHIFT) = LD_DATA_SCALING */ +/*#define SIMULATE_MIPS_DIV */ /* schur_div() in C that simulates the inline asm schur_div() on MIPS */ + +/** + * \brief deprecated. Use fLog2() instead. + */ +FIXP_DBL CalcLdData(FIXP_DBL op); + +void LdDataVector(FIXP_DBL *srcVector, FIXP_DBL *destVector, INT number); + +FIXP_DBL CalcInvLdData(FIXP_DBL op); + + +void InitLdInt(); +FIXP_DBL CalcLdInt(INT i); + +extern const USHORT sqrt_tab[49]; + +inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x) +{ + UINT y = (INT)x; + UCHAR is_zero=(y==0); + INT zeros=fixnormz_D(y) & 0x1e; + y<<=zeros; + UINT idx=(y>>26)-16; + USHORT frac=(y>>10)&0xffff; + USHORT nfrac=0xffff^frac; + UINT t=nfrac*sqrt_tab[idx]+frac*sqrt_tab[idx+1]; + t=t>>(zeros>>1); + return(is_zero ? 0 : t); +} + +inline FIXP_DBL sqrtFixp_lookup(FIXP_DBL x, INT *x_e) +{ + UINT y = (INT)x; + INT e; + + if (x == (FIXP_DBL)0) { + return x; + } + + /* Normalize */ + e=fixnormz_D(y); + y<<=e; + e = *x_e - e + 2; + + /* Correct odd exponent. */ + if (e & 1) { + y >>= 1; + e ++; + } + /* Get square root */ + UINT idx=(y>>26)-16; + USHORT frac=(y>>10)&0xffff; + USHORT nfrac=0xffff^frac; + UINT t=nfrac*sqrt_tab[idx]+frac*sqrt_tab[idx+1]; + + /* Write back exponent */ + *x_e = e >> 1; + return (FIXP_DBL)(LONG)(t>>1); +} + + + +FIXP_DBL sqrtFixp(FIXP_DBL op); + +void InitInvSqrtTab(); + +FIXP_DBL invSqrtNorm2(FIXP_DBL op, INT *shift); + +/***************************************************************************** + + functionname: invFixp + description: delivers 1/(op) + +*****************************************************************************/ +inline FIXP_DBL invFixp(FIXP_DBL op) +{ + INT tmp_exp ; + FIXP_DBL tmp_inv = invSqrtNorm2(op, &tmp_exp) ; + FDK_ASSERT((31-(2*tmp_exp+1))>=0) ; + return ( fPow2Div2( (FIXP_DBL)tmp_inv ) >> (31-(2*tmp_exp+1)) ) ; +} + + + +#if defined(__mips__) && (__GNUC__==2) + +#define FUNCTION_schur_div +inline FIXP_DBL schur_div(FIXP_DBL num,FIXP_DBL denum, INT count) +{ + INT result, tmp ; + __asm__ ("srl %1, %2, 15\n" + "div %3, %1\n" : "=lo" (result) + : "%d" (tmp), "d" (denum) , "d" (num) + : "hi" ) ; + return result<<16 ; +} + +/*###########################################################################################*/ +#elif defined(__mips__) && (__GNUC__==3) + +#define FUNCTION_schur_div +inline FIXP_DBL schur_div(FIXP_DBL num,FIXP_DBL denum, INT count) +{ + INT result, tmp; + + __asm__ ("srl %[tmp], %[denum], 15\n" + "div %[result], %[num], %[tmp]\n" + : [tmp] "+r" (tmp), [result]"=r"(result) + : [denum]"r"(denum), [num]"r"(num) + : "hi", "lo"); + return result << (DFRACT_BITS-16); +} + +/*###########################################################################################*/ +#elif defined(SIMULATE_MIPS_DIV) + +#define FUNCTION_schur_div +inline FIXP_DBL schur_div(FIXP_DBL num, FIXP_DBL denum, INT count) +{ + FDK_ASSERT (count<=DFRACT_BITS-1); + FDK_ASSERT (num>=(FIXP_DBL)0); + FDK_ASSERT (denum>(FIXP_DBL)0); + FDK_ASSERT (num <= denum); + + INT tmp = denum >> (count-1); + INT result = 0; + + while (num > tmp) + { + num -= tmp; + result++; + } + + return result << (DFRACT_BITS-count); +} + +/*###########################################################################################*/ +#endif /* target architecture selector */ + +#if !defined(FUNCTION_schur_div) +/** + * \brief Divide two FIXP_DBL values with given precision. + * \param num dividend + * \param denum divisor + * \param count amount of significant bits of the result (starting to the MSB) + * \return num/divisor + */ +FIXP_DBL schur_div(FIXP_DBL num,FIXP_DBL denum, INT count); +#endif + + + +FIXP_DBL mul_dbl_sgl_rnd (const FIXP_DBL op1, + const FIXP_SGL op2); + +/** + * \brief multiply two values with normalization, thus max precision. + * Author: Robert Weidner + * + * \param f1 first factor + * \param f2 secod factor + * \param result_e pointer to an INT where the exponent of the result is stored into + * \return mantissa of the product f1*f2 + */ +FIXP_DBL fMultNorm( + FIXP_DBL f1, + FIXP_DBL f2, + INT *result_e + ); + +/** + * \brief Divide 2 FIXP_DBL values with normalization of input values. + * \param num numerator + * \param denum denomintator + * \return num/denum with exponent = 0 + */ +FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom, INT *result_e); + +/** + * \brief Divide 2 FIXP_DBL values with normalization of input values. + * \param num numerator + * \param denum denomintator + * \param result_e pointer to an INT where the exponent of the result is stored into + * \return num/denum with exponent = *result_e + */ +FIXP_DBL fDivNorm(FIXP_DBL num, FIXP_DBL denom); + +/** + * \brief Divide 2 FIXP_DBL values with normalization of input values. + * \param num numerator + * \param denum denomintator + * \return num/denum with exponent = 0 + */ +FIXP_DBL fDivNormHighPrec(FIXP_DBL L_num, FIXP_DBL L_denum, INT *result_e); + +/** + * \brief Calculate log(argument)/log(2) (logarithm with base 2). deprecated. Use fLog2() instead. + * \param arg mantissa of the argument + * \param arg_e exponent of the argument + * \param result_e pointer to an INT to store the exponent of the result + * \return the mantissa of the result. + * \param + */ +FIXP_DBL CalcLog2(FIXP_DBL arg, INT arg_e, INT *result_e); + +/** + * \brief return 2 ^ (exp * 2^exp_e) + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \param result_e pointer to a INT where the exponent of the result will be stored into + * \return mantissa of the result + */ +FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e, INT *result_e); + +/** + * \brief return 2 ^ (exp_m * 2^exp_e). This version returns only the mantissa with implicit exponent of zero. + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \return mantissa of the result + */ +FIXP_DBL f2Pow(const FIXP_DBL exp_m, const INT exp_e); + +/** + * \brief return x ^ (exp * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e). This saves + * the need to compute log2() of constant values (when x is a constant). + * \param ldx_m mantissa of log2() of x. + * \param ldx_e exponent of log2() of x. + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \param result_e pointer to a INT where the exponent of the result will be stored into + * \return mantissa of the result + */ +FIXP_DBL fLdPow( + FIXP_DBL baseLd_m, + INT baseLd_e, + FIXP_DBL exp_m, INT exp_e, + INT *result_e + ); + +/** + * \brief return x ^ (exp * 2^exp_e), where log2(x) = baseLd_m * 2^(baseLd_e). This saves + * the need to compute log2() of constant values (when x is a constant). This version + * does not return an exponent, which is implicitly 0. + * \param ldx_m mantissa of log2() of x. + * \param ldx_e exponent of log2() of x. + * \param exp_m mantissa of the exponent to 2.0f + * \param exp_e exponent of the exponent to 2.0f + * \return mantissa of the result + */ +FIXP_DBL fLdPow( + FIXP_DBL baseLd_m, INT baseLd_e, + FIXP_DBL exp_m, INT exp_e + ); + +/** + * \brief return (base * 2^base_e) ^ (exp * 2^exp_e). Use fLdPow() instead whenever possible. + * \param base_m mantissa of the base. + * \param base_e exponent of the base. + * \param exp_m mantissa of power to be calculated of the base. + * \param exp_e exponent of power to be calculated of the base. + * \param result_e pointer to a INT where the exponent of the result will be stored into. + * \return mantissa of the result. + */ +FIXP_DBL fPow(FIXP_DBL base_m, INT base_e, FIXP_DBL exp_m, INT exp_e, INT *result_e); + +/** + * \brief return (base * 2^base_e) ^ N + * \param base mantissa of the base + * \param base_e exponent of the base + * \param power to be calculated of the base + * \param result_e pointer to a INT where the exponent of the result will be stored into + * \return mantissa of the result + */ +FIXP_DBL fPowInt(FIXP_DBL base_m, INT base_e, INT N, INT *result_e); + +/** + * \brief calculate logarithm of base 2 of x_m * 2^(x_e) + * \param x_m mantissa of the input value. + * \param x_e exponent of the input value. + * \param pointer to an INT where the exponent of the result is returned into. + * \return mantissa of the result. + */ +FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e, INT *result_e); + +/** + * \brief calculate logarithm of base 2 of x_m * 2^(x_e) + * \param x_m mantissa of the input value. + * \param x_e exponent of the input value. + * \return mantissa of the result with implicit exponent of LD_DATA_SHIFT. + */ +FIXP_DBL fLog2(FIXP_DBL x_m, INT x_e); + +/** + * \brief Add with saturation of the result. + * \param a first summand + * \param b second summand + * \return saturated sum of a and b. + */ +inline FIXP_SGL fAddSaturate(const FIXP_SGL a, const FIXP_SGL b) +{ + LONG sum; + + sum = (LONG)(SHORT)a + (LONG)(SHORT)b; + sum = fMax(fMin((INT)sum, (INT)MAXVAL_SGL), (INT)MINVAL_SGL); + return (FIXP_SGL)(SHORT)sum; +} + +/** + * \brief Add with saturation of the result. + * \param a first summand + * \param b second summand + * \return saturated sum of a and b. + */ +inline FIXP_DBL fAddSaturate(const FIXP_DBL a, const FIXP_DBL b) +{ + LONG sum; + + sum = (LONG)(a>>1) + (LONG)(b>>1); + sum = fMax(fMin((INT)sum, (INT)(MAXVAL_DBL>>1)), (INT)(MINVAL_DBL>>1)); + return (FIXP_DBL)(LONG)(sum<<1); +} + +#define TEST_ROUNDING 0 + + +#if TEST_ROUNDING +void checkRound(); +void checkRound2(); +#endif + + +/***************************************************************************** + + array for 1/n, n=1..50 + +****************************************************************************/ + + extern const FIXP_DBL invCount[50]; + + LNK_SECTION_INITCODE + inline void InitInvInt(void) {} + + +/** + * \brief Calculate the value of 1/i where i is a integer value. It supports + * input values from 1 upto 50. + * \param intValue Integer input value. + * \param FIXP_DBL representation of 1/intValue + */ +inline FIXP_DBL GetInvInt(int intValue) +{ + FDK_ASSERT((intValue > 0) && (intValue < 50)); + FDK_ASSERT(intValue<50); + return invCount[intValue]; +} + + +#endif + diff --git a/libFDK/include/mdct.h b/libFDK/include/mdct.h new file mode 100644 index 0000000..f96ea06 --- /dev/null +++ b/libFDK/include/mdct.h @@ -0,0 +1,181 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2011) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): Manuel Jander, Josef Hoepfl + Description: MDCT routines + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef __MDCT_H__ +#define __MDCT_H__ + + + +#include "common_fix.h" + +#define MDCT_OUT_HEADROOM 2 /* Output additional headroom */ +#define MDCT_OUTPUT_SCALE (DFRACT_BITS-SAMPLE_BITS-MDCT_OUT_HEADROOM) +/* Refer to "Output word length" in ISO/IEC 14496-3:2008(E) 23.2.3.6 */ +#define MDCT_OUTPUT_GAIN 16 + +#if (SAMPLE_BITS == DFRACT_BITS) +#define IMDCT_SCALE(x) (INT_PCM)SATURATE_LEFT_SHIFT(x, -MDCT_OUTPUT_SCALE, SAMPLE_BITS) +#else +#define IMDCT_SCALE(x) (INT_PCM)SATURATE_RIGHT_SHIFT(x, MDCT_OUTPUT_SCALE, SAMPLE_BITS) +#endif +#define IMDCT_SCALE_DBL(x) (FIXP_DBL)(x) + +/** + * \brief MDCT persistent data + */ +typedef struct { + union { + FIXP_DBL *freq; + FIXP_DBL *time; + } overlap; /**< Pointer to overlap memory */ + + const FIXP_WTP *prev_wrs; /**< pointer to previous right window slope */ + int prev_tl; /**< previous tranform length */ + int prev_nr; /**< previous right window offset */ + int prev_fr; /**< previous right window slope length */ + int ov_offset; /**< overlap time data fill level */ + int ov_size; /**< Overlap buffer size in words */ + +} mdct_t; + +typedef mdct_t* H_MDCT; + +/** + * \brief Initialize as valid MDCT handle + * + * \param hMdct handle of an allocated MDCT handle. + * \param overlap pointer to FIXP_DBL overlap buffer. + * \param overlapBufferSize size in FIXP_DBLs of the given overlap buffer. + * \return void + */ +void mdct_init( H_MDCT hMdct, + FIXP_DBL *overlap, + INT overlapBufferSize ); + +/** + * \brief perform MDCT transform (time domain to frequency domain) with given parameters. + * + * \param hMdct handle of an allocated MDCT handle. + * \param spectrum pointer to where the resulting MDCT spectrum will be stored into. + * \param scalefactor pointer to the input scale shift value. Updated accordingly on return. + * \param input pointer to input time domain signal + * \param tl transformation length. + * \param nr right window slope offset (amount of window coefficients assumed to be 1.0) + * \param fr right overlap window slope length + * \param wrs pointer to the right side overlap window coefficients. + * \return number of input samples processed. + */ +INT mdct_block( + H_MDCT hMdct, + FIXP_DBL *spectrum, + INT *scalefactor, + INT_PCM *input, + INT tl, + INT nr, + INT fr, + const FIXP_WTB *wrs ); + + +/** + * \brief add/multiply 2/N transform gain and MPEG4 part 3 defined output gain (see definition + * of MDCT_OUTPUT_GAIN) to given mantissa factor and exponent. + * \param pGain pointer to the mantissa of a gain factor to be applied to IMDCT data. + * \param pExponent pointer to the exponent of a gain factor to be applied to IMDCT data. + * \param tl length of the IMDCT where the gain *pGain * (2 ^ *pExponent) will be applied to. + */ +void imdct_gain( + FIXP_DBL *pGain, + int *pExponent, + int tl + ); + +/** + * \brief drain buffered output samples into given buffer. Changes the MDCT state. + */ +INT imdct_drain( + H_MDCT hMdct, + FIXP_DBL * pTimeData, + INT nrSamplesRoom + ); + + +/** + * \brief Copy overlap time domain data to given buffer. Does not change the MDCT state. + * \return number of actually copied samples (ov + nr). + */ +INT imdct_copy_ov_and_nr( + H_MDCT hMdct, + FIXP_DBL * pTimeData, + INT nrSamples + ); + +/** + * \brief Adapt MDCT parameters for non-matching window slopes. + * \param hMdct handle of an allocated MDCT handle. + * \param pfl pointer to left overlap window side length. + * \param pnl pointer to length of the left n part of the window. + * \param tl transform length. + * \param wls pointer to the left side overlap window coefficients. + * \param noOutSamples desired number of output samples. + */ +void imdct_adapt_parameters(H_MDCT hMdct, int *pfl, int *pnl, int tl, const FIXP_WTP *wls, int noOutSamples); + +/** + * \brief perform several inverse MDCT transforms (frequency domain to time domain) with given parameters. + * + * \param hMdct handle of an allocated MDCT handle. + * \param output pointer to where the output time domain signal will be stored into. + * \param stride the stride factor for accessing time domain samples in output. + * \param spectrum pointer to the input MDCT spectra. + * \param scalefactors scale shift values of the input spectrum. + * \param nSpec number of MDCT spectrums. + * \param noOutSamples desired number of output samples. + * \param tl transform length. + * \param wls pointer to the left side overlap window coefficients. + * \param fl left overlap window side length. + * \param wrs pointer to the right side overlap window coefficients of all individual IMDCTs. + * \param fr right overlap window side length of all individual IMDCTs. + * \param gain factor to apply to output samples (if != 0). + * \return number of output samples returned. + */ +INT imdct_block( + H_MDCT hMdct, + FIXP_DBL *output, + FIXP_DBL *spectrum, + const SHORT scalefactor[], + const INT nSpec, + const INT noOutSamples, + const INT tl, + const FIXP_WTP *wls, + INT fl, + const FIXP_WTP *wrs, + const INT fr, + FIXP_DBL gain ); + + +#endif /* __MDCT_H__ */ diff --git a/libFDK/include/mips/abs_mips.h b/libFDK/include/mips/abs_mips.h new file mode 100644 index 0000000..92729c5 --- /dev/null +++ b/libFDK/include/mips/abs_mips.h @@ -0,0 +1,44 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__mips__) + +#if defined(__GNUC__) && defined(__mips__) + + #if defined(__mips_dsp) + #define FUNCTION_fixabs_D + #define FUNCTION_fixabs_I + #define FUNCTION_fixabs_S + inline FIXP_DBL fixabs_D(FIXP_DBL x) { return __builtin_mips_absq_s_w(x); } + inline FIXP_SGL fixabs_S(FIXP_SGL x) { return ((x) > (FIXP_SGL)(0)) ? (x) : -(x) ; } + inline INT fixabs_I(INT x) { return __builtin_mips_absq_s_w(x); } + #endif /* __mips_dsp */ + +#endif /* defined(__GNUC__) && defined(__mips__) */ + +#endif /*__mips__ */ + diff --git a/libFDK/include/mips/clz_mips.h b/libFDK/include/mips/clz_mips.h new file mode 100644 index 0000000..23e6949 --- /dev/null +++ b/libFDK/include/mips/clz_mips.h @@ -0,0 +1,55 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__mips__) + +#if defined(__mips__) && (__GNUC__==2) && (mips>=32) + + #define FUNCTION_fixnormz_D + inline INT fixnormz_D(LONG value) + { + INT result; + __asm__ ("clz %0,%1" : "=d" (result) : "d" (value)); + + return result; + } + +#elif defined(__mips__) && (__GNUC__==3) && (__mips>=32) + + #define FUNCTION_fixnormz_D + INT inline fixnormz_D(LONG value) + { + INT result; + __asm__ ("clz %[result], %[value]" : [result] "=r" (result) : [value] "r" (value)) ; + + return result; + } + +#endif + +#endif /* __mips__ */ + diff --git a/libFDK/include/mips/cplx_mul.h b/libFDK/include/mips/cplx_mul.h new file mode 100644 index 0000000..f6f46cc --- /dev/null +++ b/libFDK/include/mips/cplx_mul.h @@ -0,0 +1,93 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + + +#if defined(__GNUC__) && defined(__mips__) + + +//#define FUNCTION_cplxMultDiv2_32x16 +//#define FUNCTION_cplxMultDiv2_32x16X2 +#define FUNCTION_cplxMultDiv2_32x32X2 +//#define FUNCTION_cplxMult_32x16 +//#define FUNCTION_cplxMult_32x16X2 +#define FUNCTION_cplxMult_32x32X2 + +#if defined(FUNCTION_cplxMultDiv2_32x32X2) +inline void cplxMultDiv2( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + FIXP_DBL a_Re, + FIXP_DBL a_Im, + FIXP_DBL b_Re, + FIXP_DBL b_Im) +{ + INT result; + + __asm__ ("mult %[a_Re], %[b_Re];\n" + "msub %[a_Im], %[b_Im];\n" + : "=hi"(result) + : [a_Re]"r"(a_Re), [b_Re]"r"(b_Re), [a_Im]"r"(a_Im), [b_Im]"r"(b_Im) + : "lo"); + + *c_Re = result; + + __asm__ ("mult %[a_Re], %[b_Im];\n" + "madd %[a_Im], %[b_Re];\n" + : "=hi"(result) + : [a_Re]"r"(a_Re), [b_Im]"r"(b_Im), [a_Im]"r"(a_Im), [b_Re]"r"(b_Re) + : "lo"); + *c_Im = result; +} +#endif + +#if defined(FUNCTION_cplxMult_32x32X2) +inline void cplxMult( FIXP_DBL *c_Re, + FIXP_DBL *c_Im, + FIXP_DBL a_Re, + FIXP_DBL a_Im, + FIXP_DBL b_Re, + FIXP_DBL b_Im) +{ + INT result; + __asm__ ("mult %[a_Re], %[b_Re];\n" + "msub %[a_Im], %[b_Im];\n" + : "=hi"(result) + : [a_Re]"r"(a_Re), [b_Re]"r"(b_Re), [a_Im]"r"(a_Im), [b_Im]"r"(b_Im) + : "lo"); + *c_Re = result<<1; + + __asm__ ("mult %[a_Re], %[b_Im];\n" + "madd %[a_Im], %[b_Re];\n" + : "=hi"(result) + : [a_Re]"r"(a_Re), [b_Im]"r"(b_Im), [a_Im]"r"(a_Im), [b_Re]"r"(b_Re) + : "lo"); + *c_Im = result<<1; +} +#endif + +#endif /* defined(__GNUC__) && defined(__mips__) */ + diff --git a/libFDK/include/mips/fixmadd_mips.h b/libFDK/include/mips/fixmadd_mips.h new file mode 100644 index 0000000..4d075ad --- /dev/null +++ b/libFDK/include/mips/fixmadd_mips.h @@ -0,0 +1,32 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__mips__) + + +#endif /* __mips__ */ + diff --git a/libFDK/include/mips/fixmul_mips.h b/libFDK/include/mips/fixmul_mips.h new file mode 100644 index 0000000..067674c --- /dev/null +++ b/libFDK/include/mips/fixmul_mips.h @@ -0,0 +1,53 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__mips__) + +#if (__GNUC__) && defined(__mips__) /* cppp replaced: elif */ +/* MIPS GCC based compiler */ + +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) + +inline INT fixmuldiv2_DD (const INT a, const INT b) +{ + INT result ; + + asm ("mult %1,%2;\n" + : "=hi" (result) + : "d" (a), "r" (b) + : "lo"); + + return result ; +} + +#endif /* (__GNUC__) && defined(__mips__) */ + +#endif /* __mips__ */ + diff --git a/libFDK/include/mips/scale.h b/libFDK/include/mips/scale.h new file mode 100644 index 0000000..82b1833 --- /dev/null +++ b/libFDK/include/mips/scale.h @@ -0,0 +1,48 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2007) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef MIPS_SCALE_H +#define MIPS_SCALE_H + +#if defined(__mips_dsp) + +/*! +* +* \brief Scale input value by 2^{scale} and saturate output to 2^{dBits-1} +* \return scaled and saturated value +* +* This macro scales src value right or left and applies saturation to (2^dBits)-1 +* maxima output. +*/ +#define SATURATE_RIGHT_SHIFT(src, scale, dBits) \ + (__builtin_mips_shll_s_w((src)>>scale,(DFRACT_BITS-(dBits)))>>(DFRACT_BITS-(dBits))) + + +#endif /*__mips_dsp */ + +#endif /* MIPS_SCALE_H */ diff --git a/libFDK/include/mips/scramble.h b/libFDK/include/mips/scramble.h new file mode 100644 index 0000000..b93031a --- /dev/null +++ b/libFDK/include/mips/scramble.h @@ -0,0 +1,59 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2007) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef MIPS_SCRAMBLE_H +#define MIPS_SCRAMBLE_H + +#define FUNCTION_scramble + +#if defined(FUNCTION_scramble) +inline void scramble(FIXP_DBL *x, INT n) { + INT m,j; + int ldn=1; + do {ldn++;} while((1<<ldn)<n); + + for (m=1,j=0; m<n-1; m++) + { + j = __builtin_mips_bitrev(m) >> (16-ldn); + + if (j>m) + { + FIXP_DBL tmp; + tmp=x[2*m]; + x[2*m]=x[2*j]; + x[2*j]=tmp; + + tmp=x[2*m+1]; + x[2*m+1]=x[2*j+1]; + x[2*j+1]=tmp; + } + } +} +#endif + +#endif /* MIPS_SCRAMBLE_H */ diff --git a/libFDK/include/qmf.h b/libFDK/include/qmf.h new file mode 100644 index 0000000..89c1061 --- /dev/null +++ b/libFDK/include/qmf.h @@ -0,0 +1,188 @@ +/**************************************************************************** + + (C) Copyright Fraunhofer IIS (2004) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + + $Id$ + +*******************************************************************************/ +/*! + \file qmf.h + \brief Complex qmf analysis/synthesis $Revision: 36871 $ + \author Markus Werner + +*/ +#ifndef __QMF_H +#define __QMF_H + + + +#include "common_fix.h" +#include "FDK_tools_rom.h" +#include "dct.h" + +/* + * Filter coefficient type definition + */ +#ifdef QMF_DATA_16BIT +#define FIXP_QMF FIXP_SGL +#define FX_DBL2FX_QMF FX_DBL2FX_SGL +#define FX_QMF2FX_DBL FX_SGL2FX_DBL +#define QFRACT_BITS FRACT_BITS +#else +#define FIXP_QMF FIXP_DBL +#define FX_DBL2FX_QMF +#define FX_QMF2FX_DBL +#define QFRACT_BITS DFRACT_BITS +#endif + +/* ARM neon optimized QMF analysis filter requires 32 bit input. + Implemented for RVCT only, currently disabled. See src/arm/qmf_arm.cpp:45 */ +#define FIXP_QAS FIXP_PCM +#define QAS_BITS SAMPLE_BITS + +#ifdef QMFSYN_STATES_16BIT +#define FIXP_QSS FIXP_SGL +#define QSS_BITS FRACT_BITS +#else +#define FIXP_QSS FIXP_DBL +#define QSS_BITS DFRACT_BITS +#endif + +/* Flags for QMF intialization */ +/* Low Power mode flag */ +#define QMF_FLAG_LP 1 +/* Filter is not symetric. This flag is set internally in the QMF initialization as required. */ +#define QMF_FLAG_NONSYMMETRIC 2 +/* Complex Low Delay Filter Bank (or std symmetric filter bank) */ +#define QMF_FLAG_CLDFB 4 +/* Flag indicating that the states should be kept. */ +#define QMF_FLAG_KEEP_STATES 8 +/* Complex Low Delay Filter Bank used in MPEG Surround Encoder */ +#define QMF_FLAG_MPSLDFB 16 +/* Complex Low Delay Filter Bank used in MPEG Surround Encoder allows a optimized calculation of the modulation in qmfForwardModulationHQ() */ +#define QMF_FLAG_MPSLDFB_OPTIMIZE_MODULATION 32 + + +typedef struct +{ + int lb_scale; /*!< Scale of low band area */ + int ov_lb_scale; /*!< Scale of adjusted overlap low band area */ + int hb_scale; /*!< Scale of high band area */ + int ov_hb_scale; /*!< Scale of adjusted overlap high band area */ +} QMF_SCALE_FACTOR; + +struct QMF_FILTER_BANK +{ + const FIXP_PFT *p_filter; /*!< Pointer to filter coefficients */ + + void *FilterStates; /*!< Pointer to buffer of filter states + FIXP_PCM in analyse and + FIXP_DBL in synthesis filter */ + int FilterSize; /*!< Size of prototype filter. */ + const FIXP_QTW *t_cos; /*!< Modulation tables. */ + const FIXP_QTW *t_sin; + int filterScale; /*!< filter scale */ + + int no_channels; /*!< Total number of channels (subbands) */ + int no_col; /*!< Number of time slots */ + int lsb; /*!< Top of low subbands */ + int usb; /*!< Top of high subbands */ + + int outScalefactor; /*!< Scale factor of output data (syn only) */ + FIXP_DBL outGain; /*!< Gain output data (syn only) (init with 0x80000000 to ignore) */ + + UINT flags; /*!< flags */ + UCHAR p_stride; /*!< Stride Factor of polyphase filters */ + +}; + +typedef struct QMF_FILTER_BANK *HANDLE_QMF_FILTER_BANK; + +void +qmfAnalysisFiltering( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Analysis Bank */ + FIXP_QMF **qmfReal, /*!< Pointer to real subband slots */ + FIXP_QMF **qmfImag, /*!< Pointer to imag subband slots */ + QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ + const INT_PCM *timeIn, /*!< Time signal */ + const int stride, /*!< Stride factor of audio data */ + FIXP_QMF *pWorkBuffer /*!< pointer to temporal working buffer */ + ); + +void +qmfSynthesisFiltering( HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_QMF **QmfBufferReal, /*!< Pointer to real subband slots */ + FIXP_QMF **QmfBufferImag, /*!< Pointer to imag subband slots */ + const QMF_SCALE_FACTOR *scaleFactor, /*!< Scale factors of QMF data */ + const int ov_len, /*!< Length of band overlap */ + INT_PCM *timeOut, /*!< Time signal */ + const int stride, /*!< Stride factor of audio data */ + FIXP_QMF *pWorkBuffer /*!< pointer to temporal working buffer */ + ); + +int +qmfInitAnalysisFilterBank( HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ + FIXP_QAS *pFilterStates, /*!< Pointer to filter state buffer */ + int noCols, /*!< Number of time slots */ + int lsb, /*!< Number of lower bands */ + int usb, /*!< Number of upper bands */ + int no_channels, /*!< Number of critically sampled bands */ + int flags); /*!< Flags */ + +void +qmfAnalysisFilteringSlot( HANDLE_QMF_FILTER_BANK anaQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_QMF *qmfReal, /*!< Low and High band, real */ + FIXP_QMF *qmfImag, /*!< Low and High band, imag */ + const INT_PCM *timeIn, /*!< Pointer to input */ + const int stride, /*!< stride factor of input */ + FIXP_QMF *pWorkBuffer /*!< pointer to temporal working buffer */ + ); + +int +qmfInitSynthesisFilterBank( HANDLE_QMF_FILTER_BANK h_Qmf, /*!< QMF Handle */ + FIXP_QSS *pFilterStates, /*!< Pointer to filter state buffer */ + int noCols, /*!< Number of time slots */ + int lsb, /*!< Number of lower bands */ + int usb, /*!< Number of upper bands */ + int no_channels, /*!< Number of critically sampled bands */ + int flags); /*!< Flags */ + +void qmfSynthesisFilteringSlot( HANDLE_QMF_FILTER_BANK synQmf, + const FIXP_QMF *realSlot, + const FIXP_QMF *imagSlot, + const int scaleFactorLowBand, + const int scaleFactorHighBand, + INT_PCM *timeOut, + const int stride, + FIXP_QMF *pWorkBuffer); + +void +qmfChangeOutScalefactor (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + int outScalefactor /*!< New scaling factor for output data */ + ); + +void +qmfChangeOutGain (HANDLE_QMF_FILTER_BANK synQmf, /*!< Handle of Qmf Synthesis Bank */ + FIXP_DBL outputGain /*!< New gain for output data */ + ); + + + +#endif /* __QMF_H */ diff --git a/libFDK/include/scale.h b/libFDK/include/scale.h new file mode 100644 index 0000000..72e7f03 --- /dev/null +++ b/libFDK/include/scale.h @@ -0,0 +1,180 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2005) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: Scaling operations + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef SCALE_H +#define SCALE_H + +#include "common_fix.h" +#include "genericStds.h" +#include "fixminmax.h" + + #define SCALE_INLINE inline + + +#if defined(__arm__) /* cppp replaced: elif */ +#include "arm/scale.h" + +#elif defined(__mips__) /* cppp replaced: elif */ +#include "mips/scale.h" + +#endif + + +#include "../src/scale.cpp" + +#ifndef FUNCTION_scaleValue +/*! + * + * \brief Multiply input by \f$ 2^{scalefactor} \f$ + * + * \return Scaled input + * + */ +#define FUNCTION_scaleValue +inline +FIXP_DBL scaleValue(const FIXP_DBL value, /*!< Value */ + INT scalefactor /*!< Scalefactor */ + ) +{ + if(scalefactor > 0) + return (value<<scalefactor); + else + return (value>>(-scalefactor)); +} +#endif + +#ifndef FUNCTION_scaleValueSaturate +/*! + * + * \brief Multiply input by \f$ 2^{scalefactor} \f$ + * \param value The value to be scaled. + * \param the shift amount + * \return \f$ value * 2^scalefactor \f$ + * + */ +#define FUNCTION_scaleValueSaturate +inline +FIXP_DBL scaleValueSaturate( + const FIXP_DBL value, + INT scalefactor + ) +{ + if(scalefactor > 0) { + if (fNorm(value) < scalefactor && value != (FIXP_DBL)0) { + return (FIXP_DBL)MAXVAL_DBL; + } else { + return (value<<scalefactor); + } + } else { + return (value>>(-scalefactor)); + } +} +#endif + +#ifndef FUNCTION_scaleValueInPlace +/*! + * + * \brief Multiply input by \f$ 2^{scalefactor} \f$ in place + * + * \return void + * + */ +#define FUNCTION_scaleValueInPlace +inline +void scaleValueInPlace( + FIXP_DBL *value, /*!< Value */ + INT scalefactor /*!< Scalefactor */ + ) +{ + INT newscale; + /* Note: The assignment inside the if conditional allows combining a load with the compare to zero (on ARM and maybe others) */ + if ((newscale = (scalefactor)) >= 0) { + *(value) <<= newscale; + } else { + *(value) >>= -newscale; + } +} +#endif + +/*! + * + * \brief Scale input value by 2^{scale} and saturate output to 2^{dBits-1} + * \return scaled and saturated value + * + * This macro scales src value right or left and applies saturation to (2^dBits)-1 + * maxima output. + */ + +#ifndef SATURATE_RIGHT_SHIFT + #define SATURATE_RIGHT_SHIFT(src, scale, dBits) \ + ( (((LONG)(src)>>(scale)) > (LONG)(((1U)<<((dBits)-1))-1)) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : (((LONG)(src)>>(scale)) < ~((LONG)(((1U)<<((dBits)-1))-1))) ? ~((LONG)(((1U)<<((dBits)-1))-1)) \ + : ((LONG)(src) >> (scale)) ) +#endif + +#ifndef SATURATE_LEFT_SHIFT + #define SATURATE_LEFT_SHIFT(src, scale, dBits) \ + ( ((LONG)(src) > ((LONG)(((1U)<<((dBits)-1))-1)>>(scale))) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) < ~((LONG)(((1U)<<((dBits)-1))-1)>>(scale))) ? ~((LONG)(((1U)<<((dBits)-1))-1)) \ + : ((LONG)(src) << (scale)) ) +#endif + +#ifndef SATURATE_SHIFT +#define SATURATE_SHIFT(src, scale, dBits) \ + ( ((scale) < 0) \ + ? SATURATE_LEFT_SHIFT((src), -(scale), (dBits)) \ + : SATURATE_RIGHT_SHIFT((src), (scale), (dBits)) ) +#endif + +/* + * Alternative shift and saturate left, saturates to -0.99999 instead of -1.0000 + * to avoid problems when inverting the sign of the result. + */ +#ifndef SATURATE_LEFT_SHIFT_ALT +#define SATURATE_LEFT_SHIFT_ALT(src, scale, dBits) \ + ( ((LONG)(src) > ((LONG)(((1U)<<((dBits)-1))-1)>>(scale))) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : ((LONG)(src) < ~((LONG)(((1U)<<((dBits)-1))-2)>>(scale))) ? ~((LONG)(((1U)<<((dBits)-1))-2)) \ + : ((LONG)(src) << (scale)) ) +#endif + +#ifndef SATURATE_RIGHT_SHIFT_ALT + #define SATURATE_RIGHT_SHIFT_ALT(src, scale, dBits) \ + ( (((LONG)(src)>>(scale)) > (LONG)(((1U)<<((dBits)-1))-1)) ? (LONG)(((1U)<<((dBits)-1))-1) \ + : (((LONG)(src)>>(scale)) < ~((LONG)(((1U)<<((dBits)-1))-2))) ? ~((LONG)(((1U)<<((dBits)-1))-2)) \ + : ((LONG)(src) >> (scale)) ) +#endif + +#ifndef SATURATE_INT_PCM_RIGHT_SHIFT +#define SATURATE_INT_PCM_RIGHT_SHIFT(src, scale) SATURATE_RIGHT_SHIFT(src, scale, SAMPLE_BITS) +#endif + +#ifndef SATURATE_INT_PCM_LEFT_SHIFT +#define SATURATE_INT_PCM_LEFT_SHIFT(src, scale) SATURATE_LEFT_SHIFT(src, scale, SAMPLE_BITS) +#endif + +#endif /* #ifndef SCALE_H */ diff --git a/libFDK/include/scramble.h b/libFDK/include/scramble.h new file mode 100644 index 0000000..3fc3b56 --- /dev/null +++ b/libFDK/include/scramble.h @@ -0,0 +1,103 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2005) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ + +#ifndef SCRAMBLE_H +#define SCRAMBLE_H + +#include "common_fix.h" + +#if defined(__arm__) +#include "arm/scramble.h" + +#elif defined(__mips__) && defined(__mips_dsp) /* cppp replaced: elif */ +#include "mips/scramble.h" + +#endif + +/***************************************************************************** + + functionname: scramble + description: bitreversal of input data + returns: + input: + output: + +*****************************************************************************/ +#if !defined(FUNCTION_scramble_sgl) + +inline void scramble_sgl(FIXP_SGL *x, INT n) +{ + INT m,k,j; + + for (m=1,j=0; m<n-1; m++) + { + {for(k=n>>1; (!((j^=k)&k)); k>>=1);} + + if (j>m) + { + FIXP_SGL tmp; + tmp=x[2*m]; + x[2*m]=x[2*j]; + x[2*j]=tmp; + + tmp=x[2*m+1]; + x[2*m+1]=x[2*j+1]; + x[2*j+1]=tmp; + } + } +} +#endif + +#if !defined(FUNCTION_scramble) + +/* default scramble functionality */ +inline void scramble(FIXP_DBL *x, INT n) +{ + INT m,k,j; + FDK_ASSERT(!(((UINT64)x)&(ALIGNMENT_DEFAULT-1))); + + for (m=1,j=0; m<n-1; m++) + { + {for(k=n>>1; (!((j^=k)&k)); k>>=1);} + + if (j>m) + { + FIXP_DBL tmp; + tmp=x[2*m]; + x[2*m]=x[2*j]; + x[2*j]=tmp; + + tmp=x[2*m+1]; + x[2*m+1]=x[2*j+1]; + x[2*j+1]=tmp; + } + } +} +#endif /* !defined(FUNCTION_scramble) */ + +#endif /* SCRAMBLE_H */ diff --git a/libFDK/include/x86/abs_x86.h b/libFDK/include/x86/abs_x86.h new file mode 100644 index 0000000..682bc9f --- /dev/null +++ b/libFDK/include/x86/abs_x86.h @@ -0,0 +1,44 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__x86__) + + #if defined(__x86_64__) + + inline INT fixabs_D(INT x) { return ((x) > (INT)(0)) ? (x) : -(x) ; } + inline INT fixabs_S(INT x) { return ((x) > (INT)(0)) ? (x) : -(x) ; } + + #define fixabs_I(x) fixabs_D(x) + + #define FUNCTION_fixabs_S + #define FUNCTION_fixabs_D + #define FUNCTION_fixabs_I + + #endif /* __x86_64__ */ + +#endif /*__x86__ */ + diff --git a/libFDK/include/x86/fixmul_x86.h b/libFDK/include/x86/fixmul_x86.h new file mode 100644 index 0000000..d391b40 --- /dev/null +++ b/libFDK/include/x86/fixmul_x86.h @@ -0,0 +1,115 @@ +/*************************** Fraunhofer IIS FDK Tools ********************** + + (C) Copyright Fraunhofer IIS (2006) + All Rights Reserved + + Please be advised that this software and/or program delivery is + Confidential Information of Fraunhofer and subject to and covered by the + + Fraunhofer IIS Software Evaluation Agreement + between Google Inc. and Fraunhofer + effective and in full force since March 1, 2012. + + You may use this software and/or program only under the terms and + conditions described in the above mentioned Fraunhofer IIS Software + Evaluation Agreement. Any other and/or further use requires a separate agreement. + + + $Id$ + Author(s): + Description: fixed point intrinsics + + This software and/or program is protected by copyright law and international + treaties. Any reproduction or distribution of this software and/or program, + or any portion of it, may result in severe civil and criminal penalties, and + will be prosecuted to the maximum extent possible under law. + +******************************************************************************/ +#if defined(__x86__) + +#if defined(_MSC_VER) && defined(_M_IX86) +/* Intel x86 */ + +#define FUNCTION_fixmul_DD +#define FUNCTION_fixmuldiv2_DD +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + +inline INT fixmul_DD (INT a, const INT b) +{ + __asm + { + mov eax, a + imul b + shl edx, 1 + mov a, edx + } + return a ; +} + + +inline INT fixmuldiv2_DD (INT a, const INT b) +{ + __asm + { + mov eax, a + imul b + mov a, edx + } + return a ; +} + +/* ############################################################################# */ +#elif (defined(__GNUC__)||defined(__gnu_linux__)) && defined(__x86__) + +#define FUNCTION_fixmul_DD +#define FUNCTION_fixmuldiv2_DD + +#define FUNCTION_fixmuldiv2BitExact_DD +#define fixmuldiv2BitExact_DD(a,b) fixmuldiv2_DD(a,b) + +#define FUNCTION_fixmulBitExact_DD +#define fixmulBitExact_DD(a,b) fixmul_DD(a,b) + +#define FUNCTION_fixmuldiv2BitExact_DS +#define fixmuldiv2BitExact_DS(a,b) fixmuldiv2_DS(a,b) + +#define FUNCTION_fixmulBitExact_DS +#define fixmulBitExact_DS(a,b) fixmul_DS(a,b) + +inline INT fixmul_DD (INT a, const INT b) +{ + INT result; + + asm( "imul %2;\n" + "shl $1, %0;\n" + : "=d"(result), "+a"(a) + : "r"(b) ); + + return result; +} + + +inline INT fixmuldiv2_DD (INT a, const INT b) +{ + INT result; + + asm ( "imul %2;" + : "=d"(result), "+a"(a) + : "r"(b) ); + + return result; +} + +#endif /* (defined(__GNUC__)||defined(__gnu_linux__)) && defined(__x86__) */ + +#endif /* __x86__ */ + |