34 template<
typename Real>
    36   if ( (N & (N-1)) != 0 || N <= 1)
    37     KALDI_ERR << 
"SplitRadixComplexFft called with invalid number of points "    48 template <
typename Real>
    51     N_(other.
N_), logn_(other.
logn_) {
    63     tab_ = 
new Real*[logn_ - 3];
    67       tab_[
i-4] = 
new Real[this_array_size];
    68       std::memcpy(tab_[
i-4], other.
tab_[
i-4],
    69                   sizeof(Real) * this_array_size);
    74 template<
typename Real>
    78   Real    *cn, *spcn, *smcn, *c3n, *spc3n, *smc3n;
    86   for (j = 2; j <= lg2; j++) {
    88     for (i = 0; i < imax; i++) {
    90       brseed_[i + imax] = brseed_[
i] + 1;
    97     tab_ = 
new Real* [logn_-3];
    98     for (i = logn_; i>=4 ; i--) {
   100       m = 1 << 
i; m2 = m / 2; m4 = m2 / 2; m8 = m4 /2;
   105       tab_[i-4] = 
new Real[6*nel];
   108       cn = tab_[i-4]; spcn  = cn + nel;  smcn  = spcn + nel;
   109       c3n = smcn + nel;  spc3n = c3n + nel; smc3n = spc3n + nel;
   112       for (n = 1; n < m4; n++) {
   113         if (n == m8) 
continue;
   115         c = std::cos(ang); s = std::sin(ang);
   116         *cn++ = c; *spcn++ = - (s + c); *smcn++ = s - c;
   117         ang = 3 * n * 
M_2PI / m;
   118         c = std::cos(ang); s = std::sin(ang);
   119         *c3n++ = c; *spc3n++ = - (s + c); *smc3n++ = s - c;
   125 template<
typename Real>
   135 template<
typename Real>
   142   ComputeRecursive(xr, xi, logn_);
   144     BitReversePermute(xr, logn_);
   145     BitReversePermute(xi, logn_);
   149 template<
typename Real>
   151                                          std::vector<Real> *temp_buffer)
 const {
   153   if (temp_buffer->size() != N_)
   154     temp_buffer->resize(N_);
   155   Real *temp_ptr = &((*temp_buffer)[0]);
   158     temp_ptr[
i] = x[
i * 2 + 1];  
   161   memcpy(static_cast<void*>(x + N_),
   162          static_cast<void*>(temp_ptr),
   165   Compute(x, x + N_, forward);
   167   memcpy(static_cast<void*>(temp_ptr),
   168          static_cast<void*>(x + N_),
   174     x[
i*2 + 1] = temp_ptr[
i];
   179 template<
typename Real>
   181   this->Compute(x, forward, &temp_buffer_);
   184 template<
typename Real>
   195   for (off = 1; off < 
n; off++) {
   196     fj = n * brseed_[off]; i = off; j = fj;
   197     tmp = x[
i]; x[
i] = x[
j]; x[
j] = tmp;
   200     for (gno = 1; gno < brseed_[off]; gno++) {
   204       tmp = *xp; *xp = *xq; *xq = tmp;
   210 template<
typename Real>
   214   Real    *xr1, *xr2, *xi1, *xi2;
   215   Real    *cn = 
nullptr, *spcn = 
nullptr, *smcn = 
nullptr, *c3n = 
nullptr,
   216     *spc3n = 
nullptr, *smc3n = 
nullptr;
   222     KALDI_ERR << 
"Error: logn is out of bounds in SRFFT";
   265     else if (logn == 1) {   
   276     else if (logn == 0) 
return;   
   280   m = 1 << logn; m2 = m / 2; m4 = m2 / 2; m8 = m4 /2;
   284   xr1 = xr; xr2 = xr1 + m2;
   285   xi1 = xi; xi2 = xi1 + m2;
   286   for (n = 0; n < m2; n++) {
   298   xr1 = xr + m2; xr2 = xr1 + m4;
   299   xi1 = xi + m2; xi2 = xi1 + m4;
   300   for (n = 0; n < m4; n++) {
   305     *xr2++ = *xr1 - *xi2;
   312   xr1 = xr + m2; xr2 = xr1 + m4;
   313   xi1 = xi + m2; xi2 = xi1 + m4;
   316     cn  = tab_[logn-4]; spcn  = cn + nel;  smcn  = spcn + nel;
   317     c3n = smcn + nel;  spc3n = c3n + nel; smc3n = spc3n + nel;
   319   xr1++; xr2++; xi1++; xi2++;
   321   for (n = 1; n < m4; n++) {
   323       tmp1 =  sqhalf * (*xr1 + *xi1);
   324       *xi1 =  sqhalf * (*xi1 - *xr1);
   326       tmp2 =  sqhalf * (*xi2 - *xr2);
   327       *xi2 = -sqhalf * (*xr2 + *xi2);
   330       tmp2 = *cn++ * (*xr1 + *xi1);
   331       tmp1 = *spcn++ * *xr1 + tmp2;
   332       *xr1 = *smcn++ * *xi1 + tmp2;
   334       tmp2 = *c3n++ * (*xr2 + *xi2);
   335       tmp1 = *spc3n++ * *xr2 + tmp2;
   336       *xr2 = *smc3n++ * *xi2 + tmp2;
   339     xr1++; xr2++; xi1++; xi2++;
   343   ComputeRecursive(xr, xi, logn-1);
   348   ComputeRecursive(xr + m2, xi + m2, logn - 2);
   351   ComputeRecursive(xr + m4, xi + m4, logn - 2);
   355 template<
typename Real>
   357   Compute(data, forward, &this->temp_buffer_);
   363 template<
typename Real>
   365                                       std::vector<Real> *temp_buffer)
 const {
   371   Real rootN_re, rootN_im;  
   372   int forward_sign = forward ? -1 : 1;
   374   Real kN_re = -forward_sign, kN_im = 0.0;  
   377     ComplexMul(rootN_re, rootN_im, &kN_re, &kN_im);
   379     Real Ck_re, Ck_im, Dk_re, Dk_im;
   381     Ck_re = 0.5 * (data[2*k] + data[N - 2*k]);
   382     Ck_im = 0.5 * (data[2*k + 1] - data[N - 2*k + 1]);
   384     Dk_re = 0.5 * (data[2*k + 1] + data[N - 2*k + 1]);
   386     Dk_im =-0.5 * (data[2*k] - data[N - 2*k]);
   400       data[2*kdash] = Ck_re;  
   401       data[2*kdash+1] = -Ck_im;
   405       ComplexAddProduct(Dk_re, -Dk_im, -kN_re, kN_im, &(data[2*kdash]), &(data[2*kdash+1]));
   415     Real zeroth = data[0] + data[1],
   416         n2th = data[0] - data[1];
 This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
 
void BitReversePermute(Real *x, Integer logn) const
 
void ComputeRecursive(Real *xr, Real *xi, Integer logn) const
 
void Compute(Real *xr, Real *xi, bool forward) const
 
void ComplexAddProduct(const Real &a_re, const Real &a_im, const Real &b_re, const Real &b_im, Real *c_re, Real *c_im)
ComplexMul implements, inline, the complex operation c += (a * b). 
 
void ComplexMul(const Real &a_re, const Real &a_im, Real *b_re, Real *b_im)
ComplexMul implements, inline, the complex multiplication b *= a. 
 
#define KALDI_ASSERT(cond)
 
void Compute(Real *x, bool forward)
If forward == true, this function transforms from a sequence of N real points to its complex fourier ...
 
void ComplexImExp(Real x, Real *a_re, Real *a_im)
ComplexImExp implements a <– exp(i x), inline. 
 
SplitRadixComplexFft(Integer N)