FastLED 3.9.15
Loading...
Searching...
No Matches
_kiss_fft_guts.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2003-2010, Mark Borgerding. All rights reserved.
3 * This file is part of KISS FFT - https://github.com/mborgerding/kissfft
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 * See COPYING file for more information.
7 */
8
9#pragma once
10
11/* kiss_fft.h
12 defines kiss_fft_scalar as either short or a float type
13 and defines
14 typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */
15#include "kiss_fft.h"
16#include <limits.h>
17#include "fl/math/math.h"
18
19#define MAXFACTORS 32
20/* e.g. an fft of length 128 has 4 factors
21 as far as kissfft is concerned
22 4*4*4*2
23 */
24
31
32/*
33 Explanation of macros dealing with complex math:
34
35 C_MUL(m,a,b) : m = a*b
36 C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise
37 C_SUB( res, a,b) : res = a - b
38 C_SUBFROM( res , a) : res -= a
39 C_ADDTO( res , a) : res += a
40 * */
41#ifdef FIXED_POINT
42#if (FIXED_POINT==32)
43# define FRACBITS 31
44# define SAMPPROD i64
45#define SAMP_MAX 2147483647
46#else
47# define FRACBITS 15
48# define SAMPPROD int32_t
49#define SAMP_MAX 32767
50#endif
51
52#define SAMP_MIN -SAMP_MAX
53
54#if defined(CHECK_OVERFLOW)
55# define CHECK_OVERFLOW_OP(a,op,b) \
56 if ( (SAMPPROD)(a) op (SAMPPROD)(b) > SAMP_MAX || (SAMPPROD)(a) op (SAMPPROD)(b) < SAMP_MIN ) { \
57 fprintf(stderr,"WARNING:overflow @ " __FILE__ "(%d): (%d " #op" %d) = %ld\n",__LINE__,(a),(b),(SAMPPROD)(a) op (SAMPPROD)(b) ); }
58#endif
59
60
61# define smul(a,b) ( (SAMPPROD)(a)*(b) )
62# define sround( x ) (kiss_fft_scalar)( ( (x) + (1<<(FRACBITS-1)) ) >> FRACBITS )
63
64# define S_MUL(a,b) sround( smul(a,b) )
65
66# define C_MUL(m,a,b) \
67 do{ (m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) ); \
68 (m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }while(0)
69
70# define DIVSCALAR(x,k) \
71 (x) = sround( smul( x, SAMP_MAX/k ) )
72
73# define C_FIXDIV(c,div) \
74 do { DIVSCALAR( (c).r , div); \
75 DIVSCALAR( (c).i , div); }while (0)
76
77# define C_MULBYSCALAR( c, s ) \
78 do{ (c).r = sround( smul( (c).r , s ) ) ;\
79 (c).i = sround( smul( (c).i , s ) ) ; }while(0)
80
81#else /* not FIXED_POINT*/
82
83# define S_MUL(a,b) ( (a)*(b) )
84#define C_MUL(m,a,b) \
85 do{ (m).r = (a).r*(b).r - (a).i*(b).i;\
86 (m).i = (a).r*(b).i + (a).i*(b).r; }while(0)
87# define C_FIXDIV(c,div) /* NOOP */
88# define C_MULBYSCALAR( c, s ) \
89 do{ (c).r *= (s);\
90 (c).i *= (s); }while(0)
91#endif
92
93#ifndef CHECK_OVERFLOW_OP
94# define CHECK_OVERFLOW_OP(a,op,b) /* noop */
95#endif
96
97#define C_ADD( res, a,b)\
98 do { \
99 CHECK_OVERFLOW_OP((a).r,+,(b).r)\
100 CHECK_OVERFLOW_OP((a).i,+,(b).i)\
101 (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \
102 }while(0)
103#define C_SUB( res, a,b)\
104 do { \
105 CHECK_OVERFLOW_OP((a).r,-,(b).r)\
106 CHECK_OVERFLOW_OP((a).i,-,(b).i)\
107 (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \
108 }while(0)
109#define C_ADDTO( res , a)\
110 do { \
111 CHECK_OVERFLOW_OP((res).r,+,(a).r)\
112 CHECK_OVERFLOW_OP((res).i,+,(a).i)\
113 (res).r += (a).r; (res).i += (a).i;\
114 }while(0)
115
116#define C_SUBFROM( res , a)\
117 do {\
118 CHECK_OVERFLOW_OP((res).r,-,(a).r)\
119 CHECK_OVERFLOW_OP((res).i,-,(a).i)\
120 (res).r -= (a).r; (res).i -= (a).i; \
121 }while(0)
122
123
124#ifdef FIXED_POINT
125# define KISS_FFT_COS(phase) fl::floor(.5+SAMP_MAX * FFT_COS(phase))
126# define KISS_FFT_SIN(phase) fl::floor(.5+SAMP_MAX * FFT_SIN(phase))
127# define HALF_OF(x) ((x)>>1)
128#elif defined(USE_SIMD)
129# define KISS_FFT_COS(phase) _mm_set1_ps( FFT_COS(phase) )
130# define KISS_FFT_SIN(phase) _mm_set1_ps( FFT_SIN(phase) )
131# define HALF_OF(x) ((x)*_mm_set1_ps(.5))
132#else
133// Use precision-aware math functions from fft_precision.h
134# define KISS_FFT_COS(phase) (kiss_fft_scalar) FFT_COS(phase)
135# define KISS_FFT_SIN(phase) (kiss_fft_scalar) FFT_SIN(phase)
136# if FASTLED_FFT_PRECISION == FASTLED_FFT_FLOAT
137# define HALF_OF(x) ((x)*0.5f)
138# else // FASTLED_FFT_DOUBLE or FASTLED_FFT_FIXED16
139# define HALF_OF(x) ((x)*0.5)
140# endif
141#endif
142
143#define kf_cexp(x,phase) \
144 do{ \
145 (x)->r = KISS_FFT_COS(phase);\
146 (x)->i = KISS_FFT_SIN(phase);\
147 }while(0)
148
149
150/* a debugging function */
151#define pcpx(c)\
152 fprintf(stderr,"%g + %gi\n",(double)((c)->r),(double)((c)->i) )
153
154
155#ifdef KISS_FFT_USE_ALLOCA
156// define this to allow use of alloca instead of malloc for temporary buffers
157// Temporary buffers are used in two case:
158// 1. FFT sizes that have "bad" factors. i.e. not 2,3 and 5
159// 2. "in-place" FFTs. Notice the quotes, since kissfft does not really do an in-place transform.
160#include <alloca.h>
161#define KISS_FFT_TMP_ALLOC(nbytes) alloca(nbytes)
162#define KISS_FFT_TMP_FREE(ptr)
163#else
164#define KISS_FFT_TMP_ALLOC(nbytes) KISS_FFT_MALLOC(nbytes)
165#define KISS_FFT_TMP_FREE(ptr) KISS_FFT_FREE(ptr)
166#endif
#define MAXFACTORS
int factors[2 *MAXFACTORS]
kiss_fft_cpx twiddles[1]