📄 g729ev_tdac_tfr.c
字号:
/* ITU-T G.729EV Optimization/Characterization Candidate *//* Version: 1.0.a *//* Revision Date: June 28, 2006 *//* ITU-T G.729EV Optimization/Characterization Candidate ANSI-C Source Code Copyright (c) 2006 France Telecom, Matsushita Electric, Mindspeed, Siemens AG, ETRI, VoiceAge Corp. All rights reserved*/#include <stdlib.h>#include "stl.h"#include "G729EV_MAIN_defines.h"#include "G729EV_TDAC_tfr.h"/*--------------------------------------------------------------------------* * Function G729EV_TDAC_tfr() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * The good thomas fast fourier transform * *--------------------------------------------------------------------------*/void G729EV_TDAC_tfr(Word16 * x1, /* (i/o) pointer on the real part of data */ Word16 * x2, /* (i/o) pointer on the imaginary part of data */ Word16 sign) /* (i) flag to select FFT (1) or IFFT (-1) */{ Word32 ACC0; /* first ACC */ Word32 ACC1; /* second ACC */ Word32 tmp32; /* Tempory 32 bits variable */ Word16 tab_x1[G729EV_TDAC_NP * G729EV_TDAC_NPP]; Word16 tab_x2[G729EV_TDAC_NP * G729EV_TDAC_NPP]; Word16 rx1[G729EV_TDAC_NP]; Word16 rx2[G729EV_TDAC_NP]; Word16 *ptr_x1; /* Pointer on tab_x1 */ Word16 *ptr_x2; /* Pointer on tab_x2 */ Word16 *ptr0_x1; /* Pointer on tab_x1 for DFT step */ Word16 *ptr0_x2; /* Pointer on tab_x2 for DFT step */ const Word16 *ptr_cos; /* Pointer on cos table */ const Word16 *ptr_sin; /* Pointer on sin table */ const Word16 *ptr_cos_Overflow; /* Pointer on cos table (case of Overflow) */ const Word16 *ptr_sin_Overflow; /* Pointer on sin table (case of Overflow) */ const Word16 *ptr_map; /* Pointer on mapping indice (input and output) */ Word16 ip, ipp, i, j; Word16 x1_tmp; Word16 x2_tmp; Word16 exp_n2; Word16 n1; Word16 n2; /* size of sub array */ Word16 n3; Word16 p; /* size of the butterfly */ Word16 inkw; Word16 w1; Word16 w2; Word16 rix; Word16 cix; Word16 rjx; Word16 cjx; /******************************************************************************** * Mapping for the input indices (Good Thomas FTT) * ********************************************************************************/ ptr_x1 = tab_x1; ptr_x2 = tab_x2; ptr_map = G729EV_TDAC_tab_map; FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { FOR(ipp = 0; ipp < G729EV_TDAC_NPP; ipp++) { i = (Word16) * ptr_map++; *ptr_x1++ = x1[i]; *ptr_x2++ = x2[i];#if (WMOPS) move16(); move16(); move16();#endif } } /*******************************************************************************/ ptr_x1 = tab_x1; ptr_x2 = tab_x2; FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { FOR(j = 0; j < G729EV_TDAC_NB_REV; j++) { i = G729EV_TDAC_tab_rev_i[j]; ipp = G729EV_TDAC_tab_rev_ipp[j]; x1_tmp = ptr_x1[ipp]; /* swap value ptr_x1[i] and ptr_x1[ipp] */ x2_tmp = ptr_x2[ipp]; /* swap value ptr_x2[i] and ptr_x2[ipp] */ ptr_x1[ipp] = ptr_x1[i]; ptr_x2[ipp] = ptr_x2[i]; ptr_x1[i] = x1_tmp; ptr_x2[i] = x2_tmp;#if (WMOPS) move16(); move16(); move16(); move16(); move16(); move16(); move16(); move16();#endif } ptr_x1 += G729EV_TDAC_NPP; ptr_x2 += G729EV_TDAC_NPP; } /******************************************************************************* * n1 size of butterfly * *******************************************************************************/ ptr_x1 = tab_x1; ptr_x2 = tab_x2; FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { FOR(exp_n2 = 0; exp_n2 <= G729EV_TDAC_EXP_NPP; exp_n2++) { n2 = shl(1, exp_n2); n1 = shr(n2, 1); n3 = sub(G729EV_TDAC_EXP_NPP, exp_n2); FOR(p = 0; p < n1; p++) { /* get twiddle factor in arrays rw1 and rw2 */ tmp32 = L_shl(L_mult(p, G729EV_TDAC_NP), sub(n3, 1)); inkw = extract_l(tmp32); w1 = G729EV_TDAC_rw1[inkw];#if (WMOPS) move16();#endif w2 = G729EV_TDAC_rw2[inkw];#if(WMOPS) move16();#endif if (sign > 0) { w2 = negate(w2); } IF(sign > 0) /* FFT */ { FOR(i = p; i < G729EV_TDAC_NPP; i = add(i, n2)) { /* select item p in array p */ j = add(i, n1); /* butterfly on x[i] and x[j] */ rix = ptr_x1[i]; cix = ptr_x2[i];#if (WMOPS) move16(); move16();#endif /* twiddle factor */ ACC0 = L_mult(w1, ptr_x1[j]); ACC0 = L_msu(ACC0, w2, ptr_x2[j]); rjx = round(ACC0); ACC0 = L_mult(w2, ptr_x1[j]); ACC0 = L_mac(ACC0, w1, ptr_x2[j]); cjx = round(ACC0); ptr_x1[i] = add(rix, rjx); ptr_x2[i] = add(cix, cjx); ptr_x1[j] = sub(rix, rjx); ptr_x2[j] = sub(cix, cjx);#if (WMOPS) move16(); move16(); move16(); move16();#endif } } ELSE /* IFFT */ { FOR(i = p; i < G729EV_TDAC_NPP; i = add(i, n2)) { /* select item p in array p */ j = add(i, n1); /* butterfly on x[i] and x[j] */ rix = shr(ptr_x1[i], 1); cix = shr(ptr_x2[i], 1);#if (WMOPS) move16(); move16();#endif /* twiddle factor */ ACC0 = L_mult(w1, ptr_x1[j]); ACC0 = L_msu(ACC0, w2, ptr_x2[j]); ACC0 = L_shr(ACC0, 1); rjx = round(ACC0); ACC0 = L_mult(w2, ptr_x1[j]); ACC0 = L_mac(ACC0, w1, ptr_x2[j]); ACC0 = L_shr(ACC0, 1); cjx = round(ACC0); ptr_x1[i] = add(rix, rjx); ptr_x2[i] = add(cix, cjx); ptr_x1[j] = sub(rix, rjx); ptr_x2[j] = sub(cix, cjx);#if (WMOPS) move16(); move16(); move16(); move16();#endif } } } } /* end while */ ptr_x1 += G729EV_TDAC_NPP; ptr_x2 += G729EV_TDAC_NPP; } /* end for ip */ /************************************************************************** * G729EV_TDAC_NPP DFT (size 5) * **************************************************************************/ ptr0_x1 = tab_x1; ptr0_x2 = tab_x2; FOR(ipp = 0; ipp < G729EV_TDAC_NPP; ipp++) { ptr_x1 = ptr0_x1; ptr_x2 = ptr0_x2; FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { rx1[ip] = *ptr_x1; rx2[ip] = *ptr_x2;#if (WMOPS) move16(); move16();#endif ptr_x1 += G729EV_TDAC_NPP; ptr_x2 += G729EV_TDAC_NPP; } ptr_x1 = ptr0_x1++; ptr_x2 = ptr0_x2++; ptr_cos = G729EV_TDAC_xcos; ptr_sin = G729EV_TDAC_xsin; IF(sign > 0) /* FFT */ { FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { /* Set Overflow to 0 to test it after radix 5 with Q15 sin & cos coef */ /* keep pointer's position on cos & sin tables */ Overflow = 0; ptr_cos_Overflow = ptr_cos; ptr_sin_Overflow = ptr_sin; ACC0 = (Word32) 0; ACC1 = (Word32) 0;#if (WMOPS) move32(); move32(); move16();#endif FOR(i = 0; i < G729EV_TDAC_NP; i++) { ACC0 = L_mac(ACC0, rx1[i], (*ptr_cos)); ACC0 = L_msu(ACC0, rx2[i], (*ptr_sin)); ACC1 = L_mac(ACC1, rx2[i], (*ptr_cos++)); ACC1 = L_mac(ACC1, rx1[i], (*ptr_sin++)); } ACC0 = L_shr(ACC0, 1); ACC1 = L_shr(ACC1, 1); /* Overflow in Radix 5 --> use cos and sin coef in Q14 */ IF(sub((Word16) Overflow, 1) == 0) { ptr_cos = ptr_cos_Overflow; ptr_sin = ptr_sin_Overflow; ACC0 = (Word32) 0; ACC1 = (Word32) 0;#if (WMOPS) move32(); move32();#endif FOR(i = 0; i < G729EV_TDAC_NP; i++) { ACC0 = L_mac(ACC0, rx1[i], shr((*ptr_cos), 1)); ACC0 = L_msu(ACC0, rx2[i], shr((*ptr_sin), 1)); ACC1 = L_mac(ACC1, rx2[i], shr((*ptr_cos++), 1)); ACC1 = L_mac(ACC1, rx1[i], shr((*ptr_sin++), 1)); } } *ptr_x1 = round(ACC0); *ptr_x2 = round(ACC1); ptr_x1 += G729EV_TDAC_NPP; ptr_x2 += G729EV_TDAC_NPP; } } ELSE /* IFFT */ { FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { /* Set Overflow to 0 to test it after radix 5 with Q15 sin & cos coef */ /* keep pointer's position on cos & sin tables */ Overflow = (Word16) 0; ptr_cos_Overflow = ptr_cos; ptr_sin_Overflow = ptr_sin; ACC0 = (Word32) 0; ACC1 = (Word32) 0;#if (WMOPS) move32(); move32(); move16();#endif FOR(i = 0; i < G729EV_TDAC_NP; i++) { ACC0 = L_mac(ACC0, rx1[i], (*ptr_cos)); ACC0 = L_mac(ACC0, rx2[i], (*ptr_sin)); ACC1 = L_mac(ACC1, rx2[i], (*ptr_cos++)); ACC1 = L_msu(ACC1, rx1[i], (*ptr_sin++)); } ACC0 = L_shr(ACC0, 1); ACC1 = L_shr(ACC1, 1); /* 0verflow in Radix 5 --> use cos and sin coef in Q14 */ IF(sub((Word16) Overflow, 1) == 0) { ptr_cos = ptr_cos_Overflow; ptr_sin = ptr_sin_Overflow; ACC0 = (Word32) 0; ACC1 = (Word32) 0;#if (WMOPS) move32(); move32();#endif FOR(i = 0; i < G729EV_TDAC_NP; i++) { ACC0 = L_mac(ACC0, rx1[i], shr((*ptr_cos), 1)); ACC0 = L_mac(ACC0, rx2[i], shr((*ptr_sin), 1)); ACC1 = L_mac(ACC1, rx2[i], shr((*ptr_cos++), 1)); ACC1 = L_msu(ACC1, rx1[i], shr((*ptr_sin++), 1)); } } *ptr_x1 = round(ACC0); *ptr_x2 = round(ACC1); ptr_x1 += G729EV_TDAC_NPP; ptr_x2 += G729EV_TDAC_NPP; } /* end for ip */ } } /* end for ipp */ /*************************************************************************** * mapping for the output indices * ***************************************************************************/ ptr_x1 = tab_x1; ptr_x2 = tab_x2; ptr_map = G729EV_TDAC_tab_map2; FOR(ip = 0; ip < G729EV_TDAC_NP; ip++) { FOR(ipp = 0; ipp < G729EV_TDAC_NPP; ipp++) { i = (Word16) * ptr_map++; x1[i] = *ptr_x1++; x2[i] = *ptr_x2++;#if(WMOPS) move16(); move16(); move16();#endif } } return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -