153a5a1b3Sopenharmony_ci/* Copyright (C) 2007 Hong Zhiqian */ 253a5a1b3Sopenharmony_ci/** 353a5a1b3Sopenharmony_ci @file kiss_fftr_tm.h 453a5a1b3Sopenharmony_ci @author Hong Zhiqian 553a5a1b3Sopenharmony_ci @brief Various compatibility routines for Speex (TriMedia version) 653a5a1b3Sopenharmony_ci*/ 753a5a1b3Sopenharmony_ci/* 853a5a1b3Sopenharmony_ci Redistribution and use in source and binary forms, with or without 953a5a1b3Sopenharmony_ci modification, are permitted provided that the following conditions 1053a5a1b3Sopenharmony_ci are met: 1153a5a1b3Sopenharmony_ci 1253a5a1b3Sopenharmony_ci - Redistributions of source code must retain the above copyright 1353a5a1b3Sopenharmony_ci notice, this list of conditions and the following disclaimer. 1453a5a1b3Sopenharmony_ci 1553a5a1b3Sopenharmony_ci - Redistributions in binary form must reproduce the above copyright 1653a5a1b3Sopenharmony_ci notice, this list of conditions and the following disclaimer in the 1753a5a1b3Sopenharmony_ci documentation and/or other materials provided with the distribution. 1853a5a1b3Sopenharmony_ci 1953a5a1b3Sopenharmony_ci - Neither the name of the Xiph.org Foundation nor the names of its 2053a5a1b3Sopenharmony_ci contributors may be used to endorse or promote products derived from 2153a5a1b3Sopenharmony_ci this software without specific prior written permission. 2253a5a1b3Sopenharmony_ci 2353a5a1b3Sopenharmony_ci THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2453a5a1b3Sopenharmony_ci ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2553a5a1b3Sopenharmony_ci LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2653a5a1b3Sopenharmony_ci A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 2753a5a1b3Sopenharmony_ci CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 2853a5a1b3Sopenharmony_ci EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2953a5a1b3Sopenharmony_ci PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 3053a5a1b3Sopenharmony_ci PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 3153a5a1b3Sopenharmony_ci LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 3253a5a1b3Sopenharmony_ci NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 3353a5a1b3Sopenharmony_ci SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3453a5a1b3Sopenharmony_ci*/ 3553a5a1b3Sopenharmony_ci#include "_kiss_fft_guts_tm.h" 3653a5a1b3Sopenharmony_ci 3753a5a1b3Sopenharmony_ci#ifdef TM_ASM 3853a5a1b3Sopenharmony_ci 3953a5a1b3Sopenharmony_ci#include "profile_tm.h" 4053a5a1b3Sopenharmony_ci 4153a5a1b3Sopenharmony_ci#ifdef FIXED_POINT 4253a5a1b3Sopenharmony_ci 4353a5a1b3Sopenharmony_ci#define TM_NDIV(res,c,frac) \ 4453a5a1b3Sopenharmony_ci { register int c1, c0; \ 4553a5a1b3Sopenharmony_ci \ 4653a5a1b3Sopenharmony_ci c1 = -asri(16,(c)); \ 4753a5a1b3Sopenharmony_ci c0 = sex16((c)); \ 4853a5a1b3Sopenharmony_ci (res) = pack16lsb(sround(c1 * (32767/(frac))), sround(c0 * (32767/(frac))));\ 4953a5a1b3Sopenharmony_ci } 5053a5a1b3Sopenharmony_ci 5153a5a1b3Sopenharmony_ci 5253a5a1b3Sopenharmony_ci#define OVERRIDE_KISS_FFTR 5353a5a1b3Sopenharmony_civoid kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar * restrict timedata, kiss_fft_cpx * restrict freqdata) 5453a5a1b3Sopenharmony_ci{ 5553a5a1b3Sopenharmony_ci register int ncfft, ncfft2, k; 5653a5a1b3Sopenharmony_ci register int * restrict tmpbuf; 5753a5a1b3Sopenharmony_ci register int * restrict twiddles; 5853a5a1b3Sopenharmony_ci 5953a5a1b3Sopenharmony_ci ncfft = st->substate->nfft; 6053a5a1b3Sopenharmony_ci ncfft2 = ncfft >> 1; 6153a5a1b3Sopenharmony_ci tmpbuf = (int*)st->tmpbuf; 6253a5a1b3Sopenharmony_ci twiddles = (int*)st->super_twiddles; 6353a5a1b3Sopenharmony_ci 6453a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(timedata); 6553a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(freqdata); 6653a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(tmpbuf); 6753a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(twiddles); 6853a5a1b3Sopenharmony_ci 6953a5a1b3Sopenharmony_ci kiss_fft(st->substate , (const kiss_fft_cpx*)timedata, st->tmpbuf); 7053a5a1b3Sopenharmony_ci 7153a5a1b3Sopenharmony_ci { 7253a5a1b3Sopenharmony_ci register int tdcr, tdci; 7353a5a1b3Sopenharmony_ci tdcr = sround(st->tmpbuf[0].r * (32767/2)); 7453a5a1b3Sopenharmony_ci tdci = sround(st->tmpbuf[0].i * (32767/2)); 7553a5a1b3Sopenharmony_ci 7653a5a1b3Sopenharmony_ci freqdata[0].r = tdcr + tdci; 7753a5a1b3Sopenharmony_ci freqdata[ncfft].r = tdcr - tdci; 7853a5a1b3Sopenharmony_ci freqdata[ncfft].i = freqdata[0].i = 0; 7953a5a1b3Sopenharmony_ci } 8053a5a1b3Sopenharmony_ci 8153a5a1b3Sopenharmony_ci for ( k=1 ; k <= ncfft2 ; ++k ) 8253a5a1b3Sopenharmony_ci { 8353a5a1b3Sopenharmony_ci register int fpk, fpnk, i, tw, f1k, f2k; 8453a5a1b3Sopenharmony_ci register int fq1, fq2; 8553a5a1b3Sopenharmony_ci 8653a5a1b3Sopenharmony_ci i = ncfft-k; 8753a5a1b3Sopenharmony_ci 8853a5a1b3Sopenharmony_ci fpk = ld32x(tmpbuf,k); 8953a5a1b3Sopenharmony_ci tw = ld32x(twiddles,k); 9053a5a1b3Sopenharmony_ci fpnk = ld32x(tmpbuf,i); 9153a5a1b3Sopenharmony_ci 9253a5a1b3Sopenharmony_ci TM_DIV(fpk, fpk, 2); 9353a5a1b3Sopenharmony_ci TM_NDIV(fpnk,fpnk,2); 9453a5a1b3Sopenharmony_ci 9553a5a1b3Sopenharmony_ci TM_ADD( f1k, fpk , fpnk ); 9653a5a1b3Sopenharmony_ci TM_SUB( f2k, fpk , fpnk ); 9753a5a1b3Sopenharmony_ci TM_MUL( tw , f2k, tw ); 9853a5a1b3Sopenharmony_ci TM_ADD( fq1, f1k, tw ); 9953a5a1b3Sopenharmony_ci TM_SHR( fq1, fq1, 1 ); 10053a5a1b3Sopenharmony_ci TM_SUB( fq2, f1k, tw ); 10153a5a1b3Sopenharmony_ci TM_NEGMSB( fq2, fq2 ); 10253a5a1b3Sopenharmony_ci TM_SHR( fq2, fq2, 1 ); 10353a5a1b3Sopenharmony_ci 10453a5a1b3Sopenharmony_ci 10553a5a1b3Sopenharmony_ci st32d( k<<2, freqdata, fq1 ); 10653a5a1b3Sopenharmony_ci st32d( i<<2, freqdata, fq2 ); 10753a5a1b3Sopenharmony_ci } 10853a5a1b3Sopenharmony_ci} 10953a5a1b3Sopenharmony_ci 11053a5a1b3Sopenharmony_ci#define OVERRIDE_KISS_FFTRI 11153a5a1b3Sopenharmony_civoid kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx * restrict freqdata,kiss_fft_scalar * restrict timedata) 11253a5a1b3Sopenharmony_ci{ 11353a5a1b3Sopenharmony_ci register int k, ncfft, ncfft2; 11453a5a1b3Sopenharmony_ci register int * restrict tmpbuf; 11553a5a1b3Sopenharmony_ci register int * restrict twiddles; 11653a5a1b3Sopenharmony_ci 11753a5a1b3Sopenharmony_ci ncfft = st->substate->nfft; 11853a5a1b3Sopenharmony_ci ncfft2 = ncfft >> 1; 11953a5a1b3Sopenharmony_ci tmpbuf = (int*)st->tmpbuf; 12053a5a1b3Sopenharmony_ci twiddles = (int*)st->super_twiddles; 12153a5a1b3Sopenharmony_ci 12253a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(freqdata); 12353a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(timedata); 12453a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(tmpbuf); 12553a5a1b3Sopenharmony_ci TMDEBUG_ALIGNMEM(twiddles); 12653a5a1b3Sopenharmony_ci 12753a5a1b3Sopenharmony_ci { 12853a5a1b3Sopenharmony_ci register int fqr, fqnr; 12953a5a1b3Sopenharmony_ci 13053a5a1b3Sopenharmony_ci fqr = freqdata[0].r; 13153a5a1b3Sopenharmony_ci fqnr = freqdata[ncfft].r; 13253a5a1b3Sopenharmony_ci 13353a5a1b3Sopenharmony_ci st->tmpbuf[0].r = fqr + fqnr; 13453a5a1b3Sopenharmony_ci st->tmpbuf[0].i = fqr - fqnr; 13553a5a1b3Sopenharmony_ci } 13653a5a1b3Sopenharmony_ci 13753a5a1b3Sopenharmony_ci for ( k=1 ; k <= ncfft2 ; ++k ) 13853a5a1b3Sopenharmony_ci { 13953a5a1b3Sopenharmony_ci register int fk, fnkc, i, tw, fek, fok, tmp; 14053a5a1b3Sopenharmony_ci register int tbk, tbn; 14153a5a1b3Sopenharmony_ci 14253a5a1b3Sopenharmony_ci i = ncfft-k; 14353a5a1b3Sopenharmony_ci 14453a5a1b3Sopenharmony_ci fk = ld32x(freqdata,k); 14553a5a1b3Sopenharmony_ci tw = ld32x(twiddles,k); 14653a5a1b3Sopenharmony_ci fnkc = pack16lsb(-freqdata[i].i, freqdata[i].r); 14753a5a1b3Sopenharmony_ci 14853a5a1b3Sopenharmony_ci TM_ADD (fek, fk, fnkc); 14953a5a1b3Sopenharmony_ci TM_SUB (tmp, fk, fnkc); 15053a5a1b3Sopenharmony_ci TM_MUL (fok, tmp, tw ); 15153a5a1b3Sopenharmony_ci TM_ADD (tbk, fek, fok); 15253a5a1b3Sopenharmony_ci TM_SUB (tbn, fek, fok); 15353a5a1b3Sopenharmony_ci TM_NEGMSB(tbn, tbn); 15453a5a1b3Sopenharmony_ci 15553a5a1b3Sopenharmony_ci st32d(k<<2, tmpbuf, tbk); 15653a5a1b3Sopenharmony_ci st32d(i<<2, tmpbuf, tbn); 15753a5a1b3Sopenharmony_ci } 15853a5a1b3Sopenharmony_ci kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); 15953a5a1b3Sopenharmony_ci} 16053a5a1b3Sopenharmony_ci 16153a5a1b3Sopenharmony_ci#else 16253a5a1b3Sopenharmony_ci 16353a5a1b3Sopenharmony_ci#define OVERRIDE_KISS_FFTR 16453a5a1b3Sopenharmony_civoid kiss_fftr(kiss_fftr_cfg st,const kiss_fft_scalar * restrict timedata,kiss_fft_cpx * restrict freqdata) 16553a5a1b3Sopenharmony_ci{ 16653a5a1b3Sopenharmony_ci register kiss_fft_cpx fpnk, fpk, f1k, f2k, twk; 16753a5a1b3Sopenharmony_ci register int k, ncfft; 16853a5a1b3Sopenharmony_ci register kiss_fft_cpx * restrict tmpbuf, * restrict tw; 16953a5a1b3Sopenharmony_ci register float tdcr, tdci; 17053a5a1b3Sopenharmony_ci 17153a5a1b3Sopenharmony_ci ncfft = st->substate->nfft; 17253a5a1b3Sopenharmony_ci tmpbuf= st->tmpbuf; 17353a5a1b3Sopenharmony_ci tw = st->super_twiddles; 17453a5a1b3Sopenharmony_ci 17553a5a1b3Sopenharmony_ci kiss_fft( st->substate , (const kiss_fft_cpx*)timedata, tmpbuf ); 17653a5a1b3Sopenharmony_ci 17753a5a1b3Sopenharmony_ci tdcr = tmpbuf[0].r; 17853a5a1b3Sopenharmony_ci tdci = tmpbuf[0].i; 17953a5a1b3Sopenharmony_ci 18053a5a1b3Sopenharmony_ci freqdata[0].r = tdcr + tdci; 18153a5a1b3Sopenharmony_ci freqdata[ncfft].r = tdcr - tdci; 18253a5a1b3Sopenharmony_ci freqdata[ncfft].i = freqdata[0].i = 0; 18353a5a1b3Sopenharmony_ci 18453a5a1b3Sopenharmony_ci for ( k=1;k <= ncfft/2 ; ++k ) 18553a5a1b3Sopenharmony_ci { 18653a5a1b3Sopenharmony_ci fpk = tmpbuf[k]; 18753a5a1b3Sopenharmony_ci fpnk.r = tmpbuf[ncfft-k].r; 18853a5a1b3Sopenharmony_ci fpnk.i = -tmpbuf[ncfft-k].i; 18953a5a1b3Sopenharmony_ci 19053a5a1b3Sopenharmony_ci C_ADD( f1k, fpk , fpnk ); 19153a5a1b3Sopenharmony_ci C_SUB( f2k, fpk , fpnk ); 19253a5a1b3Sopenharmony_ci C_MUL( twk, f2k , tw[k]); 19353a5a1b3Sopenharmony_ci 19453a5a1b3Sopenharmony_ci freqdata[k].r = HALF_OF(f1k.r + twk.r); 19553a5a1b3Sopenharmony_ci freqdata[k].i = HALF_OF(f1k.i + twk.i); 19653a5a1b3Sopenharmony_ci freqdata[ncfft-k].r = HALF_OF(f1k.r - twk.r); 19753a5a1b3Sopenharmony_ci freqdata[ncfft-k].i = HALF_OF(twk.i - f1k.i); 19853a5a1b3Sopenharmony_ci } 19953a5a1b3Sopenharmony_ci} 20053a5a1b3Sopenharmony_ci 20153a5a1b3Sopenharmony_ci#define OVERRIDE_KISS_FFTRI 20253a5a1b3Sopenharmony_civoid kiss_fftri(kiss_fftr_cfg st,const kiss_fft_cpx * restrict freqdata,kiss_fft_scalar * restrict timedata) 20353a5a1b3Sopenharmony_ci{ 20453a5a1b3Sopenharmony_ci register int k, ncfft; 20553a5a1b3Sopenharmony_ci register kiss_fft_cpx * restrict tmpbuf, * restrict tw; 20653a5a1b3Sopenharmony_ci 20753a5a1b3Sopenharmony_ci 20853a5a1b3Sopenharmony_ci ncfft = st->substate->nfft; 20953a5a1b3Sopenharmony_ci tmpbuf= st->tmpbuf; 21053a5a1b3Sopenharmony_ci tw = st->super_twiddles; 21153a5a1b3Sopenharmony_ci 21253a5a1b3Sopenharmony_ci tmpbuf[0].r = freqdata[0].r + freqdata[ncfft].r; 21353a5a1b3Sopenharmony_ci tmpbuf[0].i = freqdata[0].r - freqdata[ncfft].r; 21453a5a1b3Sopenharmony_ci 21553a5a1b3Sopenharmony_ci for (k = 1; k <= ncfft / 2; ++k) 21653a5a1b3Sopenharmony_ci { 21753a5a1b3Sopenharmony_ci register kiss_fft_cpx fk, fnkc, fek, fok, tmp; 21853a5a1b3Sopenharmony_ci fk = freqdata[k]; 21953a5a1b3Sopenharmony_ci fnkc.r = freqdata[ncfft - k].r; 22053a5a1b3Sopenharmony_ci fnkc.i = -freqdata[ncfft - k].i; 22153a5a1b3Sopenharmony_ci 22253a5a1b3Sopenharmony_ci C_ADD (fek, fk, fnkc); 22353a5a1b3Sopenharmony_ci C_SUB (tmp, fk, fnkc); 22453a5a1b3Sopenharmony_ci C_MUL (fok,tmp,tw[k]); 22553a5a1b3Sopenharmony_ci C_ADD (tmpbuf[k],fek, fok); 22653a5a1b3Sopenharmony_ci C_SUB (tmp, fek, fok); 22753a5a1b3Sopenharmony_ci tmpbuf[ncfft - k].r = tmp.r; 22853a5a1b3Sopenharmony_ci tmpbuf[ncfft - k].i = -tmp.i; 22953a5a1b3Sopenharmony_ci } 23053a5a1b3Sopenharmony_ci kiss_fft (st->substate, st->tmpbuf, (kiss_fft_cpx *) timedata); 23153a5a1b3Sopenharmony_ci} 23253a5a1b3Sopenharmony_ci 23353a5a1b3Sopenharmony_ci#endif 23453a5a1b3Sopenharmony_ci#endif 23553a5a1b3Sopenharmony_ci 236