@@ -108,12 +108,12 @@ void celt_tx_mdct_inv_float_neon(const OpusTXContext *s, void *out, void *in, pt
108108/* M-point power-of-two sub-FFTs. The PFA kernel reads len and map (the
109109 split-radix parity scatter map); the preshuffled kernels themselves read
110110 nothing (fft_sr additionally reads len). */
111- static const OpusTXContext celt_tx_p2_4 = { 4 , 1 , celt_tx_p2_map_4 , NULL , NULL , NULL , NULL };
112- static const OpusTXContext celt_tx_p2_8 = { 8 , 1 , celt_tx_p2_map_8 , NULL , NULL , NULL , NULL };
113- static const OpusTXContext celt_tx_p2_16 = { 16 , 1 , celt_tx_p2_map_16 , NULL , NULL , NULL , NULL };
114- static const OpusTXContext celt_tx_p2_32 = { 32 , 1 , celt_tx_p2_map_32 , NULL , NULL , NULL , NULL };
111+ static const OpusTXContext celt_tx_p2_4 = { 4 , 1 , celt_tx_p2_map_4 , NULL , NULL , NULL , celt_tx_fft4_fwd_float_neon };
112+ static const OpusTXContext celt_tx_p2_8 = { 8 , 1 , celt_tx_p2_map_8 , NULL , NULL , NULL , celt_tx_fft8_ns_float_neon };
113+ static const OpusTXContext celt_tx_p2_16 = { 16 , 1 , celt_tx_p2_map_16 , NULL , NULL , NULL , celt_tx_fft16_ns_float_neon };
114+ static const OpusTXContext celt_tx_p2_32 = { 32 , 1 , celt_tx_p2_map_32 , NULL , NULL , NULL , celt_tx_fft32_ns_float_neon };
115115#if defined(ENABLE_QEXT )
116- static const OpusTXContext celt_tx_p2_64 = { 64 , 1 , celt_tx_p2_map_64 , NULL , NULL , NULL , NULL };
116+ static const OpusTXContext celt_tx_p2_64 = { 64 , 1 , celt_tx_p2_map_64 , NULL , NULL , NULL , celt_tx_fft_sr_ns_float_neon };
117117#endif
118118
119119/* 15xM PFA sub-FFTs; .tmp is filled in per call with stack scratch. */
@@ -139,23 +139,23 @@ static const OpusTXContext celt_tx_sr_512 = { 512, 1, NULL, NULL, NULL, NULL, NU
139139
140140/* Inverse MDCT roots; for the 15*M sizes .sub is relinked per call to the
141141 stack copy of the PFA context, the power-of-two ones run fully const. */
142- static const OpusTXContext celt_tx_mdct_120 = { 120 , 1 , celt_tx_mdct_map_120 , ( const void * ) celt_tx_mdct_exp_120 , NULL , & celt_tx_pfa_60 , celt_tx_fft_pfa_15xM_ns_float_neon };
143- static const OpusTXContext celt_tx_mdct_240 = { 240 , 1 , celt_tx_mdct_map_240 , ( const void * ) celt_tx_mdct_exp_240 , NULL , & celt_tx_pfa_120 , celt_tx_fft_pfa_15xM_ns_float_neon };
144- static const OpusTXContext celt_tx_mdct_480 = { 480 , 1 , celt_tx_mdct_map_480 , ( const void * ) celt_tx_mdct_exp_480 , NULL , & celt_tx_pfa_240 , celt_tx_fft_pfa_15xM_ns_float_neon };
145- static const OpusTXContext celt_tx_mdct_960 = { 960 , 1 , celt_tx_mdct_map_960 , ( const void * ) celt_tx_mdct_exp_960 , NULL , & celt_tx_pfa_480 , celt_tx_fft_pfa_15xM_ns_float_neon };
142+ static const OpusTXContext celt_tx_mdct_120 = { 120 , 1 , celt_tx_mdct_map_120 , NULL , NULL , & celt_tx_pfa_60 , celt_tx_fft_pfa_15xM_ns_float_neon };
143+ static const OpusTXContext celt_tx_mdct_240 = { 240 , 1 , celt_tx_mdct_map_240 , NULL , NULL , & celt_tx_pfa_120 , celt_tx_fft_pfa_15xM_ns_float_neon };
144+ static const OpusTXContext celt_tx_mdct_480 = { 480 , 1 , celt_tx_mdct_map_480 , NULL , NULL , & celt_tx_pfa_240 , celt_tx_fft_pfa_15xM_ns_float_neon };
145+ static const OpusTXContext celt_tx_mdct_960 = { 960 , 1 , celt_tx_mdct_map_960 , NULL , NULL , & celt_tx_pfa_480 , celt_tx_fft_pfa_15xM_ns_float_neon };
146146#if defined(ENABLE_QEXT )
147- static const OpusTXContext celt_tx_mdct_1920 = { 1920 , 1 , celt_tx_mdct_map_1920 , ( const void * ) celt_tx_mdct_exp_1920 , NULL , & celt_tx_pfa_960 , celt_tx_fft_pfa_15xM_ns_float_neon };
147+ static const OpusTXContext celt_tx_mdct_1920 = { 1920 , 1 , celt_tx_mdct_map_1920 , NULL , NULL , & celt_tx_pfa_960 , celt_tx_fft_pfa_15xM_ns_float_neon };
148148#endif
149149
150150#if defined(CUSTOM_MODES )
151- static const OpusTXContext celt_tx_mdct_64 = { 64 , 1 , celt_tx_mdct_map_64 , ( const void * ) celt_tx_mdct_exp_64 , NULL , & celt_tx_sr_32 , celt_tx_fft32_ns_float_neon };
152- static const OpusTXContext celt_tx_mdct_128 = { 128 , 1 , celt_tx_mdct_map_128 , ( const void * ) celt_tx_mdct_exp_128 , NULL , & celt_tx_sr_64 , celt_tx_fft_sr_ns_float_neon };
153- static const OpusTXContext celt_tx_mdct_256 = { 256 , 1 , celt_tx_mdct_map_256 , ( const void * ) celt_tx_mdct_exp_256 , NULL , & celt_tx_sr_128 , celt_tx_fft_sr_ns_float_neon };
154- static const OpusTXContext celt_tx_mdct_512 = { 512 , 1 , celt_tx_mdct_map_512 , ( const void * ) celt_tx_mdct_exp_512 , NULL , & celt_tx_sr_256 , celt_tx_fft_sr_ns_float_neon };
155- static const OpusTXContext celt_tx_mdct_1024 = { 1024 , 1 , celt_tx_mdct_map_1024 , ( const void * ) celt_tx_mdct_exp_1024 , NULL , & celt_tx_sr_512 , celt_tx_fft_sr_ns_float_neon };
151+ static const OpusTXContext celt_tx_mdct_64 = { 64 , 1 , celt_tx_mdct_map_64 , NULL , NULL , & celt_tx_sr_32 , celt_tx_fft32_ns_float_neon };
152+ static const OpusTXContext celt_tx_mdct_128 = { 128 , 1 , celt_tx_mdct_map_128 , NULL , NULL , & celt_tx_sr_64 , celt_tx_fft_sr_ns_float_neon };
153+ static const OpusTXContext celt_tx_mdct_256 = { 256 , 1 , celt_tx_mdct_map_256 , NULL , NULL , & celt_tx_sr_128 , celt_tx_fft_sr_ns_float_neon };
154+ static const OpusTXContext celt_tx_mdct_512 = { 512 , 1 , celt_tx_mdct_map_512 , NULL , NULL , & celt_tx_sr_256 , celt_tx_fft_sr_ns_float_neon };
155+ static const OpusTXContext celt_tx_mdct_1024 = { 1024 , 1 , celt_tx_mdct_map_1024 , NULL , NULL , & celt_tx_sr_512 , celt_tx_fft_sr_ns_float_neon };
156156#endif
157157
158- static const OpusTXContext * celt_tx_mdct_kernel (int len )
158+ const OpusTXContext * celt_tx_mdct_kernel (int len )
159159{
160160 switch (len ) {
161161 case 120 : return & celt_tx_mdct_120 ;
@@ -185,6 +185,10 @@ void clt_mdct_backward_tx(const mdct_lookup *l, kiss_fft_scalar *in,
185185 int N = l -> n >> shift ;
186186 int N2 = N >> 1 ;
187187 const OpusTXContext * tpl = celt_tx_mdct_kernel (N2 );
188+ const kiss_twiddle_scalar * trig ;
189+ int cur_n ;
190+ VARDECL (kiss_fft_scalar , tmp );
191+ SAVE_STACK ;
188192
189193 if (tpl == NULL )
190194 {
@@ -194,28 +198,37 @@ void clt_mdct_backward_tx(const mdct_lookup *l, kiss_fft_scalar *in,
194198 }
195199 (void )arch ;
196200
201+ trig = l -> trig ;
202+ cur_n = l -> n ;
203+ for (i = 0 ; i < shift ; i ++ ) {
204+ cur_n >>= 1 ;
205+ trig += cur_n ;
206+ }
207+
197208 /* Pre-rotate, N/4 complex FFT and post-rotate, writing the raw N/2
198209 samples to out[overlap/2 ..] like the C code does. For the 15*M sizes,
199210 only the PFA scratch buffer is written through the context tree, so
200211 the two levels that reference it are copied to the stack; the mode
201212 data stays shared and read-only across threads. The power-of-two
202213 sizes run their sub-FFT in place on the output and need no fixup. */
214+ ALLOC (tmp , N2 , kiss_fft_scalar ); /* N/4 complex values */
215+
203216 if (tpl -> fn == celt_tx_fft_pfa_15xM_ns_float_neon )
204217 {
205218 OpusTXContext mdct , pfa ;
206- VARDECL (kiss_fft_scalar , tmp );
207- SAVE_STACK ;
208- ALLOC (tmp , N2 , kiss_fft_scalar ); /* N/4 complex values */
209-
210219 mdct = * tpl ;
220+ mdct .exp = trig ;
221+ mdct .tmp = tmp ;
211222 pfa = * tpl -> sub ;
212223 pfa .tmp = tmp ;
213224 mdct .sub = & pfa ;
214225 celt_tx_mdct_inv_float_neon (& mdct , out + (overlap >>1 ), in ,
215226 (ptrdiff_t )stride * sizeof (kiss_fft_scalar ));
216- RESTORE_STACK ;
217227 } else {
218- celt_tx_mdct_inv_float_neon (tpl , out + (overlap >>1 ), in ,
228+ OpusTXContext mdct = * tpl ;
229+ mdct .exp = trig ;
230+ mdct .tmp = tmp ;
231+ celt_tx_mdct_inv_float_neon (& mdct , out + (overlap >>1 ), in ,
219232 (ptrdiff_t )stride * sizeof (kiss_fft_scalar ));
220233 }
221234
@@ -237,6 +250,7 @@ void clt_mdct_backward_tx(const mdct_lookup *l, kiss_fft_scalar *in,
237250 wp2 -- ;
238251 }
239252 }
253+ RESTORE_STACK ;
240254}
241255
242256#endif /* OPUS_ARM_TX_MDCT */
0 commit comments