/* First and second pass at once */ static inline void MLO_Fft_DoPass1 (MLO_Float dest_ptr [], const MLO_Float x_ptr [], int len, const MLO_Int16 br_ptr []) { const int qlen = len >> 2; int coef_index = 0; do { const int ri_0 = br_ptr [coef_index >> 2]; const int ri_1 = ri_0 + 2 * qlen; /* br_ptr [coef_index + 1] */ const int ri_2 = ri_0 + 1 * qlen; /* br_ptr [coef_index + 2] */ const int ri_3 = ri_0 + 3 * qlen; /* br_ptr [coef_index + 3] */ MLO_Float * df2 = dest_ptr + coef_index; MLO_Float sf_0; MLO_Float sf_2; df2 [1] = MLO_Float_Sub (x_ptr [ri_0], x_ptr [ri_1]); df2 [3] = MLO_Float_Sub (x_ptr [ri_2], x_ptr [ri_3]); sf_0 = MLO_Float_Add (x_ptr [ri_0], x_ptr [ri_1]); sf_2 = MLO_Float_Add (x_ptr [ri_2], x_ptr [ri_3]); df2 [0] = MLO_Float_Add (sf_0, sf_2); df2 [2] = MLO_Float_Sub (sf_0, sf_2); coef_index += 4; } while (coef_index < len); }
/* Third pass */ static inline void MLO_Fft_DoPass3 (MLO_Float dest_ptr [], const MLO_Float src_ptr [], int len) { const MLO_Float sqrt2_2 = MLO_FLOAT_C (MLO_DEFS_SQRT2 * 0.5); int coef_index = 0; do { MLO_Float v; dest_ptr [coef_index ] = MLO_Float_Add (src_ptr [coef_index], src_ptr [coef_index + 4]); dest_ptr [coef_index + 4] = src_ptr [coef_index] - src_ptr [coef_index + 4]; dest_ptr [coef_index + 2] = src_ptr [coef_index + 2]; dest_ptr [coef_index + 6] = src_ptr [coef_index + 6]; v = MLO_Float_Sub (src_ptr [coef_index + 5], src_ptr [coef_index + 7]); v = MLO_Float_Mul (v, sqrt2_2); dest_ptr [coef_index + 1] = MLO_Float_Add (src_ptr [coef_index + 1], v); dest_ptr [coef_index + 3] = MLO_Float_Sub (src_ptr [coef_index + 1], v); v = MLO_Float_Add (src_ptr [coef_index + 5], src_ptr [coef_index + 7]); v = MLO_Float_Mul (v, sqrt2_2); dest_ptr [coef_index + 5] = MLO_Float_Add (v, src_ptr [coef_index + 3]); dest_ptr [coef_index + 7] = MLO_Float_Sub (v, src_ptr [coef_index + 3]); coef_index += 8; } while (coef_index < len); }
/* Other passes */ static inline void MLO_Fft_DoPassN (MLO_Float dest_ptr [], const MLO_Float src_ptr [], int len, int pass) { const int dist = 1L << (pass - 2); const int c1_r = 0; const int c1_i = dist; const int c2_r = dist * 2; const int c2_i = dist * 3; const int cend = dist * 4; const int table_step = MLO_FFT_TABLE_LEN_COS >> (pass - 2); long coef_index = 0; do { const MLO_Float * const sf = src_ptr + coef_index; MLO_Float * const df = dest_ptr + coef_index; int i = 1; /* Extreme coefficients are always real */ df [c1_r] = MLO_Float_Add (sf [c1_r], sf [c2_r]); df [c2_r] = sf [c1_r] - sf [c2_r]; df [c1_i] = sf [c1_i]; df [c2_i] = sf [c2_i]; /* Others are conjugate complex numbers */ do { const MLO_Float c = MLO_Fft_table_cos [ i * table_step]; const MLO_Float s = MLO_Fft_table_cos [(dist - i) * table_step]; const MLO_Float sf_r_i = sf [c1_r + i]; const MLO_Float sf_i_i = sf [c1_i + i]; const MLO_Float v1 = MLO_Float_Sub ( MLO_Float_Mul (sf [c2_r + i], c), MLO_Float_Mul (sf [c2_i + i], s) ); MLO_Float v2; df [c1_r + i] = MLO_Float_Add (sf_r_i, v1); df [c2_r - i] = MLO_Float_Sub (sf_r_i, v1); v2 = MLO_Float_Add ( MLO_Float_Mul (sf [c2_r + i], s), MLO_Float_Mul (sf [c2_i + i], c) ); df [c2_r + i] = MLO_Float_Add (v2, sf_i_i); df [cend - i] = MLO_Float_Sub (v2, sf_i_i); ++ i; } while (i < dist); coef_index += cend; } while (coef_index < len); }
static void MLO_Ms_ProcessSfb (MLO_IndivChnStream *ics_l_ptr, MLO_IndivChnStream *ics_r_ptr, int g, int sfb, int win_pos) { int sfb_start; int sfb_len; int window_group_length; int win; MLO_ASSERT (ics_l_ptr != NULL); MLO_ASSERT (ics_r_ptr != NULL); MLO_ASSERT (g >= 0); MLO_ASSERT (g < 8); MLO_ASSERT (sfb >= 0); MLO_ASSERT (sfb < ics_r_ptr->ics_info.max_sfb); MLO_ASSERT (win_pos >= 0); MLO_ASSERT (win_pos < MLO_DEFS_FRAME_LEN_LONG); sfb_start = ics_r_ptr->ics_info.swb_offset [sfb]; sfb_len = ics_r_ptr->ics_info.swb_offset [sfb + 1] - sfb_start; win_pos += sfb_start; window_group_length = ics_r_ptr->ics_info.window_group_length [g]; for (win = 0; win < window_group_length; ++win) { int pos_end = win_pos + sfb_len; int i; for (i = win_pos; i < pos_end; ++i) { const MLO_Float l = ics_l_ptr->coef_arr [i]; const MLO_Float r = ics_r_ptr->coef_arr [i]; ics_l_ptr->coef_arr [i] = MLO_Float_Add (l, r); ics_r_ptr->coef_arr [i] = MLO_Float_Sub (l, r); } win_pos += MLO_DEFS_FRAME_LEN_SHORT; } }