1/* Copyright (C) 2007 Hong Zhiqian */
2/**
3   @file _kiss_fft_guts_tm.h
4   @author Hong Zhiqian
5   @brief Various compatibility routines for Speex (TriMedia version)
6*/
7/*
8   Redistribution and use in source and binary forms, with or without
9   modification, are permitted provided that the following conditions
10   are met:
11
12   - Redistributions of source code must retain the above copyright
13   notice, this list of conditions and the following disclaimer.
14
15   - Redistributions in binary form must reproduce the above copyright
16   notice, this list of conditions and the following disclaimer in the
17   documentation and/or other materials provided with the distribution.
18
19   - Neither the name of the Xiph.org Foundation nor the names of its
20   contributors may be used to endorse or promote products derived from
21   this software without specific prior written permission.
22
23   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
27   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34*/
35
36#ifndef _KISS_FFT_GUTS_TM_
37#define _KISS_FFT_GUTS_TM_
38
39#ifdef TM_ASM
40
41#include <ops/custom_defs.h>
42
43#ifdef FIXED_POINT
44
45#undef	sround
46#define sround(x)	sex16(((x) + (1<<(FRACBITS-1)) ) >> FRACBITS)
47
48#undef	MIN
49#undef	MAX
50#define MIN(a,b)	imin(a,b)
51#define	MAX(a,b)	imax(a,b)
52
53#define TM_MUL(res,a,b)																\
54	{	register int a0, a1, b0, b1;												\
55																					\
56		a0	 = sex16((a));															\
57		a1	 = asri(16,(a));														\
58		b0	 = sex16((b));															\
59		b1	 = asri(16,(b));														\
60		(res)= pack16lsb(															\
61			sround(ifir16((a),funshift2((b),(b)))),									\
62			sround(a0*b0-a1*b1));													\
63	}																				\
64
65#define TM_ADD(res,a,b)																\
66	{	(res)=dspidualadd((a),(b));													\
67	}																				\
68
69#define TM_SUB(res,a,b)																\
70	{	(res)=dspidualsub((a),(b));													\
71	}																				\
72
73#define TM_SHR(res,a,shift)															\
74	{	(res)=dualasr((a),(shift));													\
75	}																				\
76
77#define TM_DIV(res,c,frac)															\
78	{	register int c1, c0;														\
79																					\
80		c1 = asri(16,(c));															\
81		c0 = sex16((c));															\
82		(res) = pack16lsb(sround(c1 * (32767/(frac))), sround(c0 * (32767/(frac))));\
83	}																				\
84
85#define TM_NEGMSB(res, a)															\
86	{	(res) = pack16lsb((ineg(asri(16,(a)))), (a));								\
87	}																				\
88
89#else
90
91#undef	MIN
92#undef	MAX
93#define MIN(a,b)	fmin(a,b)
94#define MAX(a,b)	fmax(a,b)
95
96#endif
97#endif
98
99#undef	CHECKBUF
100#define CHECKBUF(buf,nbuf,n)													\
101    {																			\
102        if ( nbuf < (size_t)(n) ) {												\
103            speex_free(buf);													\
104            buf = (kiss_fft_cpx*)KISS_FFT_MALLOC(sizeof(kiss_fft_cpx)*(n)); 	\
105            nbuf = (size_t)(n);													\
106        }																		\
107	}																			\
108
109#undef	 C_ADD
110#define  C_ADD( res, a,b)														\
111   {																			\
112	    CHECK_OVERFLOW_OP((a).r,+,(b).r)										\
113	    CHECK_OVERFLOW_OP((a).i,+,(b).i)										\
114	    (res).r=(a).r+(b).r;  (res).i=(a).i+(b).i;								\
115    }																			\
116
117
118#undef	 C_SUB
119#define  C_SUB( res, a,b)														\
120    {																			\
121	    CHECK_OVERFLOW_OP((a).r,-,(b).r)										\
122	    CHECK_OVERFLOW_OP((a).i,-,(b).i)										\
123	    (res).r=(a).r-(b).r;  (res).i=(a).i-(b).i;								\
124    }																			\
125
126#undef	C_ADDTO
127#define C_ADDTO( res , a)														\
128    {																			\
129	    CHECK_OVERFLOW_OP((res).r,+,(a).r)										\
130	    CHECK_OVERFLOW_OP((res).i,+,(a).i)										\
131	    (res).r += (a).r;  (res).i += (a).i;									\
132    }																			\
133
134#undef	C_SUBFROM
135#define C_SUBFROM( res, a)														\
136    {																			\
137	    CHECK_OVERFLOW_OP((res).r,-,(a).r)										\
138	    CHECK_OVERFLOW_OP((res).i,-,(a).i)										\
139	    (res).r -= (a).r;  (res).i -= (a).i;									\
140	}																			\
141
142#undef	 kf_cexp
143#define  kf_cexp(x,phase)														\
144	{	(x)->r = KISS_FFT_COS(phase);											\
145		(x)->i = KISS_FFT_SIN(phase); }											\
146
147#undef	 kf_cexp2
148#define  kf_cexp2(x,phase)														\
149    {	(x)->r = spx_cos_norm((phase));											\
150		(x)->i = spx_cos_norm((phase)-32768); }									\
151
152
153#ifdef FIXED_POINT
154
155#undef	C_MUL
156#define C_MUL(m,a,b)															\
157	{	(m).r = sround( smul((a).r,(b).r) - smul((a).i,(b).i) );				\
158		(m).i = sround( smul((a).r,(b).i) + smul((a).i,(b).r) ); }				\
159
160#undef	C_FIXDIV
161#define C_FIXDIV(c,div)															\
162	{   DIVSCALAR( (c).r , div);												\
163		DIVSCALAR( (c).i  , div); }												\
164
165#undef	C_MULBYSCALAR
166#define C_MULBYSCALAR( c, s )													\
167    {	(c).r =  sround( smul( (c).r , s ) ) ;									\
168        (c).i =  sround( smul( (c).i , s ) ) ; }								\
169
170#else
171
172#undef	C_MUL
173#define C_MUL(m,a,b)															\
174	{	(m).r = (a).r*(b).r - (a).i*(b).i;										\
175        (m).i = (a).r*(b).i + (a).i*(b).r; }									\
176
177
178#undef	C_MULBYSCALAR
179#define C_MULBYSCALAR( c, s )													\
180    {	(c).r *= (s);															\
181        (c).i *= (s); }															\
182
183
184
185#endif
186
187#endif
188
189