Blame gst-libs/gst/fft/_kiss_fft_guts_s32.h

Packit 971217
/*
Packit 971217
Copyright (c) 2003-2004, Mark Borgerding
Packit 971217
Packit 971217
All rights reserved.
Packit 971217
Packit 971217
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
Packit 971217
Packit 971217
    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
Packit 971217
    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
Packit 971217
    * Neither the author nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission.
Packit 971217
Packit 971217
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 971217
*/
Packit 971217
Packit 971217
/* kiss_fft.h
Packit 971217
   defines kiss_fft_s32_scalar as either short or a float type
Packit 971217
   and defines
Packit 971217
   typedef struct { kiss_fft_s32_scalar r; kiss_fft_s32_scalar i; }kiss_fft_s32_cpx; */
Packit 971217
#include "kiss_fft_s32.h"
Packit 971217
#include <limits.h>
Packit 971217
Packit 971217
/* The 2*sizeof(size_t) alignment here is borrowed from
Packit 971217
 * GNU libc, so it should be good most everywhere.
Packit 971217
 * It is more conservative than is needed on some 64-bit
Packit 971217
 * platforms, but ia64 does require a 16-byte alignment.
Packit 971217
 * The SIMD extensions for x86 and ppc32 would want a
Packit 971217
 * larger alignment than this, but we don't need to
Packit 971217
 * do better than malloc.
Packit 971217
 *
Packit 971217
 * Borrowed from GLib's gobject/gtype.c
Packit 971217
 */
Packit 971217
#define STRUCT_ALIGNMENT (2 * sizeof (size_t))
Packit 971217
#define ALIGN_STRUCT(offset) \
Packit 971217
      ((offset + (STRUCT_ALIGNMENT - 1)) & -STRUCT_ALIGNMENT)
Packit 971217
Packit 971217
#define MAXFACTORS 32
Packit 971217
/* e.g. an fft of length 128 has 4 factors 
Packit 971217
 as far as kissfft is concerned
Packit 971217
 4*4*4*2
Packit 971217
 */
Packit 971217
Packit 971217
struct kiss_fft_s32_state{
Packit 971217
    int nfft;
Packit 971217
    int inverse;
Packit 971217
    int factors[2*MAXFACTORS];
Packit 971217
    kiss_fft_s32_cpx twiddles[1];
Packit 971217
};
Packit 971217
Packit 971217
/*
Packit 971217
  Explanation of macros dealing with complex math:
Packit 971217
Packit 971217
   C_MUL(m,a,b)         : m = a*b
Packit 971217
   C_FIXDIV( c , div )  : if a fixed point impl., c /= div. noop otherwise
Packit 971217
   C_SUB( res, a,b)     : res = a - b
Packit 971217
   C_SUBFROM( res , a)  : res -= a
Packit 971217
   C_ADDTO( res , a)    : res += a
Packit 971217
 * */
Packit 971217
Packit 971217
#define FRACBITS 31
Packit 971217
#define SAMPPROD int64_t
Packit 971217
#define SAMP_MAX 2147483647
Packit 971217
Packit 971217
#define SAMP_MIN -SAMP_MAX
Packit 971217
Packit 971217
#if defined(CHECK_OVERFLOW)
Packit 971217
#  define CHECK_OVERFLOW_OP(a,op,b)  \
Packit 971217
	if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
Packit 971217
		fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) );  }
Packit 971217
#endif
Packit 971217
Packit 971217
Packit 971217
#   define smul(a,b) ( (SAMPPROD)(a)*(b) )
Packit 971217
#   define sround( x )  (kiss_fft_s32_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
Packit 971217
Packit 971217
#   define S_MUL(a,b) sround( smul(a,b) )
Packit 971217
Packit 971217
#   define C_MUL(m,a,b) \
Packit 971217
      do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
Packit 971217
          (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
Packit 971217
Packit 971217
#   define DIVSCALAR(x,k) \
Packit 971217
	(x) = sround( smul(  x, SAMP_MAX/k ) )
Packit 971217
Packit 971217
#   define C_FIXDIV(c,div) \
Packit 971217
	do {    DIVSCALAR( (c).r , div);  \
Packit 971217
		DIVSCALAR( (c).i  , div); }while (0)
Packit 971217
Packit 971217
#   define C_MULBYSCALAR( c, s ) \
Packit 971217
    do{ (c).r =  sround( smul( (c).r , s ) ) ;\
Packit 971217
        (c).i =  sround( smul( (c).i , s ) ) ; }while(0)
Packit 971217
Packit 971217
#ifndef CHECK_OVERFLOW_OP
Packit 971217
#  define CHECK_OVERFLOW_OP(a,op,b) /* noop */
Packit 971217
#endif
Packit 971217
Packit 971217
#define  C_ADD( res, a,b)\
Packit 971217
    do { \
Packit 971217
	    CHECK_OVERFLOW_OP((a).r,+,(b).r)\
Packit 971217
	    CHECK_OVERFLOW_OP((a).i,+,(b).i)\
Packit 971217
	    (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i; \
Packit 971217
    }while(0)
Packit 971217
#define  C_SUB( res, a,b)\
Packit 971217
    do { \
Packit 971217
	    CHECK_OVERFLOW_OP((a).r,-,(b).r)\
Packit 971217
	    CHECK_OVERFLOW_OP((a).i,-,(b).i)\
Packit 971217
	    (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i; \
Packit 971217
    }while(0)
Packit 971217
#define C_ADDTO( res , a)\
Packit 971217
    do { \
Packit 971217
	    CHECK_OVERFLOW_OP((res).r,+,(a).r)\
Packit 971217
	    CHECK_OVERFLOW_OP((res).i,+,(a).i)\
Packit 971217
	    (res).r += (a).r;  (res).i += (a).i;\
Packit 971217
    }while(0)
Packit 971217
Packit 971217
#define C_SUBFROM( res , a)\
Packit 971217
    do {\
Packit 971217
	    CHECK_OVERFLOW_OP((res).r,-,(a).r)\
Packit 971217
	    CHECK_OVERFLOW_OP((res).i,-,(a).i)\
Packit 971217
	    (res).r -= (a).r;  (res).i -= (a).i; \
Packit 971217
    }while(0)
Packit 971217
Packit 971217
Packit 971217
#  define KISS_FFT_S32_COS(phase)  floor(.5+SAMP_MAX * cos (phase))
Packit 971217
#  define KISS_FFT_S32_SIN(phase)  floor(.5+SAMP_MAX * sin (phase))
Packit 971217
#  define HALF_OF(x) ((x)>>1)
Packit 971217
Packit 971217
#define  kf_cexp(x,phase) \
Packit 971217
	do{ \
Packit 971217
		(x)->r = KISS_FFT_S32_COS(phase);\
Packit 971217
		(x)->i = KISS_FFT_S32_SIN(phase);\
Packit 971217
	}while(0)
Packit 971217
Packit 971217
Packit 971217
/* a debugging function */
Packit 971217
#define pcpx(c)\
Packit 971217
    fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )