configure: bump to 1.2rc3
[speexdsp.git] / tmv / kiss_fftr_tm.h
1 /* Copyright (C) 2007 Hong Zhiqian */\r
2 /**\r
3    @file kiss_fftr_tm.h\r
4    @author Hong Zhiqian\r
5    @brief Various compatibility routines for Speex (TriMedia version)\r
6 */\r
7 /*\r
8    Redistribution and use in source and binary forms, with or without\r
9    modification, are permitted provided that the following conditions\r
10    are met:\r
11    \r
12    - Redistributions of source code must retain the above copyright\r
13    notice, this list of conditions and the following disclaimer.\r
14    \r
15    - Redistributions in binary form must reproduce the above copyright\r
16    notice, this list of conditions and the following disclaimer in the\r
17    documentation and/or other materials provided with the distribution.\r
18    \r
19    - Neither the name of the Xiph.org Foundation nor the names of its\r
20    contributors may be used to endorse or promote products derived from\r
21    this software without specific prior written permission.\r
22    \r
23    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r
24    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r
25    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\r
26    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR\r
27    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\r
28    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\r
29    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\r
30    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
31    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
32    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\r
33    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
34 */\r
35 #include "_kiss_fft_guts_tm.h"\r
36 \r
37 #ifdef TM_ASM\r
38 \r
39 #include "profile_tm.h"\r
40 \r
41 #ifdef FIXED_POINT\r
42 \r
43 #define TM_NDIV(res,c,frac)                                                                                                                     \\r
44         {       register int c1, c0;                                                                                                            \\r
45                                                                                                                                                                         \\r
46                 c1 = -asri(16,(c));                                                                                                                     \\r
47                 c0 = sex16((c));                                                                                                                        \\r
48                 (res) = pack16lsb(sround(c1 * (32767/(frac))), sround(c0 * (32767/(frac))));\\r
49         }       \r
50 \r
51 \r
52 #define OVERRIDE_KISS_FFTR\r
53 void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar * restrict timedata, kiss_fft_cpx * restrict freqdata)\r
54 {\r
55         register int ncfft, ncfft2, k;\r
56         register int * restrict tmpbuf;\r
57         register int * restrict twiddles;\r
58 \r
59         ncfft = st->substate->nfft;\r
60         ncfft2 = ncfft >> 1;\r
61         tmpbuf = (int*)st->tmpbuf;\r
62         twiddles = (int*)st->super_twiddles;\r
63 \r
64         TMDEBUG_ALIGNMEM(timedata);\r
65         TMDEBUG_ALIGNMEM(freqdata);\r
66         TMDEBUG_ALIGNMEM(tmpbuf);\r
67         TMDEBUG_ALIGNMEM(twiddles);\r
68 \r
69         kiss_fft(st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf);\r
70 \r
71          {\r
72                 register int tdcr, tdci;\r
73                 tdcr = sround(st->tmpbuf[0].r * (32767/2));\r
74                 tdci = sround(st->tmpbuf[0].i * (32767/2));\r
75 \r
76                 freqdata[0].r = tdcr + tdci;\r
77                 freqdata[ncfft].r = tdcr - tdci;\r
78                 freqdata[ncfft].i = freqdata[0].i = 0;\r
79          }\r
80 \r
81          for ( k=1 ; k <= ncfft2 ; ++k ) \r
82          {      \r
83                 register int fpk, fpnk, i, tw, f1k, f2k;\r
84                 register int fq1, fq2;\r
85 \r
86                 i = ncfft-k;\r
87 \r
88                 fpk  = ld32x(tmpbuf,k);\r
89                 tw   = ld32x(twiddles,k);\r
90                 fpnk = ld32x(tmpbuf,i);\r
91 \r
92                 TM_DIV(fpk, fpk, 2);\r
93                 TM_NDIV(fpnk,fpnk,2);\r
94  \r
95         TM_ADD( f1k, fpk , fpnk );\r
96         TM_SUB( f2k, fpk , fpnk );\r
97                 TM_MUL( tw , f2k, tw );\r
98                 TM_ADD( fq1, f1k, tw );\r
99                 TM_SHR( fq1, fq1, 1  );\r
100                 TM_SUB( fq2, f1k, tw );\r
101                 TM_NEGMSB( fq2, fq2 );\r
102                 TM_SHR( fq2, fq2, 1 );\r
103 \r
104 \r
105                 st32d( k<<2, freqdata, fq1 );\r
106                 st32d( i<<2, freqdata, fq2 );\r
107     }\r
108 }\r
109 \r
110 #define OVERRIDE_KISS_FFTRI\r
111 void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx * restrict freqdata,kiss_fft_scalar * restrict timedata)\r
112 {\r
113         register int k, ncfft, ncfft2;\r
114         register int * restrict tmpbuf;\r
115         register int * restrict twiddles;\r
116 \r
117     ncfft = st->substate->nfft;\r
118         ncfft2 = ncfft >> 1;\r
119         tmpbuf = (int*)st->tmpbuf;\r
120         twiddles = (int*)st->super_twiddles;\r
121 \r
122         TMDEBUG_ALIGNMEM(freqdata);\r
123         TMDEBUG_ALIGNMEM(timedata);\r
124         TMDEBUG_ALIGNMEM(tmpbuf);\r
125         TMDEBUG_ALIGNMEM(twiddles);\r
126 \r
127         {\r
128                 register int fqr, fqnr;\r
129 \r
130                 fqr  = freqdata[0].r;\r
131                 fqnr = freqdata[ncfft].r;\r
132 \r
133                 st->tmpbuf[0].r = fqr + fqnr;\r
134                 st->tmpbuf[0].i = fqr - fqnr;\r
135         }\r
136 \r
137     for ( k=1 ; k <= ncfft2 ; ++k ) \r
138         {\r
139                 register int fk, fnkc, i, tw, fek, fok, tmp;\r
140                 register int tbk, tbn;\r
141 \r
142                 i = ncfft-k;\r
143 \r
144                 fk = ld32x(freqdata,k);\r
145                 tw = ld32x(twiddles,k);\r
146                 fnkc = pack16lsb(-freqdata[i].i, freqdata[i].r);\r
147         \r
148         TM_ADD (fek, fk, fnkc);\r
149         TM_SUB (tmp, fk, fnkc);\r
150         TM_MUL (fok, tmp, tw );\r
151                 TM_ADD (tbk, fek, fok);\r
152                 TM_SUB (tbn, fek, fok);\r
153                 TM_NEGMSB(tbn, tbn);\r
154 \r
155                 st32d(k<<2, tmpbuf, tbk);\r
156                 st32d(i<<2, tmpbuf, tbn);\r
157     }\r
158     kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);\r
159 }\r
160 \r
161 #else\r
162 \r
163 #define OVERRIDE_KISS_FFTR\r
164 void kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar * restrict timedata,kiss_fft_cpx * restrict freqdata)\r
165 {\r
166     register kiss_fft_cpx fpnk, fpk, f1k, f2k, twk;\r
167     register int k, ncfft;\r
168         register kiss_fft_cpx * restrict tmpbuf, * restrict tw;\r
169         register float tdcr, tdci;\r
170 \r
171     ncfft = st->substate->nfft;\r
172         tmpbuf= st->tmpbuf;\r
173         tw        = st->super_twiddles;\r
174 \r
175         kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, tmpbuf );\r
176 \r
177         tdcr = tmpbuf[0].r;\r
178     tdci = tmpbuf[0].i;\r
179     \r
180         freqdata[0].r = tdcr + tdci;\r
181     freqdata[ncfft].r = tdcr - tdci;\r
182     freqdata[ncfft].i = freqdata[0].i = 0;\r
183 \r
184     for ( k=1;k <= ncfft/2 ; ++k ) \r
185         {\r
186         fpk    = tmpbuf[k]; \r
187         fpnk.r = tmpbuf[ncfft-k].r;\r
188         fpnk.i = -tmpbuf[ncfft-k].i;\r
189 \r
190         C_ADD( f1k, fpk , fpnk );\r
191         C_SUB( f2k, fpk , fpnk );\r
192         C_MUL( twk, f2k , tw[k]);\r
193 \r
194         freqdata[k].r = HALF_OF(f1k.r + twk.r);\r
195         freqdata[k].i = HALF_OF(f1k.i + twk.i);\r
196         freqdata[ncfft-k].r = HALF_OF(f1k.r - twk.r);\r
197         freqdata[ncfft-k].i = HALF_OF(twk.i - f1k.i);\r
198     }\r
199 }\r
200 \r
201 #define OVERRIDE_KISS_FFTRI\r
202 void kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx * restrict freqdata,kiss_fft_scalar * restrict timedata)\r
203 {\r
204     register int k, ncfft;\r
205         register kiss_fft_cpx * restrict tmpbuf, * restrict tw;\r
206         \r
207                 \r
208     ncfft = st->substate->nfft;\r
209         tmpbuf= st->tmpbuf;\r
210         tw        = st->super_twiddles;\r
211                 \r
212     tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r;\r
213     tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r;\r
214 \r
215     for (k = 1; k <= ncfft / 2; ++k) \r
216         {\r
217         register kiss_fft_cpx fk, fnkc, fek, fok, tmp;\r
218         fk = freqdata[k];\r
219         fnkc.r = freqdata[ncfft - k].r;\r
220         fnkc.i = -freqdata[ncfft - k].i;\r
221 \r
222         C_ADD (fek, fk, fnkc);\r
223         C_SUB (tmp, fk, fnkc);\r
224         C_MUL (fok,tmp,tw[k]);\r
225         C_ADD (tmpbuf[k],fek, fok);\r
226         C_SUB (tmp, fek, fok);\r
227                 tmpbuf[ncfft - k].r = tmp.r;\r
228         tmpbuf[ncfft - k].i = -tmp.i;\r
229         }\r
230     kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata);\r
231 }\r
232 \r
233 #endif\r
234 #endif\r
235 \r