saturated.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #if !defined(_SPANDSP_SATURATED_H_)
00031 #define _SPANDSP_SATURATED_H_
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #if defined(__cplusplus)
00043 extern "C"
00044 {
00045 #endif
00046
00047 static __inline__ int16_t saturate(int32_t amp)
00048 {
00049 int16_t amp16;
00050
00051
00052 amp16 = (int16_t) amp;
00053 if (amp == amp16)
00054 return amp16;
00055 if (amp > INT16_MAX)
00056 return INT16_MAX;
00057 return INT16_MIN;
00058 }
00059
00060
00061
00062 static __inline__ int16_t saturate15(int32_t amp)
00063 {
00064 if (amp > 16383)
00065 return 16383;
00066 if (amp < -16384)
00067 return -16384;
00068 return (int16_t) amp;
00069 }
00070
00071
00072 static __inline__ int16_t fsaturatef(float famp)
00073 {
00074 if (famp > (float) INT16_MAX)
00075 return INT16_MAX;
00076 if (famp < (float) INT16_MIN)
00077 return INT16_MIN;
00078 return (int16_t) lrintf(famp);
00079 }
00080
00081
00082 static __inline__ int16_t fsaturate(double damp)
00083 {
00084 if (damp > (double) INT16_MAX)
00085 return INT16_MAX;
00086 if (damp < (double) INT16_MIN)
00087 return INT16_MIN;
00088 return (int16_t) lrint(damp);
00089 }
00090
00091
00092
00093 static __inline__ int16_t ffastsaturatef(float famp)
00094 {
00095 if (famp > (float) INT16_MAX)
00096 return INT16_MAX;
00097 if (famp < (float) INT16_MIN)
00098 return INT16_MIN;
00099 return (int16_t) lfastrintf(famp);
00100 }
00101
00102
00103
00104 static __inline__ int16_t ffastsaturate(double damp)
00105 {
00106 if (damp > (double) INT16_MAX)
00107 return INT16_MAX;
00108 if (damp < (double) INT16_MIN)
00109 return INT16_MIN;
00110 return (int16_t) lfastrint(damp);
00111 }
00112
00113
00114
00115 static __inline__ float ffsaturatef(float famp)
00116 {
00117 if (famp > (float) INT16_MAX)
00118 return (float) INT16_MAX;
00119 if (famp < (float) INT16_MIN)
00120 return (float) INT16_MIN;
00121 return famp;
00122 }
00123
00124
00125
00126 static __inline__ double ffsaturate(double famp)
00127 {
00128 if (famp > (double) INT16_MAX)
00129 return (double) INT16_MAX;
00130 if (famp < (double) INT16_MIN)
00131 return (double) INT16_MIN;
00132 return famp;
00133 }
00134
00135
00136 static __inline__ int16_t saturated_add16(int16_t a, int16_t b)
00137 {
00138 #if defined(__GNUC__) && defined(__i386__)
00139 __asm__ __volatile__(
00140 " addw %2,%0;\n"
00141 " jno 0f;\n"
00142 " movw $0x7fff,%0;\n"
00143 " adcw $0,%0;\n"
00144 "0:"
00145 : "=r" (a)
00146 : "0" (a), "ir" (b)
00147 : "cc"
00148 );
00149 return a;
00150 #else
00151 return saturate((int32_t) a + (int32_t) b);
00152 #endif
00153 }
00154
00155
00156 static __inline__ int32_t saturated_add32(int32_t a, int32_t b)
00157 {
00158 #if defined(__GNUC__) && defined(__i386__)
00159 __asm__ __volatile__(
00160 " addl %2,%0;\n"
00161 " jno 0f;\n"
00162 " movl $0x7fffffff,%0;\n"
00163 " adcl $0,%0;\n"
00164 "0:"
00165 : "=r" (a)
00166 : "0" (a), "ir" (b)
00167 : "cc"
00168 );
00169 return a;
00170 #else
00171 uint32_t A;
00172
00173 if (a < 0)
00174 {
00175 if (b >= 0)
00176 return a + b;
00177
00178 A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1);
00179 return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2;
00180 }
00181
00182 if (b <= 0)
00183 return a + b;
00184
00185 A = (uint32_t) a + (uint32_t) b;
00186 return (A > INT32_MAX) ? INT32_MAX : A;
00187 #endif
00188 }
00189
00190
00191 static __inline__ int16_t saturated_sub16(int16_t a, int16_t b)
00192 {
00193 return saturate((int32_t) a - (int32_t) b);
00194 }
00195
00196
00197 static __inline__ int16_t saturated_mul16(int16_t a, int16_t b)
00198 {
00199 if (a == INT16_MIN && b == INT16_MIN)
00200 return INT16_MAX;
00201
00202 return (int16_t) (((int32_t) a*(int32_t) b) >> 15);
00203 }
00204
00205
00206 static __inline__ int32_t saturated_mul_16_32(int16_t a, int16_t b)
00207 {
00208 return ((int32_t) a*(int32_t) b) << 1;
00209 }
00210
00211
00212 static __inline__ int16_t saturated_abs16(int16_t a)
00213 {
00214 return (a == INT16_MIN) ? INT16_MAX : (int16_t) abs(a);
00215 }
00216
00217
00218 #if defined(__cplusplus)
00219 }
00220 #endif
00221
00222 #endif
00223