@@ -786,7 +786,7 @@ unsigned cubic_quant(celt_norm *X, int N, int res, int B, ec_enc *enc, opus_val3
786786 int K ;
787787 VARDECL (int , iy );
788788 celt_norm faceval = -1 ;
789- float norm ;
789+ opus_val32 norm ;
790790 int sign ;
791791 SAVE_STACK ;
792792 ALLOC (iy , N , int );
@@ -795,6 +795,7 @@ unsigned cubic_quant(celt_norm *X, int N, int res, int B, ec_enc *enc, opus_val3
795795 if (B != 1 ) K = IMAX (1 , K - 1 );
796796 if (K == 1 ) {
797797 if (resynth ) OPUS_CLEAR (X , N );
798+ RESTORE_STACK ;
798799 return 0 ;
799800 }
800801 for (i = 0 ;i < N ;i ++ ) {
@@ -806,9 +807,25 @@ unsigned cubic_quant(celt_norm *X, int N, int res, int B, ec_enc *enc, opus_val3
806807 sign = X [face ]< 0 ;
807808 ec_enc_uint (enc , face , N );
808809 ec_enc_bits (enc , sign , 1 );
810+ #ifdef FIXED_POINT
811+ if (faceval != 0 ) {
812+ int face_shift = 30 - celt_ilog2 (faceval );
813+ norm = celt_rcp_norm32 (SHL32 (faceval , face_shift ));
814+ norm = MULT16_32_Q15 (K , norm );
815+ for (i = 0 ;i < N ;i ++ ) {
816+ /* By computing X[i]+faceval inside the shift, the result is guaranteed non-negative. */
817+ iy [i ] = IMIN (K - 1 , (MULT32_32_Q31 (SHL32 (X [i ]+ faceval , face_shift - 1 ), norm )) >> 15 );
818+ }
819+ } else {
820+ OPUS_CLEAR (iy , N );
821+ }
822+ #else
809823 norm = .5f * K /(faceval + EPSILON );
810824 for (i = 0 ;i < N ;i ++ ) {
811825 iy [i ] = IMIN (K - 1 , (int )floor ((X [i ]+ faceval )* norm ));
826+ }
827+ #endif
828+ for (i = 0 ;i < N ;i ++ ) {
812829 if (i != face ) ec_enc_bits (enc , iy [i ], res );
813830 }
814831 if (resynth ) {
0 commit comments