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)