PageRenderTime 52ms CodeModel.GetById 16ms app.highlight 29ms RepoModel.GetById 2ms app.codeStats 0ms

/project/jni/sndfile/src/GSM610/add.c

https://github.com/aichunyu/FFPlayer
C | 240 lines | 149 code | 34 blank | 57 comment | 45 complexity | 270603e40fe71ff71afe61ebaf738a1f MD5 | raw file
  1/*
  2 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische
  3 * Universitaet Berlin.  See the accompanying file "COPYRIGHT" for
  4 * details.  THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
  5 */
  6
  7/*
  8 *  See private.h for the more commonly used macro versions.
  9 */
 10
 11#include	<stdio.h>
 12#include	<assert.h>
 13
 14#include	"gsm610_priv.h"
 15
 16#define	saturate(x) 	\
 17	((x) < MIN_WORD ? MIN_WORD : (x) > MAX_WORD ? MAX_WORD: (x))
 18
 19word gsm_add ( word a, word b)
 20{
 21	longword sum = (longword)a + (longword)b;
 22	return saturate(sum);
 23}
 24
 25word gsm_sub ( word a, word b)
 26{
 27	longword diff = (longword)a - (longword)b;
 28	return saturate(diff);
 29}
 30
 31word gsm_mult ( word a, word b)
 32{
 33	if (a == MIN_WORD && b == MIN_WORD)
 34		return MAX_WORD;
 35	
 36	return SASR_L( (longword)a * (longword)b, 15 );
 37}
 38
 39word gsm_mult_r ( word a, word b)
 40{
 41	if (b == MIN_WORD && a == MIN_WORD) return MAX_WORD;
 42	else {
 43		longword prod = (longword)a * (longword)b + 16384;
 44		prod >>= 15;
 45		return prod & 0xFFFF;
 46	}
 47}
 48
 49word gsm_abs (word a)
 50{
 51	return a < 0 ? (a == MIN_WORD ? MAX_WORD : -a) : a;
 52}
 53
 54longword gsm_L_mult (word a, word b)
 55{
 56	assert( a != MIN_WORD || b != MIN_WORD );
 57	return ((longword)a * (longword)b) << 1;
 58}
 59
 60longword gsm_L_add ( longword a, longword b)
 61{
 62	if (a < 0) {
 63		if (b >= 0) return a + b;
 64		else {
 65			ulongword A = (ulongword)-(a + 1) + (ulongword)-(b + 1);
 66			return A >= MAX_LONGWORD ? MIN_LONGWORD :-(longword)A-2;
 67		}
 68	}
 69	else if (b <= 0) return a + b;
 70	else {
 71		ulongword A = (ulongword)a + (ulongword)b;
 72		return A > MAX_LONGWORD ? MAX_LONGWORD : A;
 73	}
 74}
 75
 76longword gsm_L_sub ( longword a, longword b)
 77{
 78	if (a >= 0) {
 79		if (b >= 0) return a - b;
 80		else {
 81			/* a>=0, b<0 */
 82
 83			ulongword A = (ulongword)a + -(b + 1);
 84			return A >= MAX_LONGWORD ? MAX_LONGWORD : (A + 1);
 85		}
 86	}
 87	else if (b <= 0) return a - b;
 88	else {
 89		/* a<0, b>0 */  
 90
 91		ulongword A = (ulongword)-(a + 1) + b;
 92		return A >= MAX_LONGWORD ? MIN_LONGWORD : -(longword)A - 1;
 93	}
 94}
 95
 96static unsigned char const bitoff[ 256 ] = {
 97	 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
 98	 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
 99	 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
100	 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
101	 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
102	 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
103	 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
104	 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
109	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
110	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
111	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
112	 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
113};
114
115word gsm_norm (longword a )
116/*
117 * the number of left shifts needed to normalize the 32 bit
118 * variable L_var1 for positive values on the interval
119 *
120 * with minimum of
121 * minimum of 1073741824  (01000000000000000000000000000000) and 
122 * maximum of 2147483647  (01111111111111111111111111111111)
123 *
124 *
125 * and for negative values on the interval with
126 * minimum of -2147483648 (-10000000000000000000000000000000) and
127 * maximum of -1073741824 ( -1000000000000000000000000000000).
128 *
129 * in order to normalize the result, the following
130 * operation must be done: L_norm_var1 = L_var1 << norm( L_var1 );
131 *
132 * (That's 'ffs', only from the left, not the right..)
133 */
134{
135	assert(a != 0);
136
137	if (a < 0) {
138		if (a <= -1073741824) return 0;
139		a = ~a;
140	}
141
142	return    a & 0xffff0000 
143		? ( a & 0xff000000
144		  ?  -1 + bitoff[ 0xFF & (a >> 24) ]
145		  :   7 + bitoff[ 0xFF & (a >> 16) ] )
146		: ( a & 0xff00
147		  ?  15 + bitoff[ 0xFF & (a >> 8) ]
148		  :  23 + bitoff[ 0xFF & a ] );
149}
150
151longword gsm_L_asl (longword a, int n)
152{
153	if (n >= 32) return 0;
154	if (n <= -32) return -(a < 0);
155	if (n < 0) return gsm_L_asr(a, -n);
156	return a << n;
157}
158
159word gsm_asr (word a, int n)
160{
161	if (n >= 16) return -(a < 0);
162	if (n <= -16) return 0;
163	if (n < 0) return a << -n;
164
165	return SASR_W (a, (word) n);
166}
167
168word gsm_asl (word a, int n)
169{
170	if (n >= 16) return 0;
171	if (n <= -16) return -(a < 0);
172	if (n < 0) return gsm_asr(a, -n);
173	return a << n;
174}
175
176longword gsm_L_asr (longword a, int n)
177{
178	if (n >= 32) return -(a < 0);
179	if (n <= -32) return 0;
180	if (n < 0) return a << -n;
181
182	return SASR_L (a, (word) n);
183}
184
185/*
186**	word gsm_asr (word a, int n)
187**	{
188**		if (n >= 16) return -(a < 0);
189**		if (n <= -16) return 0;
190**		if (n < 0) return a << -n;
191**	
192**	#	ifdef	SASR_W
193**			return a >> n;
194**	#	else
195**			if (a >= 0) return a >> n;
196**			else return -(word)( -(uword)a >> n );
197**	#	endif
198**	}
199**	
200*/
201/* 
202 *  (From p. 46, end of section 4.2.5)
203 *
204 *  NOTE: The following lines gives [sic] one correct implementation
205 *  	  of the div(num, denum) arithmetic operation.  Compute div
206 *        which is the integer division of num by denum: with denum
207 *	  >= num > 0
208 */
209
210word gsm_div (word num, word denum)
211{
212	longword	L_num   = num;
213	longword	L_denum = denum;
214	word		div 	= 0;
215	int		k 	= 15;
216
217	/* The parameter num sometimes becomes zero.
218	 * Although this is explicitly guarded against in 4.2.5,
219	 * we assume that the result should then be zero as well.
220	 */
221
222	/* assert(num != 0); */
223
224	assert(num >= 0 && denum >= num);
225	if (num == 0)
226	    return 0;
227
228	while (k--) {
229		div   <<= 1;
230		L_num <<= 1;
231
232		if (L_num >= L_denum) {
233			L_num -= L_denum;
234			div++;
235		}
236	}
237
238	return div;
239}
240