@@ -128,7 +128,7 @@ static OPUS_INLINE opus_val32 celt_maxabs32(const opus_val32 *x, int len)
128
128
#endif
129
129
#endif
130
130
131
- #if !defined( FIXED_POINT ) || defined( ENABLE_QEXT )
131
+ #ifndef FIXED_POINT
132
132
/* Calculates the arctangent of x using a Remez approximation of order 15,
133
133
* incorporating only odd-powered terms. */
134
134
static OPUS_INLINE float celt_atan_norm (float x )
@@ -176,7 +176,9 @@ static OPUS_INLINE float celt_atan2p_norm(float y, float x)
176
176
return 1.f - celt_atan_norm (x / y );
177
177
}
178
178
}
179
+ #endif
179
180
181
+ #if !defined(FIXED_POINT ) || defined(ENABLE_QEXT )
180
182
/* Computes estimated cosine values for (PI/2 * x) using only terms with even
181
183
* exponents. */
182
184
static OPUS_INLINE float celt_cos_norm2 (float x )
@@ -521,6 +523,68 @@ opus_val32 celt_rcp(opus_val32 x);
521
523
opus_val32 frac_div32_q29 (opus_val32 a , opus_val32 b );
522
524
opus_val32 frac_div32 (opus_val32 a , opus_val32 b );
523
525
526
+ /* Computes atan(x) multiplied by 2/PI. The input value (x) should be within the
527
+ * range of -1 to 1 and represented in Q30 format. The function will return the
528
+ * result in Q30 format. */
529
+ static OPUS_INLINE opus_val32 celt_atan_norm (opus_val32 x )
530
+ {
531
+ /* Approximation constants. */
532
+ static const opus_int32 ATAN_2_OVER_PI = 1367130551 ; /* Q31 */
533
+ static const opus_int32 ATAN_COEFF_A03 = -715791936 ; /* Q31 */
534
+ static const opus_int32 ATAN_COEFF_A05 = 857391616 ; /* Q32 */
535
+ static const opus_int32 ATAN_COEFF_A07 = -1200579328 ; /* Q33 */
536
+ static const opus_int32 ATAN_COEFF_A09 = 1682636672 ; /* Q34 */
537
+ static const opus_int32 ATAN_COEFF_A11 = -1985085440 ; /* Q35 */
538
+ static const opus_int32 ATAN_COEFF_A13 = 1583306112 ; /* Q36 */
539
+ static const opus_int32 ATAN_COEFF_A15 = -598602432 ; /* Q37 */
540
+ opus_int32 x_sq_q30 ;
541
+ opus_int32 x_q31 ;
542
+ opus_int32 tmp ;
543
+ /* The expected x is in the range of [-1.0f, 1.0f] */
544
+ celt_sig_assert ((x <= 1073741824 ) && (x >= -1073741824 ));
545
+
546
+ /* If x = 1.0f, returns 0.5f */
547
+ if (x == 1073741824 )
548
+ {
549
+ return 536870912 ; /* 0.5f (Q30) */
550
+ }
551
+ /* If x = 1.0f, returns 0.5f */
552
+ if (x == -1073741824 )
553
+ {
554
+ return -536870912 ; /* -0.5f (Q30) */
555
+ }
556
+ x_q31 = SHL32 (x , 1 );
557
+ x_sq_q30 = MULT32_32_Q31 (x_q31 , x );
558
+ /* Split evaluation in steps to avoid exploding macro expansion. */
559
+ tmp = MULT32_32_Q31 (x_sq_q30 , ATAN_COEFF_A15 );
560
+ tmp = MULT32_32_Q31 (x_sq_q30 , ADD32 (ATAN_COEFF_A13 , tmp ));
561
+ tmp = MULT32_32_Q31 (x_sq_q30 , ADD32 (ATAN_COEFF_A11 , tmp ));
562
+ tmp = MULT32_32_Q31 (x_sq_q30 , ADD32 (ATAN_COEFF_A09 , tmp ));
563
+ tmp = MULT32_32_Q31 (x_sq_q30 , ADD32 (ATAN_COEFF_A07 , tmp ));
564
+ tmp = MULT32_32_Q31 (x_sq_q30 , ADD32 (ATAN_COEFF_A05 , tmp ));
565
+ tmp = MULT32_32_Q31 (x_sq_q30 , ADD32 (ATAN_COEFF_A03 , tmp ));
566
+ tmp = ADD32 (x , MULT32_32_Q31 (x_q31 , tmp ));
567
+ return MULT32_32_Q31 (ATAN_2_OVER_PI , tmp );
568
+ }
569
+
570
+ /* Calculates the arctangent of y/x, multiplies the result by 2/pi, and returns
571
+ * the value in Q30 format. Both input values (x and y) must be within the range
572
+ * of 0 to 1 and represented in Q30 format. Inputs must be zero or greater, and
573
+ * at least one input must be non-zero. */
574
+ static OPUS_INLINE opus_val32 celt_atan2p_norm (opus_val32 y , opus_val32 x )
575
+ {
576
+ celt_sig_assert (x >=0 && y >=0 );
577
+ if (y == 0 && x == 0 ) {
578
+ return 0 ;
579
+ } else if (y < x ) {
580
+ return celt_atan_norm (SHR32 (frac_div32 (y , x ), 1 ));
581
+ } else {
582
+ celt_sig_assert (y > 0 );
583
+ return 1073741824 /* 1.0f Q30 */ -
584
+ celt_atan_norm (SHR32 (frac_div32 (x , y ), 1 ));
585
+ }
586
+ }
587
+
524
588
#define M1 32767
525
589
#define M2 -21
526
590
#define M3 -11943
0 commit comments