[opus] QCONST16 cross compile inconsistency

Pedro Becerra pbecerr at gmail.com
Wed Jul 24 16:42:41 PDT 2013


Greetings,

I have found that QCONST16(32.f, 10) yields different result
(from gcc 4.4.7 ) when the code is compiled for TI C55 or
C64 DSPs.

gcc - result is 32767
TI compiler result is -32768 (C55 compiler version 4.4.1 and
C6x compiler version 7.4.2)

Although not in the current code, QCONST32(32.f, 26) results
differ in similar fashion.

Judging by the use #ifdef TI_C.. in the code base, these TI
processors have had some level of cross compile support.
It is with that understanding that I submit for your
consideration the attached patch with one solution that
addresses this issue.
The changed macros continue to be compile-time constant generators
for gcc and the TI compilers.

thank you
--
Pedro Becerra
-------------- next part --------------
diff --git a/celt/arch.h b/celt/arch.h
index e497a4d..6511667 100644
--- a/celt/arch.h
+++ b/celt/arch.h
@@ -107,6 +107,18 @@ typedef opus_val32 celt_ener;
 #define SCALEIN(a)      (a)
 #define SCALEOUT(a)     (a)
 
+/** Compile-time conversion of float constant to 16-bit value */
+#define QCONST16(x,bits)  (opus_val16)(                                 \
+    (( 0.5 + (double)(x) * ((opus_val32)(1)<<(bits)) ) >= (double)(INT16_MAX) ) ? \
+    (opus_val16)(INT16_MAX) :                                           \
+    (opus_val16)( 0.5 + (double)(x) * (double)((opus_val32)(1)<<(bits))) )
+
+/** Compile-time conversion of float constant to 32-bit value */
+#define QCONST32(x,bits)  (opus_val32)(                                 \
+    (( 0.5 + (double)(x) * ((opus_val32)(1)<<(bits)) ) >= (double)(INT32_MAX) ) ? \
+    (opus_val32)(INT32_MAX) :                                           \
+    (opus_val32)( 0.5 + (double)(x) * (double)((opus_val32)(1)<<(bits))) )
+
 #ifdef FIXED_DEBUG
 #include "fixed_debug.h"
 #else
diff --git a/celt/fixed_debug.h b/celt/fixed_debug.h
index f11d890..a479b81 100644
--- a/celt/fixed_debug.h
+++ b/celt/fixed_debug.h
@@ -49,9 +49,6 @@ extern opus_int64 celt_mips;
 
 #define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
 
-#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
-#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
-
 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
 #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
diff --git a/celt/fixed_generic.h b/celt/fixed_generic.h
index ac01a43..0b17563 100644
--- a/celt/fixed_generic.h
+++ b/celt/fixed_generic.h
@@ -48,12 +48,6 @@
 /** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
 #define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
 
-/** Compile-time conversion of float constant to 16-bit value */
-#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
-
-/** Compile-time conversion of float constant to 32-bit value */
-#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
-
 /** Negate a 16-bit value */
 #define NEG16(x) (-(x))
 /** Negate a 32-bit value */


More information about the opus mailing list