📄 g729ev_tdbwe_fft.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 "G729EV_TDBWE_fft.h"#include "G729EV_G729_ld8k.h"/*--------------------------------------------------------------------------* * Function G729EV_TDBWE_c_fft() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * FFT function for complex sequences * * * * The decimation-in-time complex FFT is implemented below. * * The input complex numbers are presented as the real part followed by * * the imaginary part for each sample. The counters are therefore * * incremented by two to access the complex valued samples. * *--------------------------------------------------------------------------*/void G729EV_TDBWE_c_fft(Word16 * farray_ptr, /* (i/o) complex input signal / complex output FFT bins */ Word16 * nls) /* (i) normalization shift amount */{ Word16 i, j, k, ii, jj, kk, ji, kj; Word32 ftmp_real, ftmp_imag; Word16 ftmp, tmp, tmp1, tmp2; Word16 sh; Word16 *farray_ptr_p1; /* Rearrange the input array in bit reversed order */ j = 0;#ifdef WMOPS move16();#endif FOR(i = 0; i < G729EV_TDBWE_FFT_SIZE_M_2; i = i + 2) { IF(sub(j, i) > 0) { ftmp = *(farray_ptr + i); *(farray_ptr + i) = *(farray_ptr + j); *(farray_ptr + j) = ftmp;#ifdef WMOPS move16(); move16(); move16();#endif farray_ptr_p1 = &farray_ptr[1]; ftmp = *(farray_ptr_p1 + i); *(farray_ptr_p1 + i) = *(farray_ptr_p1 + j); *(farray_ptr_p1 + j) = ftmp;#ifdef WMOPS move16(); move16(); move16();#endif } k = G729EV_TDBWE_FFT_SIZE_BY_TWO;#ifdef WMOPS move16();#endif WHILE(sub(j, k) >= 0) { j = sub(j, k); k = shr(k, 1); } j = add(j, k); } /* The FFT part */ FOR(i = 0; i < G729EV_TDBWE_FFT_NUM_STAGE; i++) /* i: stage counter */ { jj = shl(2, i); /* FFT size */ kk = shl(jj, 1); /* 2 * FFT size */ ii = shl(2, sub(G729EV_TDBWE_FFT_NUM_STAGE, i)); /* 2*2* number of FFTs */ ji = 0; /* phase table index */#ifdef WMOPS move16();#endif /* rescale to format 0x01fff <= farray <= 0xe000 */ sh = 16;#ifdef WMOPS move16();#endif FOR(k = 0; k < G729EV_TDBWE_FFT_SIZE; ++k) { IF(farray_ptr[k] != 0) { tmp = norm_s(farray_ptr[k]); if (sub(tmp, sh) < 0) { sh = tmp;#ifdef WMOPS move16();#endif } } } if (sub(sh, 16) == 0) { sh = 0;#ifdef WMOPS move16();#endif } sh = sub(sh, 2); *nls = add(*nls, sh); FOR(k = 0; k < G729EV_TDBWE_FFT_SIZE; ++k) { farray_ptr[k] = shl(farray_ptr[k], sh);#ifdef WMOPS move16();#endif } FOR(j = 0; j < jj; j = j + 2) /* j: sample counter */ { k = j;#ifdef WMOPS move16();#endif WHILE(sub(k, G729EV_TDBWE_FFT_SIZE) < 0) { /* k: butterfly top */ kj = add(k, jj); /* kj: butterfly bottom */ /* Butterfly computations */ ftmp_real = L_mult(*(farray_ptr + kj), G729EV_TDBWE_fft_phs_tbl[ji]); ftmp_real = L_msu(ftmp_real, *(farray_ptr + kj + 1), G729EV_TDBWE_fft_phs_tbl[ji + 1]); ftmp_imag = L_mult(*(farray_ptr + kj + 1), G729EV_TDBWE_fft_phs_tbl[ji]); ftmp_imag = L_mac(ftmp_imag, *(farray_ptr + kj), G729EV_TDBWE_fft_phs_tbl[ji + 1]); tmp1 = round(ftmp_real); tmp2 = round(ftmp_imag); /* max(tmp1/tmp2) = 0x2d41 */ tmp = sub(*(farray_ptr + k), tmp1); *(farray_ptr + kj) = tmp;#ifdef WMOPS move16();#endif tmp = sub(*(farray_ptr + k + 1), tmp2); *(farray_ptr + kj + 1) = tmp;#ifdef WMOPS move16();#endif tmp = add(*(farray_ptr + k), tmp1); *(farray_ptr + k) = tmp;#ifdef WMOPS move16();#endif tmp = add(*(farray_ptr + k + 1), tmp2); *(farray_ptr + k + 1) = tmp;#ifdef WMOPS move16();#endif k = add(k, kk); } ji = add(ji, ii); } /* max(stage N out) = 0x4d40 */ }}/*--------------------------------------------------------------------------* * Function G729EV_TDBWE_r_fft() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * FFT function for real sequences * *--------------------------------------------------------------------------*/void G729EV_TDBWE_r_fft(Word16 * farray_ptr, /* (i/o) input signal / output FFT bins */ Word16 * nls) /* (i) normalization shift amount */{ Word16 ftmp1_real, ftmp1_imag, ftmp2_real, ftmp2_imag; Word32 Lftmp1_real, Lftmp1_imag; Word16 i, j, ip1, jp1; Word32 Ltmp1; /* Perform the complex FFT */ G729EV_TDBWE_c_fft(farray_ptr, nls); /* max(farray_ptr) = 0x26a0 */ FOR(i = 0; i < G729EV_TDBWE_FFT_SIZE; ++i) { farray_ptr[i] = shr(farray_ptr[i], 1);#ifdef WMOPS move16();#endif } /* First, handle the DC and foldover frequencies */ ftmp1_real = *farray_ptr; ftmp2_real = *(farray_ptr + 1); *farray_ptr = add(ftmp1_real, ftmp2_real); *(farray_ptr + 1) = sub(ftmp1_real, ftmp2_real);#ifdef WMOPS move16(); move16(); move16(); move16();#endif /* Now, handle the remaining positive frequencies */ FOR(i = 2; i <= G729EV_TDBWE_FFT_SIZE_BY_TWO; i = i + 2) { j = sub(G729EV_TDBWE_FFT_SIZE, i); ip1 = add(i, 1); jp1 = add(j, 1); ftmp1_real = add(*(farray_ptr + i), *(farray_ptr + j)); ftmp1_imag = sub(*(farray_ptr + ip1), *(farray_ptr + jp1)); ftmp2_real = add(*(farray_ptr + ip1), *(farray_ptr + jp1)); ftmp2_imag = sub(*(farray_ptr + j), *(farray_ptr + i)); Lftmp1_real = L_deposit_h(ftmp1_real); Lftmp1_imag = L_deposit_h(ftmp1_imag); Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, G729EV_TDBWE_fft_phs_tbl[i]); Ltmp1 = L_msu(Ltmp1, ftmp2_imag, G729EV_TDBWE_fft_phs_tbl[ip1]); *(farray_ptr + i) = round(Ltmp1);#ifdef WMOPS move16();#endif Ltmp1 = L_mac(Lftmp1_imag, ftmp2_imag, G729EV_TDBWE_fft_phs_tbl[i]); Ltmp1 = L_mac(Ltmp1, ftmp2_real, G729EV_TDBWE_fft_phs_tbl[ip1]); *(farray_ptr + ip1) = round(Ltmp1);#ifdef WMOPS move16();#endif Ltmp1 = L_mac(Lftmp1_real, ftmp2_real, G729EV_TDBWE_fft_phs_tbl[j]); Ltmp1 = L_mac(Ltmp1, ftmp2_imag, G729EV_TDBWE_fft_phs_tbl[jp1]); *(farray_ptr + j) = round(Ltmp1);#ifdef WMOPS move16();#endif Ltmp1 = L_negate(Lftmp1_imag); Ltmp1 = L_msu(Ltmp1, ftmp2_imag, G729EV_TDBWE_fft_phs_tbl[j]); Ltmp1 = L_mac(Ltmp1, ftmp2_real, G729EV_TDBWE_fft_phs_tbl[jp1]); *(farray_ptr + jp1) = round(Ltmp1);#ifdef WMOPS move16();#endif }}/*--------------------------------------------------------------------------* * Function G729EV_TDBWE_fft() * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * TDBWE FFT implementation * *--------------------------------------------------------------------------*/void G729EV_TDBWE_fft(Word16 * x, /* (i) input sequency */ Word16 * reX, /* (o) real part of the FFT spectrum */ Word16 * imX, /* (o) imaginary part of the FFT spectrum */ Word16 vector_size, /* (i) number of elements in x[] */ Word16 * nls) /* (i/o) normalization shift amount */{ Word16 i, it2; Word16 buffer[G729EV_TDBWE_FFT_SIZE]; Word16 *bp1; G729EV_G729_Copy(x, buffer, vector_size); G729EV_TDBWE_r_fft(buffer, nls); /* compute only the used bins of the spectrum */ imX[0] = 0; reX[0] = shl(buffer[0], 1);#ifdef WMOPS move16(); move16();#endif bp1 = &buffer[1]; FOR(i = 1; i <= 24; i++) { it2 = add(i, i); imX[i] = sub(0, bp1[it2]); reX[i] = buffer[it2];#ifdef WMOPS move16(); move16();#endif }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -