fixes overflows in celt_iir() by doing proper saturation
[opus.git] / celt / fixed_debug.h
1 /* Copyright (C) 2003-2008 Jean-Marc Valin
2    Copyright (C) 2007-2012 Xiph.Org Foundation */
3 /**
4    @file fixed_debug.h
5    @brief Fixed-point operations with debugging
6 */
7 /*
8    Redistribution and use in source and binary forms, with or without
9    modification, are permitted provided that the following conditions
10    are met:
11
12    - Redistributions of source code must retain the above copyright
13    notice, this list of conditions and the following disclaimer.
14
15    - Redistributions in binary form must reproduce the above copyright
16    notice, this list of conditions and the following disclaimer in the
17    documentation and/or other materials provided with the distribution.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
23    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef FIXED_DEBUG_H
33 #define FIXED_DEBUG_H
34
35 #include <stdio.h>
36 #include "opus_defines.h"
37
38 #ifdef CELT_C
39 OPUS_EXPORT opus_int64 celt_mips=0;
40 #else
41 extern opus_int64 celt_mips;
42 #endif
43
44 #define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
45 #define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15))
46
47 /** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
48 #define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16))
49
50 #define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16)
51
52 #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
53 #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
54
55 #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
56 #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)
57 #define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1))
58
59 #define SHR(a,b) SHR32(a,b)
60 #define PSHR(a,b) PSHR32(a,b)
61
62 /** Add two 32-bit values, ignore any overflows */
63 #define ADD32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)+(opus_uint32)(b)))
64 /** Subtract two 32-bit values, ignore any overflows  */
65 #define SUB32_ovflw(a,b) (celt_mips+=2,(opus_val32)((opus_uint32)(a)-(opus_uint32)(b)))
66 #define NEG32_ovflw(a) (celt_mips+=2,(opus_val32)(-(opus_uint32)(a)))
67
68 static OPUS_INLINE short NEG16(int x)
69 {
70    int res;
71    if (!VERIFY_SHORT(x))
72    {
73       fprintf (stderr, "NEG16: input is not short: %d\n", (int)x);
74 #ifdef FIXED_DEBUG_ASSERT
75       celt_assert(0);
76 #endif
77    }
78    res = -x;
79    if (!VERIFY_SHORT(res))
80    {
81       fprintf (stderr, "NEG16: output is not short: %d\n", (int)res);
82 #ifdef FIXED_DEBUG_ASSERT
83       celt_assert(0);
84 #endif
85    }
86    celt_mips++;
87    return res;
88 }
89 static OPUS_INLINE int NEG32(opus_int64 x)
90 {
91    opus_int64 res;
92    if (!VERIFY_INT(x))
93    {
94       fprintf (stderr, "NEG16: input is not int: %d\n", (int)x);
95 #ifdef FIXED_DEBUG_ASSERT
96       celt_assert(0);
97 #endif
98    }
99    res = -x;
100    if (!VERIFY_INT(res))
101    {
102       fprintf (stderr, "NEG16: output is not int: %d\n", (int)res);
103 #ifdef FIXED_DEBUG_ASSERT
104       celt_assert(0);
105 #endif
106    }
107    celt_mips+=2;
108    return res;
109 }
110
111 #define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__)
112 static OPUS_INLINE short EXTRACT16_(int x, char *file, int line)
113 {
114    int res;
115    if (!VERIFY_SHORT(x))
116    {
117       fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line);
118 #ifdef FIXED_DEBUG_ASSERT
119       celt_assert(0);
120 #endif
121    }
122    res = x;
123    celt_mips++;
124    return res;
125 }
126
127 #define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__)
128 static OPUS_INLINE int EXTEND32_(int x, char *file, int line)
129 {
130    int res;
131    if (!VERIFY_SHORT(x))
132    {
133       fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line);
134 #ifdef FIXED_DEBUG_ASSERT
135       celt_assert(0);
136 #endif
137    }
138    res = x;
139    celt_mips++;
140    return res;
141 }
142
143 #define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__)
144 static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line)
145 {
146    int res;
147    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
148    {
149       fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line);
150 #ifdef FIXED_DEBUG_ASSERT
151       celt_assert(0);
152 #endif
153    }
154    res = a>>shift;
155    if (!VERIFY_SHORT(res))
156    {
157       fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line);
158 #ifdef FIXED_DEBUG_ASSERT
159       celt_assert(0);
160 #endif
161    }
162    celt_mips++;
163    return res;
164 }
165 #define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__)
166 static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line)
167 {
168    int res;
169    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift))
170    {
171       fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line);
172 #ifdef FIXED_DEBUG_ASSERT
173       celt_assert(0);
174 #endif
175    }
176    res = a<<shift;
177    if (!VERIFY_SHORT(res))
178    {
179       fprintf (stderr, "SHL16: output is not short: %d in %s: line %d\n", res, file, line);
180 #ifdef FIXED_DEBUG_ASSERT
181       celt_assert(0);
182 #endif
183    }
184    celt_mips++;
185    return res;
186 }
187
188 static OPUS_INLINE int SHR32(opus_int64 a, int shift)
189 {
190    opus_int64  res;
191    if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
192    {
193       fprintf (stderr, "SHR32: inputs are not int: %d %d\n", (int)a, shift);
194 #ifdef FIXED_DEBUG_ASSERT
195       celt_assert(0);
196 #endif
197    }
198    res = a>>shift;
199    if (!VERIFY_INT(res))
200    {
201       fprintf (stderr, "SHR32: output is not int: %d\n", (int)res);
202 #ifdef FIXED_DEBUG_ASSERT
203       celt_assert(0);
204 #endif
205    }
206    celt_mips+=2;
207    return res;
208 }
209 #define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__)
210 static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line)
211 {
212    opus_int64  res;
213    if (!VERIFY_INT(a) || !VERIFY_SHORT(shift))
214    {
215       fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line);
216 #ifdef FIXED_DEBUG_ASSERT
217       celt_assert(0);
218 #endif
219    }
220    res = a<<shift;
221    if (!VERIFY_INT(res))
222    {
223       fprintf (stderr, "SHL32: output is not int: %lld<<%d = %lld in %s: line %d\n", a, shift, res, file, line);
224 #ifdef FIXED_DEBUG_ASSERT
225       celt_assert(0);
226 #endif
227    }
228    celt_mips+=2;
229    return res;
230 }
231
232 #define PSHR32(a,shift) (celt_mips--,SHR32(ADD32((a),(((opus_val32)(1)<<((shift))>>1))),shift))
233 #define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift)))
234
235 #define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a))))
236 #define SROUND16(x,a) (celt_mips--,EXTRACT16(SATURATE(PSHR32(x,a), 32767)));
237
238 #define HALF16(x)  (SHR16(x,1))
239 #define HALF32(x)  (SHR32(x,1))
240
241 //#define SHR(a,shift) ((a) >> (shift))
242 //#define SHL(a,shift) ((a) << (shift))
243
244 #define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__)
245 static OPUS_INLINE short ADD16_(int a, int b, char *file, int line)
246 {
247    int res;
248    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
249    {
250       fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
251 #ifdef FIXED_DEBUG_ASSERT
252       celt_assert(0);
253 #endif
254    }
255    res = a+b;
256    if (!VERIFY_SHORT(res))
257    {
258       fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line);
259 #ifdef FIXED_DEBUG_ASSERT
260       celt_assert(0);
261 #endif
262    }
263    celt_mips++;
264    return res;
265 }
266
267 #define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__)
268 static OPUS_INLINE short SUB16_(int a, int b, char *file, int line)
269 {
270    int res;
271    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
272    {
273       fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
274 #ifdef FIXED_DEBUG_ASSERT
275       celt_assert(0);
276 #endif
277    }
278    res = a-b;
279    if (!VERIFY_SHORT(res))
280    {
281       fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line);
282 #ifdef FIXED_DEBUG_ASSERT
283       celt_assert(0);
284 #endif
285    }
286    celt_mips++;
287    return res;
288 }
289
290 #define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__)
291 static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line)
292 {
293    opus_int64 res;
294    if (!VERIFY_INT(a) || !VERIFY_INT(b))
295    {
296       fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
297 #ifdef FIXED_DEBUG_ASSERT
298       celt_assert(0);
299 #endif
300    }
301    res = a+b;
302    if (!VERIFY_INT(res))
303    {
304       fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line);
305 #ifdef FIXED_DEBUG_ASSERT
306       celt_assert(0);
307 #endif
308    }
309    celt_mips+=2;
310    return res;
311 }
312
313 #define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__)
314 static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line)
315 {
316    opus_int64 res;
317    if (!VERIFY_INT(a) || !VERIFY_INT(b))
318    {
319       fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
320 #ifdef FIXED_DEBUG_ASSERT
321       celt_assert(0);
322 #endif
323    }
324    res = a-b;
325    if (!VERIFY_INT(res))
326    {
327       fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line);
328 #ifdef FIXED_DEBUG_ASSERT
329       celt_assert(0);
330 #endif
331    }
332    celt_mips+=2;
333    return res;
334 }
335
336 #undef UADD32
337 #define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__)
338 static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line)
339 {
340    opus_uint64 res;
341    if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
342    {
343       fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
344 #ifdef FIXED_DEBUG_ASSERT
345       celt_assert(0);
346 #endif
347    }
348    res = a+b;
349    if (!VERIFY_UINT(res))
350    {
351       fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line);
352 #ifdef FIXED_DEBUG_ASSERT
353       celt_assert(0);
354 #endif
355    }
356    celt_mips+=2;
357    return res;
358 }
359
360 #undef USUB32
361 #define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__)
362 static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line)
363 {
364    opus_uint64 res;
365    if (!VERIFY_UINT(a) || !VERIFY_UINT(b))
366    {
367       fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line);
368 #ifdef FIXED_DEBUG_ASSERT
369       celt_assert(0);
370 #endif
371    }
372    if (a<b)
373    {
374       fprintf (stderr, "USUB32: inputs underflow: %llu < %llu in %s: line %d\n", a, b, file, line);
375 #ifdef FIXED_DEBUG_ASSERT
376       celt_assert(0);
377 #endif
378    }
379    res = a-b;
380    if (!VERIFY_UINT(res))
381    {
382       fprintf (stderr, "USUB32: output is not uint32: %llu - %llu = %llu in %s: line %d\n", a, b, res, file, line);
383 #ifdef FIXED_DEBUG_ASSERT
384       celt_assert(0);
385 #endif
386    }
387    celt_mips+=2;
388    return res;
389 }
390
391 /* result fits in 16 bits */
392 static OPUS_INLINE short MULT16_16_16(int a, int b)
393 {
394    int res;
395    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
396    {
397       fprintf (stderr, "MULT16_16_16: inputs are not short: %d %d\n", a, b);
398 #ifdef FIXED_DEBUG_ASSERT
399       celt_assert(0);
400 #endif
401    }
402    res = a*b;
403    if (!VERIFY_SHORT(res))
404    {
405       fprintf (stderr, "MULT16_16_16: output is not short: %d\n", res);
406 #ifdef FIXED_DEBUG_ASSERT
407       celt_assert(0);
408 #endif
409    }
410    celt_mips++;
411    return res;
412 }
413
414 #define MULT16_16(a, b) MULT16_16_(a, b, __FILE__, __LINE__)
415 static OPUS_INLINE int MULT16_16_(int a, int b, char *file, int line)
416 {
417    opus_int64 res;
418    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
419    {
420       fprintf (stderr, "MULT16_16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
421 #ifdef FIXED_DEBUG_ASSERT
422       celt_assert(0);
423 #endif
424    }
425    res = ((opus_int64)a)*b;
426    if (!VERIFY_INT(res))
427    {
428       fprintf (stderr, "MULT16_16: output is not int: %d in %s: line %d\n", (int)res, file, line);
429 #ifdef FIXED_DEBUG_ASSERT
430       celt_assert(0);
431 #endif
432    }
433    celt_mips++;
434    return res;
435 }
436
437 #define MAC16_16(c,a,b)     (celt_mips-=2,ADD32((c),MULT16_16((a),(b))))
438
439 #define MULT16_32_QX(a, b, Q) MULT16_32_QX_(a, b, Q, __FILE__, __LINE__)
440 static OPUS_INLINE int MULT16_32_QX_(int a, opus_int64 b, int Q, char *file, int line)
441 {
442    opus_int64 res;
443    if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
444    {
445       fprintf (stderr, "MULT16_32_Q%d: inputs are not short+int: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
446 #ifdef FIXED_DEBUG_ASSERT
447       celt_assert(0);
448 #endif
449    }
450    if (ABS32(b)>=((opus_val32)(1)<<(15+Q)))
451    {
452       fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line);
453 #ifdef FIXED_DEBUG_ASSERT
454       celt_assert(0);
455 #endif
456    }
457    res = (((opus_int64)a)*(opus_int64)b) >> Q;
458    if (!VERIFY_INT(res))
459    {
460       fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line);
461 #ifdef FIXED_DEBUG_ASSERT
462       celt_assert(0);
463 #endif
464    }
465    if (Q==15)
466       celt_mips+=3;
467    else
468       celt_mips+=4;
469    return res;
470 }
471
472 #define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__)
473 static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line)
474 {
475    opus_int64 res;
476    if (!VERIFY_SHORT(a) || !VERIFY_INT(b))
477    {
478       fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line);
479 #ifdef FIXED_DEBUG_ASSERT
480       celt_assert(0);
481 #endif
482    }
483    if (ABS32(b)>=((opus_int64)(1)<<(15+Q)))
484    {
485       fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line);
486 #ifdef FIXED_DEBUG_ASSERT
487       celt_assert(0);
488 #endif
489    }
490    res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<<Q)>>1))>> Q;
491    if (!VERIFY_INT(res))
492    {
493       fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line);
494 #ifdef FIXED_DEBUG_ASSERT
495       celt_assert(0);
496 #endif
497    }
498    if (Q==15)
499       celt_mips+=4;
500    else
501       celt_mips+=5;
502    return res;
503 }
504
505 #define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15)
506 #define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b))))
507 #define MAC16_32_Q16(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q16((a),(b))))
508
509 static OPUS_INLINE int SATURATE(int a, int b)
510 {
511    if (a>b)
512       a=b;
513    if (a<-b)
514       a = -b;
515    celt_mips+=3;
516    return a;
517 }
518
519 static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a)
520 {
521    celt_mips+=3;
522    if (a>32767)
523       return 32767;
524    else if (a<-32768)
525       return -32768;
526    else return a;
527 }
528
529 static OPUS_INLINE int MULT16_16_Q11_32(int a, int b)
530 {
531    opus_int64 res;
532    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
533    {
534       fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b);
535 #ifdef FIXED_DEBUG_ASSERT
536       celt_assert(0);
537 #endif
538    }
539    res = ((opus_int64)a)*b;
540    res >>= 11;
541    if (!VERIFY_INT(res))
542    {
543       fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res);
544 #ifdef FIXED_DEBUG_ASSERT
545       celt_assert(0);
546 #endif
547    }
548    celt_mips+=3;
549    return res;
550 }
551 static OPUS_INLINE short MULT16_16_Q13(int a, int b)
552 {
553    opus_int64 res;
554    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
555    {
556       fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b);
557 #ifdef FIXED_DEBUG_ASSERT
558       celt_assert(0);
559 #endif
560    }
561    res = ((opus_int64)a)*b;
562    res >>= 13;
563    if (!VERIFY_SHORT(res))
564    {
565       fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res);
566 #ifdef FIXED_DEBUG_ASSERT
567       celt_assert(0);
568 #endif
569    }
570    celt_mips+=3;
571    return res;
572 }
573 static OPUS_INLINE short MULT16_16_Q14(int a, int b)
574 {
575    opus_int64 res;
576    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
577    {
578       fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b);
579 #ifdef FIXED_DEBUG_ASSERT
580       celt_assert(0);
581 #endif
582    }
583    res = ((opus_int64)a)*b;
584    res >>= 14;
585    if (!VERIFY_SHORT(res))
586    {
587       fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res);
588 #ifdef FIXED_DEBUG_ASSERT
589       celt_assert(0);
590 #endif
591    }
592    celt_mips+=3;
593    return res;
594 }
595
596 #define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__)
597 static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line)
598 {
599    opus_int64 res;
600    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
601    {
602       fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line);
603 #ifdef FIXED_DEBUG_ASSERT
604       celt_assert(0);
605 #endif
606    }
607    res = ((opus_int64)a)*b;
608    res >>= 15;
609    if (!VERIFY_SHORT(res))
610    {
611       fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line);
612 #ifdef FIXED_DEBUG_ASSERT
613       celt_assert(0);
614 #endif
615    }
616    celt_mips+=1;
617    return res;
618 }
619
620 static OPUS_INLINE short MULT16_16_P13(int a, int b)
621 {
622    opus_int64 res;
623    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
624    {
625       fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b);
626 #ifdef FIXED_DEBUG_ASSERT
627       celt_assert(0);
628 #endif
629    }
630    res = ((opus_int64)a)*b;
631    res += 4096;
632    if (!VERIFY_INT(res))
633    {
634       fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res);
635 #ifdef FIXED_DEBUG_ASSERT
636       celt_assert(0);
637 #endif
638    }
639    res >>= 13;
640    if (!VERIFY_SHORT(res))
641    {
642       fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res);
643 #ifdef FIXED_DEBUG_ASSERT
644       celt_assert(0);
645 #endif
646    }
647    celt_mips+=4;
648    return res;
649 }
650 static OPUS_INLINE short MULT16_16_P14(int a, int b)
651 {
652    opus_int64 res;
653    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
654    {
655       fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b);
656 #ifdef FIXED_DEBUG_ASSERT
657       celt_assert(0);
658 #endif
659    }
660    res = ((opus_int64)a)*b;
661    res += 8192;
662    if (!VERIFY_INT(res))
663    {
664       fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res);
665 #ifdef FIXED_DEBUG_ASSERT
666       celt_assert(0);
667 #endif
668    }
669    res >>= 14;
670    if (!VERIFY_SHORT(res))
671    {
672       fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res);
673 #ifdef FIXED_DEBUG_ASSERT
674       celt_assert(0);
675 #endif
676    }
677    celt_mips+=4;
678    return res;
679 }
680 static OPUS_INLINE short MULT16_16_P15(int a, int b)
681 {
682    opus_int64 res;
683    if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b))
684    {
685       fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b);
686 #ifdef FIXED_DEBUG_ASSERT
687       celt_assert(0);
688 #endif
689    }
690    res = ((opus_int64)a)*b;
691    res += 16384;
692    if (!VERIFY_INT(res))
693    {
694       fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res);
695 #ifdef FIXED_DEBUG_ASSERT
696       celt_assert(0);
697 #endif
698    }
699    res >>= 15;
700    if (!VERIFY_SHORT(res))
701    {
702       fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res);
703 #ifdef FIXED_DEBUG_ASSERT
704       celt_assert(0);
705 #endif
706    }
707    celt_mips+=2;
708    return res;
709 }
710
711 #define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__)
712
713 static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line)
714 {
715    opus_int64 res;
716    if (b==0)
717    {
718       fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
719 #ifdef FIXED_DEBUG_ASSERT
720       celt_assert(0);
721 #endif
722       return 0;
723    }
724    if (!VERIFY_INT(a) || !VERIFY_SHORT(b))
725    {
726       fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
727 #ifdef FIXED_DEBUG_ASSERT
728       celt_assert(0);
729 #endif
730    }
731    res = a/b;
732    if (!VERIFY_SHORT(res))
733    {
734       fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line);
735       if (res>32767)
736          res = 32767;
737       if (res<-32768)
738          res = -32768;
739 #ifdef FIXED_DEBUG_ASSERT
740       celt_assert(0);
741 #endif
742    }
743    celt_mips+=35;
744    return res;
745 }
746
747 #define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__)
748 static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line)
749 {
750    opus_int64 res;
751    if (b==0)
752    {
753       fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line);
754 #ifdef FIXED_DEBUG_ASSERT
755       celt_assert(0);
756 #endif
757       return 0;
758    }
759
760    if (!VERIFY_INT(a) || !VERIFY_INT(b))
761    {
762       fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line);
763 #ifdef FIXED_DEBUG_ASSERT
764       celt_assert(0);
765 #endif
766    }
767    res = a/b;
768    if (!VERIFY_INT(res))
769    {
770       fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line);
771 #ifdef FIXED_DEBUG_ASSERT
772       celt_assert(0);
773 #endif
774    }
775    celt_mips+=70;
776    return res;
777 }
778
779 static OPUS_INLINE opus_val16 SIG2WORD16_generic(celt_sig x)
780 {
781    x = PSHR32(x, SIG_SHIFT);
782    x = MAX32(x, -32768);
783    x = MIN32(x, 32767);
784    return EXTRACT16(x);
785 }
786 #define SIG2WORD16(x) (SIG2WORD16_generic(x))
787
788
789 #undef PRINT_MIPS
790 #define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0);
791
792 #endif