1 /* ----------------------------------------------------------------------
2  * Project:      CMSIS DSP Library
3  * Title:        Error.cpp
4  * Description:  Error functions
5  *
6  * $Date:        20. June 2019
7  * $Revision:    V1.0.0
8  *
9  * Target Processor: Cortex-M cores
10  * -------------------------------------------------------------------- */
11 /*
12  * Copyright (C) 2010-2019 ARM Limited or its affiliates. All rights reserved.
13  *
14  * SPDX-License-Identifier: Apache-2.0
15  *
16  * Licensed under the Apache License, Version 2.0 (the License); you may
17  * not use this file except in compliance with the License.
18  * You may obtain a copy of the License at
19  *
20  * www.apache.org/licenses/LICENSE-2.0
21  *
22  * Unless required by applicable law or agreed to in writing, software
23  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
24  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25  * See the License for the specific language governing permissions and
26  * limitations under the License.
27  */
28 #include <cstdlib>
29 #include <cstdio>
30 #include "arm_math_types.h"
31 #include "arm_math_types_f16.h"
32 #include "Error.h"
33 #include <cinttypes>
34 
35 namespace Client {
36 
37 template <typename T>
assert_not_empty_generic(unsigned long nb,AnyPattern<T> & p)38 void assert_not_empty_generic(unsigned long nb, AnyPattern<T> &p)
39 {
40    if (p.nbSamples() == 0)
41    {
42         throw (Error(EMPTY_PATTERN_ERROR,nb));
43    }
44    if (p.ptr() == NULL)
45    {
46         throw (Error(EMPTY_PATTERN_ERROR,nb));
47    }
48 };
49 
50 
51 template <>
assert_near_equal(unsigned long nb,double pa,double pb,double threshold)52 void assert_near_equal(unsigned long nb,double pa, double pb, double threshold)
53 {
54     if (fabs(pa - pb) > threshold)
55     {
56          char details[200];
57          sprintf(details,"diff %g > %g (%g,%g)",fabs(pa - pb) , threshold,pa,pb);
58          throw (Error(EQUAL_ERROR,nb,details));
59     }
60 };
61 
62 template <>
assert_near_equal(unsigned long nb,float32_t pa,float32_t pb,float32_t threshold)63 void assert_near_equal(unsigned long nb,float32_t pa, float32_t pb, float32_t threshold)
64 {
65     if (fabs(pa - pb) > threshold)
66     {
67          char details[200];
68          sprintf(details,"diff %g > %g (%g,%g)",fabs(pa - pb) , threshold, pa, pb);
69          throw (Error(EQUAL_ERROR,nb,details));
70     }
71 };
72 
73 #if !defined (__CC_ARM) && defined(ARM_FLOAT16_SUPPORTED)
74 template <>
assert_near_equal(unsigned long nb,float16_t pa,float16_t pb,float16_t threshold)75 void assert_near_equal(unsigned long nb,float16_t pa, float16_t pb, float16_t threshold)
76 {
77     if (fabs(pa - pb) > threshold)
78     {
79          char details[200];
80          sprintf(details,"diff %g > %g (%g,%g)",fabs(pa - pb) , threshold, pa, pb);
81          throw (Error(EQUAL_ERROR,nb,details));
82     }
83 };
84 #endif
85 
86 template <>
assert_near_equal(unsigned long nb,q63_t pa,q63_t pb,q63_t threshold)87 void assert_near_equal(unsigned long nb,q63_t pa, q63_t pb, q63_t threshold)
88 {
89     if (abs(pa - pb) > threshold)
90     {
91          char details[200];
92          #if __sizeof_long == 8
93          sprintf(details,"diff %ld > %ld (0x%016lX,0x%016lX)",abs(pa - pb) , threshold,pa,pb);
94          #else
95          sprintf(details,"diff %lld > %lld (0x%016llX,0x%016llX)",abs(pa - pb) , threshold,pa,pb);
96          #endif
97          throw (Error(EQUAL_ERROR,nb,details));
98     }
99 };
100 
101 template <>
assert_near_equal(unsigned long nb,q31_t pa,q31_t pb,q31_t threshold)102 void assert_near_equal(unsigned long nb,q31_t pa, q31_t pb, q31_t threshold)
103 {
104     if (abs(pa - pb) > threshold)
105     {
106          char details[200];
107          sprintf(details,"diff %d > %d (0x%08X,0x%08X)",abs(pa - pb) , threshold,pa,pb);
108          throw (Error(EQUAL_ERROR,nb,details));
109     }
110 };
111 
112 template <>
assert_near_equal(unsigned long nb,q15_t pa,q15_t pb,q15_t threshold)113 void assert_near_equal(unsigned long nb,q15_t pa, q15_t pb, q15_t threshold)
114 {
115     if (abs(pa - pb) > threshold)
116     {
117          char details[200];
118          sprintf(details,"diff %d > %d (0x%04X,0x%04X)",abs(pa - pb) , threshold,pa,pb);
119          throw (Error(EQUAL_ERROR,nb,details));
120     }
121 };
122 
123 template <>
assert_near_equal(unsigned long nb,q7_t pa,q7_t pb,q7_t threshold)124 void assert_near_equal(unsigned long nb,q7_t pa, q7_t pb, q7_t threshold)
125 {
126     if (abs(pa - pb) > threshold)
127     {
128          char details[200];
129          sprintf(details,"diff %d > %d (0x%02X,0x%02X)",abs(pa - pb) , threshold,pa,pb);
130          throw (Error(EQUAL_ERROR,nb,details));
131     }
132 };
133 
assert_not_empty(unsigned long nb,AnyPattern<float64_t> & p)134 void assert_not_empty(unsigned long nb, AnyPattern<float64_t> &p)
135 {
136   assert_not_empty_generic(nb,p);
137 }
138 
assert_not_empty(unsigned long nb,AnyPattern<float32_t> & p)139 void assert_not_empty(unsigned long nb, AnyPattern<float32_t> &p)
140 {
141   assert_not_empty_generic(nb,p);
142 }
143 
144 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
assert_not_empty(unsigned long nb,AnyPattern<float16_t> & p)145 void assert_not_empty(unsigned long nb, AnyPattern<float16_t> &p)
146 {
147   assert_not_empty_generic(nb,p);
148 }
149 #endif
150 
assert_not_empty(unsigned long nb,AnyPattern<q63_t> & p)151 void assert_not_empty(unsigned long nb, AnyPattern<q63_t> &p)
152 {
153   assert_not_empty_generic(nb,p);
154 }
155 
assert_not_empty(unsigned long nb,AnyPattern<q31_t> & p)156 void assert_not_empty(unsigned long nb, AnyPattern<q31_t> &p)
157 {
158   assert_not_empty_generic(nb,p);
159 }
160 
assert_not_empty(unsigned long nb,AnyPattern<q15_t> & p)161 void assert_not_empty(unsigned long nb, AnyPattern<q15_t> &p)
162 {
163   assert_not_empty_generic(nb,p);
164 }
165 
assert_not_empty(unsigned long nb,AnyPattern<q7_t> & p)166 void assert_not_empty(unsigned long nb, AnyPattern<q7_t> &p)
167 {
168   assert_not_empty_generic(nb,p);
169 }
170 
assert_not_empty(unsigned long nb,AnyPattern<uint32_t> & p)171 void assert_not_empty(unsigned long nb, AnyPattern<uint32_t> &p)
172 {
173   assert_not_empty_generic(nb,p);
174 }
175 
assert_not_empty(unsigned long nb,AnyPattern<uint16_t> & p)176 void assert_not_empty(unsigned long nb, AnyPattern<uint16_t> &p)
177 {
178   assert_not_empty_generic(nb,p);
179 }
180 
assert_not_empty(unsigned long nb,AnyPattern<uint8_t> & p)181 void assert_not_empty(unsigned long nb, AnyPattern<uint8_t> &p)
182 {
183   assert_not_empty_generic(nb,p);
184 }
185 
assert_relative_error(unsigned long nb,float64_t & a,float64_t & b,double threshold)186 void assert_relative_error(unsigned long nb,float64_t &a, float64_t &b, double threshold)
187 {
188     float64_t rel,delta,average;
189 
190     delta=abs(a-b);
191     average = (abs(a) + abs(b)) / 2.0f;
192     if (average !=0)
193     {
194         rel = delta / average;
195         //printf("%6.9f %6.9f %6.9f %g %g\n",a,b,rel,delta,average);
196         if (rel > threshold)
197         {
198             //printf("rel = %g, threshold %g \n",rel,threshold);
199             char details[200];
200             sprintf(details,"diff (%g,%g), %g > %g",a,b,rel , threshold);
201             throw (Error(RELATIVE_ERROR,nb,details));
202         }
203     }
204 };
205 
assert_relative_error(unsigned long nb,float32_t & a,float32_t & b,double threshold)206 void assert_relative_error(unsigned long nb,float32_t &a, float32_t &b, double threshold)
207 {
208     double rel,delta,average;
209 
210     delta=abs(a-b);
211     average = (abs((float)a) + abs((float)b)) / 2.0f;
212     if (average !=0)
213     {
214         rel = delta / average;
215         //printf("%6.9f %6.9f %6.9f %g %g\n",a,b,rel,delta,average);
216         if (rel > threshold)
217         {
218             //printf("rel = %g, threshold %g \n",rel,threshold);
219             char details[200];
220             sprintf(details,"diff (%g,%g), %g > %g",a,b,rel , threshold);
221             throw (Error(RELATIVE_ERROR,nb,details));
222         }
223     }
224 };
225 
226 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
assert_relative_error(unsigned long nb,float16_t & a,float16_t & b,double threshold)227 void assert_relative_error(unsigned long nb,float16_t &a, float16_t &b, double threshold)
228 {
229     double rel,delta,average;
230 
231     delta=abs(a-b);
232     average = (abs(a) + abs(b)) / 2.0f;
233     if (average !=0)
234     {
235         rel = delta / average;
236         //printf("%6.9f %6.9f %6.9f %g %g\n",a,b,rel,delta,average);
237         if (rel > threshold)
238         {
239             //printf("rel = %g, threshold %g \n",rel,threshold);
240             char details[200];
241             sprintf(details,"diff (%g,%g), %g > %g",a,b,rel , threshold);
242             throw (Error(RELATIVE_ERROR,nb,details));
243         }
244     }
245 };
246 #endif
247 
assert_relative_error(unsigned long nb,AnyPattern<float64_t> & pa,AnyPattern<float64_t> & pb,double threshold)248 void assert_relative_error(unsigned long nb,AnyPattern<float64_t> &pa, AnyPattern<float64_t> &pb, double threshold)
249 {
250     ASSERT_NOT_EMPTY(pa);
251     ASSERT_NOT_EMPTY(pb);
252 
253     if (pa.nbSamples() != pb.nbSamples())
254     {
255         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
256     }
257 
258     unsigned long i=0;
259 
260     float64_t *ptrA = pa.ptr();
261     float64_t *ptrB = pb.ptr();
262     char id[40];
263 
264     for(i=0; i < pa.nbSamples(); i++)
265     {
266        try
267        {
268           assert_relative_error(nb,ptrA[i],ptrB[i],threshold);
269        }
270        catch(Error &err)
271        {
272           sprintf(id," (nb=%lu)",i);
273           strcat(err.details,id);
274           throw(err);
275        }
276     }
277 };
278 
assert_relative_error(unsigned long nb,AnyPattern<float32_t> & pa,AnyPattern<float32_t> & pb,double threshold)279 void assert_relative_error(unsigned long nb,AnyPattern<float32_t> &pa, AnyPattern<float32_t> &pb, double threshold)
280 {
281     ASSERT_NOT_EMPTY(pa);
282     ASSERT_NOT_EMPTY(pb);
283 
284     if (pa.nbSamples() != pb.nbSamples())
285     {
286         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
287     }
288 
289     unsigned long i=0;
290 
291     float32_t *ptrA = pa.ptr();
292     float32_t *ptrB = pb.ptr();
293     char id[40];
294 
295     for(i=0; i < pa.nbSamples(); i++)
296     {
297        try
298        {
299           assert_relative_error(nb,ptrA[i],ptrB[i],threshold);
300        }
301        catch(Error &err)
302        {
303           sprintf(id," (nb=%lu)",i);
304           strcat(err.details,id);
305           throw(err);
306        }
307     }
308 };
309 
310 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
assert_relative_error(unsigned long nb,AnyPattern<float16_t> & pa,AnyPattern<float16_t> & pb,double threshold)311 void assert_relative_error(unsigned long nb,AnyPattern<float16_t> &pa, AnyPattern<float16_t> &pb, double threshold)
312 {
313     ASSERT_NOT_EMPTY(pa);
314     ASSERT_NOT_EMPTY(pb);
315 
316     if (pa.nbSamples() != pb.nbSamples())
317     {
318         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
319     }
320 
321     unsigned long i=0;
322 
323     float16_t *ptrA = pa.ptr();
324     float16_t *ptrB = pb.ptr();
325     char id[40];
326 
327     for(i=0; i < pa.nbSamples(); i++)
328     {
329        try
330        {
331           assert_relative_error(nb,ptrA[i],ptrB[i],threshold);
332        }
333        catch(Error &err)
334        {
335           sprintf(id," (nb=%lu)",i);
336           strcat(err.details,id);
337           throw(err);
338        }
339     }
340 };
341 #endif
342 
assert_close_error(unsigned long nb,float64_t & ref,float64_t & val,double absthreshold,double relthreshold)343 void assert_close_error(unsigned long nb,float64_t &ref, float64_t &val, double absthreshold,double relthreshold)
344 {
345 
346     if (abs(val - ref) > (absthreshold + relthreshold * abs(ref)))
347     {
348         char details[200];
349         sprintf(details,"close error %g > %g: (val = %g, ref = %g)",abs(val - ref) , absthreshold + relthreshold * abs(ref),val,ref);
350         throw (Error(CLOSE_ERROR,nb,details));
351     }
352 };
353 
assert_close_error(unsigned long nb,AnyPattern<float64_t> & pref,AnyPattern<float64_t> & pval,double absthreshold,double relthreshold)354 void assert_close_error(unsigned long nb,AnyPattern<float64_t> &pref, AnyPattern<float64_t> &pval, double absthreshold,double relthreshold)
355 {
356     ASSERT_NOT_EMPTY(pref);
357     ASSERT_NOT_EMPTY(pval);
358 
359     if (pref.nbSamples() != pval.nbSamples())
360     {
361         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
362     }
363 
364     unsigned long i=0;
365     char id[40];
366 
367     float64_t *ptrA = pref.ptr();
368     float64_t *ptrB = pval.ptr();
369 
370     for(i=0; i < pref.nbSamples(); i++)
371     {
372        try
373        {
374           assert_close_error(nb,ptrA[i],ptrB[i],absthreshold,relthreshold);
375        }
376        catch(Error &err)
377        {
378           sprintf(id," (nb=%lu)",i);
379           strcat(err.details,id);
380           throw(err);
381        }
382 
383     }
384 };
385 
assert_close_error(unsigned long nb,float32_t & ref,float32_t & val,double absthreshold,double relthreshold)386 void assert_close_error(unsigned long nb,float32_t &ref, float32_t &val, double absthreshold,double relthreshold)
387 {
388 
389     if (abs(val - ref) > (absthreshold + relthreshold * abs(ref)))
390     {
391         char details[200];
392         sprintf(details,"close error %g > %g: (val = %g, ref = %g)",abs(val - ref) , absthreshold + relthreshold * abs(ref),val,ref);
393         throw (Error(CLOSE_ERROR,nb,details));
394     }
395 };
396 
assert_close_error(unsigned long nb,AnyPattern<float32_t> & pref,AnyPattern<float32_t> & pval,double absthreshold,double relthreshold)397 void assert_close_error(unsigned long nb,AnyPattern<float32_t> &pref, AnyPattern<float32_t> &pval, double absthreshold,double relthreshold)
398 {
399     ASSERT_NOT_EMPTY(pref);
400     ASSERT_NOT_EMPTY(pval);
401 
402     if (pref.nbSamples() != pval.nbSamples())
403     {
404         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
405     }
406 
407     unsigned long i=0;
408     char id[40];
409 
410     float32_t *ptrA = pref.ptr();
411     float32_t *ptrB = pval.ptr();
412 
413     for(i=0; i < pref.nbSamples(); i++)
414     {
415        try
416        {
417           assert_close_error(nb,ptrA[i],ptrB[i],absthreshold,relthreshold);
418        }
419        catch(Error &err)
420        {
421           sprintf(id," (nb=%lu)",i);
422           strcat(err.details,id);
423           throw(err);
424        }
425 
426     }
427 };
428 
429 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
assert_close_error(unsigned long nb,float16_t & ref,float16_t & val,double absthreshold,double relthreshold)430 void assert_close_error(unsigned long nb,float16_t &ref, float16_t &val, double absthreshold,double relthreshold)
431 {
432 
433     if (abs((float)val - (float)ref) > (absthreshold + relthreshold * abs((float)ref)))
434     {
435         char details[200];
436         sprintf(details,"close error %g > %g: (val = %g, ref = %g)",abs(val - ref) , absthreshold + relthreshold * abs(ref),val,ref);
437         throw (Error(CLOSE_ERROR,nb,details));
438     }
439 };
440 
assert_close_error(unsigned long nb,AnyPattern<float16_t> & pref,AnyPattern<float16_t> & pval,double absthreshold,double relthreshold)441 void assert_close_error(unsigned long nb,AnyPattern<float16_t> &pref, AnyPattern<float16_t> &pval, double absthreshold,double relthreshold)
442 {
443     ASSERT_NOT_EMPTY(pref);
444     ASSERT_NOT_EMPTY(pval);
445 
446     if (pref.nbSamples() != pval.nbSamples())
447     {
448         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
449     }
450 
451     unsigned long i=0;
452     char id[40];
453 
454     float16_t *ptrA = pref.ptr();
455     float16_t *ptrB = pval.ptr();
456 
457     for(i=0; i < pref.nbSamples(); i++)
458     {
459        try
460        {
461           assert_close_error(nb,ptrA[i],ptrB[i],absthreshold,relthreshold);
462        }
463        catch(Error &err)
464        {
465           sprintf(id," (nb=%lu)",i);
466           strcat(err.details,id);
467           throw(err);
468        }
469 
470     }
471 };
472 #endif
473 
474 /**
475  * @brief  Calculation of SNR
476  * @param  float*   Pointer to the reference buffer
477  * @param  float*   Pointer to the test buffer
478  * @param  uint32_t     total number of samples
479  * @return float    SNR
480  * The function calculates signal to noise ratio for the reference output
481  * and test output
482  */
483 
484 /* If NaN, force SNR to 0.0 to ensure test will fail */
485 #define IFNANRETURNZERO(val)\
486      if (isnan((val)))      \
487      {                      \
488        return(0.0);         \
489      }
490 
491 #define IFINFINITERETURN(val,def)\
492      if (isinf((val)))           \
493      {                           \
494        if ((val) > 0)            \
495        {                         \
496           return(def);           \
497        }                         \
498        else                      \
499        {                         \
500          return(-def);           \
501        }                         \
502      }
503 
arm_snr_f32(float * pRef,float * pTest,uint32_t buffSize)504 float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
505 {
506   float EnergySignal = 0.0, EnergyError = 0.0;
507   uint32_t i;
508   float SNR;
509 
510   for (i = 0; i < buffSize; i++)
511     {
512       /* Checking for a NAN value in pRef array */
513       IFNANRETURNZERO(pRef[i]);
514 
515       /* Checking for a NAN value in pTest array */
516       IFNANRETURNZERO(pTest[i]);
517 
518       EnergySignal += pRef[i] * pRef[i];
519       EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
520     }
521 
522     /* Checking for a NAN value in EnergyError */
523     IFNANRETURNZERO(EnergyError);
524 
525 
526     SNR = 10 * log10f (EnergySignal / EnergyError);
527 
528     /* Checking for a NAN value in SNR */
529     IFNANRETURNZERO(SNR);
530     IFINFINITERETURN(SNR,100000.0);
531 
532 
533   return (SNR);
534 
535 }
536 
537 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
arm_snr_f16(float16_t * pRef,float16_t * pTest,uint32_t buffSize)538 float arm_snr_f16(float16_t *pRef, float16_t *pTest, uint32_t buffSize)
539 {
540   float EnergySignal = 0.0, EnergyError = 0.0;
541   uint32_t i;
542   float SNR;
543 
544   for (i = 0; i < buffSize; i++)
545     {
546       /* Checking for a NAN value in pRef array */
547       IFNANRETURNZERO((float)pRef[i]);
548 
549       /* Checking for a NAN value in pTest array */
550       IFNANRETURNZERO((float)pTest[i]);
551 
552       EnergySignal += pRef[i] * pRef[i];
553       EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
554     }
555 
556     /* Checking for a NAN value in EnergyError */
557     IFNANRETURNZERO(EnergyError);
558 
559 
560     SNR = 10 * log10f (EnergySignal / EnergyError);
561 
562     /* Checking for a NAN value in SNR */
563     IFNANRETURNZERO(SNR);
564     IFINFINITERETURN(SNR,100000.0);
565 
566 
567   return (SNR);
568 
569 }
570 #endif
571 
arm_snr_q63(q63_t * pRef,q63_t * pTest,uint32_t buffSize)572 float arm_snr_q63(q63_t *pRef, q63_t *pTest, uint32_t buffSize)
573 {
574   double EnergySignal = 0.0, EnergyError = 0.0;
575   uint32_t i;
576   float SNR;
577 
578   double testVal,refVal;
579 
580   for (i = 0; i < buffSize; i++)
581     {
582 
583       testVal = ((double)pTest[i])  / 9223372036854775808.0;
584       refVal = ((double)pRef[i])  / 9223372036854775808.0;
585 
586       EnergySignal += refVal * refVal;
587       EnergyError += (refVal - testVal) * (refVal - testVal);
588 
589     }
590 
591 
592   SNR = 10 * log10 (EnergySignal / EnergyError);
593 
594 
595   /* Checking for a NAN value in SNR */
596    IFNANRETURNZERO(SNR);
597    IFINFINITERETURN(SNR,100000.0);
598 
599   //printf("SNR = %f\n",SNR);
600 
601   return (SNR);
602 
603 }
604 
arm_snr_q31(q31_t * pRef,q31_t * pTest,uint32_t buffSize)605 float arm_snr_q31(q31_t *pRef, q31_t *pTest, uint32_t buffSize)
606 {
607   float EnergySignal = 0.0, EnergyError = 0.0;
608   uint32_t i;
609   float SNR;
610 
611   float32_t testVal,refVal;
612 
613   for (i = 0; i < buffSize; i++)
614     {
615 
616       testVal = ((float32_t)pTest[i])  / 2147483648.0f;
617       refVal = ((float32_t)pRef[i])  / 2147483648.0f;
618 
619       EnergySignal += refVal * refVal;
620       EnergyError += (refVal - testVal) * (refVal - testVal);
621     }
622 
623 
624   SNR = 10 * log10f (EnergySignal / EnergyError);
625 
626   /* Checking for a NAN value in SNR */
627    IFNANRETURNZERO(SNR);
628    IFINFINITERETURN(SNR,100000.0);
629 
630    //printf("SNR = %f\n",SNR);
631 
632   return (SNR);
633 
634 }
635 
arm_snr_q15(q15_t * pRef,q15_t * pTest,uint32_t buffSize)636 float arm_snr_q15(q15_t *pRef, q15_t *pTest, uint32_t buffSize)
637 {
638   float EnergySignal = 0.0, EnergyError = 0.0;
639   uint32_t i;
640   float SNR;
641 
642   float32_t testVal,refVal;
643 
644   for (i = 0; i < buffSize; i++)
645     {
646 
647       testVal = ((float32_t)pTest[i])   / 32768.0f;
648       refVal = ((float32_t)pRef[i])  / 32768.0f;
649 
650       EnergySignal += refVal * refVal;
651       EnergyError += (refVal - testVal) * (refVal - testVal);
652     }
653 
654 
655   SNR = 10 * log10f (EnergySignal / EnergyError);
656 
657   /* Checking for a NAN value in SNR */
658   IFNANRETURNZERO(SNR);
659   IFINFINITERETURN(SNR,100000.0);
660 
661   //printf("SNR = %f\n",SNR);
662 
663   return (SNR);
664 
665 }
666 
arm_snr_q7(q7_t * pRef,q7_t * pTest,uint32_t buffSize)667 float arm_snr_q7(q7_t *pRef, q7_t *pTest, uint32_t buffSize)
668 {
669   float EnergySignal = 0.0, EnergyError = 0.0;
670   uint32_t i;
671   float SNR;
672 
673   float32_t testVal,refVal;
674 
675   for (i = 0; i < buffSize; i++)
676     {
677 
678       testVal = ((float32_t)pTest[i])   / 128.0f;
679       refVal = ((float32_t)pRef[i])  / 128.0f;
680 
681       EnergySignal += refVal * refVal;
682       EnergyError += (refVal - testVal) * (refVal - testVal);
683     }
684 
685 
686   SNR = 10 * log10f (EnergySignal / EnergyError);
687 
688   IFNANRETURNZERO(SNR);
689   IFINFINITERETURN(SNR,100000.0);
690 
691   return (SNR);
692 
693 }
694 
arm_snr_f64(double * pRef,double * pTest,uint32_t buffSize)695 double arm_snr_f64(double *pRef, double *pTest, uint32_t buffSize)
696 {
697   double EnergySignal = 0.0, EnergyError = 0.0;
698   uint32_t i;
699   double SNR;
700 
701   for (i = 0; i < buffSize; i++)
702     {
703       /* Checking for a NAN value in pRef array */
704       IFNANRETURNZERO(pRef[i]);
705 
706 
707       /* Checking for a NAN value in pTest array */
708       IFNANRETURNZERO(pTest[i]);
709 
710       EnergySignal += pRef[i] * pRef[i];
711       EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
712     }
713 
714     /* Checking for a NAN value in EnergyError */
715     IFNANRETURNZERO(EnergyError);
716 
717     SNR = 10 * log10 (EnergySignal / EnergyError);
718 
719     /* Checking for a NAN value in SNR */
720     IFNANRETURNZERO(SNR);
721     IFINFINITERETURN(SNR,100000.0);
722 
723   return (SNR);
724 
725 }
726 
assert_snr_error(unsigned long nb,AnyPattern<float32_t> & pa,AnyPattern<float32_t> & pb,float32_t threshold)727 void assert_snr_error(unsigned long nb,AnyPattern<float32_t> &pa,AnyPattern<float32_t> &pb, float32_t threshold)
728 {
729    float32_t snr;
730 
731    ASSERT_NOT_EMPTY(pa);
732    ASSERT_NOT_EMPTY(pb);
733 
734    if (pa.nbSamples() != pb.nbSamples())
735    {
736         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
737    }
738 
739    float32_t *ptrA = pa.ptr();
740    float32_t *ptrB = pb.ptr();
741 
742    snr = arm_snr_f32(ptrA, ptrB, pa.nbSamples());
743 
744    //printf("SNR = %f\n",snr);
745 
746    if (snr < threshold)
747    {
748      char details[200];
749      sprintf(details,"SNR %g < %g",snr,threshold);
750      throw (Error(SNR_ERROR,nb,details));
751    }
752 }
753 
assert_snr_error(unsigned long nb,float32_t a,float32_t b,float32_t threshold)754 void assert_snr_error(unsigned long nb,float32_t a,float32_t b, float32_t threshold)
755 {
756    float32_t snr;
757 
758    snr = arm_snr_f32(&a, &b, 1);
759 
760    //printf("SNR = %f\n",snr);
761 
762    if (snr < threshold)
763    {
764      char details[200];
765      sprintf(details,"SNR %g < %g",snr,threshold);
766      throw (Error(SNR_ERROR,nb,details));
767    }
768 }
769 
770 #if !defined( __CC_ARM ) && defined(ARM_FLOAT16_SUPPORTED)
assert_snr_error(unsigned long nb,AnyPattern<float16_t> & pa,AnyPattern<float16_t> & pb,float32_t threshold)771 void assert_snr_error(unsigned long nb,AnyPattern<float16_t> &pa,AnyPattern<float16_t> &pb, float32_t threshold)
772 {
773    float32_t snr;
774 
775    ASSERT_NOT_EMPTY(pa);
776    ASSERT_NOT_EMPTY(pb);
777 
778    if (pa.nbSamples() != pb.nbSamples())
779    {
780         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
781    }
782 
783    float16_t *ptrA = pa.ptr();
784    float16_t *ptrB = pb.ptr();
785 
786    snr = arm_snr_f16(ptrA, ptrB, pa.nbSamples());
787 
788    //printf("SNR = %f\n",snr);
789 
790    if (snr < threshold)
791    {
792      char details[200];
793      sprintf(details,"SNR %g < %g",snr,threshold);
794      throw (Error(SNR_ERROR,nb,details));
795    }
796 }
797 #endif
798 
799 #if !defined (__CC_ARM) && defined(ARM_FLOAT16_SUPPORTED)
assert_snr_error(unsigned long nb,float16_t a,float16_t b,float32_t threshold)800 void assert_snr_error(unsigned long nb,float16_t a,float16_t b, float32_t threshold)
801 {
802    float32_t snr;
803 
804    snr = arm_snr_f16(&a, &b, 1);
805 
806    //printf("SNR = %f\n",snr);
807 
808    if (snr < threshold)
809    {
810      char details[200];
811      sprintf(details,"SNR %g < %g",snr,threshold);
812      throw (Error(SNR_ERROR,nb,details));
813    }
814 }
815 #endif
816 
assert_snr_error(unsigned long nb,AnyPattern<float64_t> & pa,AnyPattern<float64_t> & pb,float64_t threshold)817 void assert_snr_error(unsigned long nb,AnyPattern<float64_t> &pa,AnyPattern<float64_t> &pb, float64_t threshold)
818 {
819    float64_t snr;
820 
821    ASSERT_NOT_EMPTY(pa);
822    ASSERT_NOT_EMPTY(pb);
823 
824    if (pa.nbSamples() != pb.nbSamples())
825    {
826         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
827    }
828 
829    float64_t *ptrA = pa.ptr();
830    float64_t *ptrB = pb.ptr();
831 
832    snr = arm_snr_f64(ptrA, ptrB, pa.nbSamples());
833 
834    //printf("SNR = %f\n",snr);
835 
836    if (snr < threshold)
837    {
838      char details[200];
839      sprintf(details,"SNR %g < %g",snr,threshold);
840      throw (Error(SNR_ERROR,nb,details));
841    }
842 }
843 
assert_snr_error(unsigned long nb,float64_t a,float64_t b,float64_t threshold)844 void assert_snr_error(unsigned long nb,float64_t a,float64_t b, float64_t threshold)
845 {
846    float64_t snr;
847 
848    snr = arm_snr_f64(&a, &b, 1);
849 
850    //printf("SNR = %f\n",snr);
851 
852    if (snr < threshold)
853    {
854      char details[200];
855      sprintf(details,"SNR %g < %g",snr,threshold);
856      throw (Error(SNR_ERROR,nb,details));
857    }
858 }
859 
assert_snr_error(unsigned long nb,AnyPattern<q63_t> & pa,AnyPattern<q63_t> & pb,float32_t threshold)860 void assert_snr_error(unsigned long nb,AnyPattern<q63_t> &pa,AnyPattern<q63_t> &pb, float32_t threshold)
861 {
862    float32_t snr;
863 
864    ASSERT_NOT_EMPTY(pa);
865    ASSERT_NOT_EMPTY(pb);
866 
867    if (pa.nbSamples() != pb.nbSamples())
868    {
869         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
870    }
871 
872    q63_t *ptrA = pa.ptr();
873    q63_t *ptrB = pb.ptr();
874 
875 
876    snr = arm_snr_q63(ptrA, ptrB, pa.nbSamples());
877 
878    //printf("SNR = %f\n",snr);
879 
880    if (snr < threshold)
881    {
882      char details[200];
883      sprintf(details,"SNR %g < %g",snr,threshold);
884      throw (Error(SNR_ERROR,nb,details));
885    }
886 
887 }
888 
assert_snr_error(unsigned long nb,q63_t a,q63_t b,float32_t threshold)889 void assert_snr_error(unsigned long nb,q63_t a,q63_t b, float32_t threshold)
890 {
891    float32_t snr;
892 
893    snr = arm_snr_q63(&a, &b, 1);
894 
895    //printf("SNR = %f\n",snr);
896 
897    if (snr < threshold)
898    {
899      char details[200];
900      sprintf(details,"SNR %g < %g",snr,threshold);
901      throw (Error(SNR_ERROR,nb,details));
902    }
903 
904 }
905 
assert_snr_error(unsigned long nb,AnyPattern<q31_t> & pa,AnyPattern<q31_t> & pb,float32_t threshold)906 void assert_snr_error(unsigned long nb,AnyPattern<q31_t> &pa,AnyPattern<q31_t> &pb, float32_t threshold)
907 {
908    float32_t snr;
909 
910    ASSERT_NOT_EMPTY(pa);
911    ASSERT_NOT_EMPTY(pb);
912 
913    if (pa.nbSamples() != pb.nbSamples())
914    {
915         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
916    }
917 
918    q31_t *ptrA = pa.ptr();
919    q31_t *ptrB = pb.ptr();
920 
921 
922    snr = arm_snr_q31(ptrA, ptrB, pa.nbSamples());
923 
924    //printf("SNR = %f\n",snr);
925 
926    if (snr < threshold)
927    {
928      char details[200];
929      sprintf(details,"SNR %g < %g",snr,threshold);
930      throw (Error(SNR_ERROR,nb,details));
931    }
932 
933 }
934 
assert_snr_error(unsigned long nb,q31_t a,q31_t b,float32_t threshold)935 void assert_snr_error(unsigned long nb,q31_t a,q31_t b, float32_t threshold)
936 {
937    float32_t snr;
938 
939    snr = arm_snr_q31(&a, &b, 1);
940 
941 
942    if (snr < threshold)
943    {
944      char details[200];
945      sprintf(details,"SNR %g < %g",snr,threshold);
946      throw (Error(SNR_ERROR,nb,details));
947    }
948 
949 }
950 
assert_snr_error(unsigned long nb,AnyPattern<q15_t> & pa,AnyPattern<q15_t> & pb,float32_t threshold)951 void assert_snr_error(unsigned long nb,AnyPattern<q15_t> &pa,AnyPattern<q15_t> &pb, float32_t threshold)
952 {
953    float32_t snr;
954 
955    ASSERT_NOT_EMPTY(pa);
956    ASSERT_NOT_EMPTY(pb);
957 
958    if (pa.nbSamples() != pb.nbSamples())
959    {
960         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
961    }
962 
963    q15_t *ptrA = pa.ptr();
964    q15_t *ptrB = pb.ptr();
965 
966    snr = arm_snr_q15(ptrA, ptrB, pa.nbSamples());
967 
968    //printf("SNR = %f\n",snr);
969 
970    if (snr < threshold)
971    {
972      char details[200];
973      sprintf(details,"SNR %g < %g",snr,threshold);
974      throw (Error(SNR_ERROR,nb,details));
975    }
976 
977 }
978 
assert_snr_error(unsigned long nb,q15_t a,q15_t b,float32_t threshold)979 void assert_snr_error(unsigned long nb,q15_t a,q15_t b, float32_t threshold)
980 {
981    float32_t snr;
982 
983    snr = arm_snr_q15(&a, &b, 1);
984 
985    //printf("SNR = %f\n",snr);
986 
987    if (snr < threshold)
988    {
989      char details[200];
990      sprintf(details,"SNR %g < %g",snr,threshold);
991      throw (Error(SNR_ERROR,nb,details));
992    }
993 
994 }
995 
assert_snr_error(unsigned long nb,AnyPattern<q7_t> & pa,AnyPattern<q7_t> & pb,float32_t threshold)996 void assert_snr_error(unsigned long nb,AnyPattern<q7_t> &pa,AnyPattern<q7_t> &pb, float32_t threshold)
997 {
998    float32_t snr;
999 
1000    ASSERT_NOT_EMPTY(pa);
1001    ASSERT_NOT_EMPTY(pb);
1002 
1003    if (pa.nbSamples() != pb.nbSamples())
1004    {
1005         throw (Error(DIFFERENT_LENGTH_ERROR,nb));
1006    }
1007 
1008    q7_t *ptrA = pa.ptr();
1009    q7_t *ptrB = pb.ptr();
1010 
1011    snr = arm_snr_q7(ptrA, ptrB, pa.nbSamples());
1012 
1013    //printf("SNR = %f\n",snr);
1014 
1015    if (snr < threshold)
1016    {
1017      char details[200];
1018      sprintf(details,"SNR %g < %g",snr,threshold);
1019      throw (Error(SNR_ERROR,nb,details));
1020    }
1021 
1022 }
1023 
assert_snr_error(unsigned long nb,q7_t a,q7_t b,float32_t threshold)1024 void assert_snr_error(unsigned long nb,q7_t a,q7_t b, float32_t threshold)
1025 {
1026    float32_t snr;
1027 
1028    snr = arm_snr_q7(&a, &b, 1);
1029 
1030    //printf("SNR = %f\n",snr);
1031 
1032    if (snr < threshold)
1033    {
1034      char details[200];
1035      sprintf(details,"SNR %g < %g",snr,threshold);
1036      throw (Error(SNR_ERROR,nb,details));
1037    }
1038 
1039 }
1040 
assert_true(unsigned long nb,bool cond)1041 void assert_true(unsigned long nb,bool cond)
1042 {
1043    if (!cond)
1044    {
1045      throw (Error(BOOL_ERROR,nb));
1046    }
1047 }
1048 
assert_false(unsigned long nb,bool cond)1049 void assert_false(unsigned long nb,bool cond)
1050 {
1051    if (cond)
1052    {
1053       throw (Error(BOOL_ERROR,nb));
1054    }
1055 }
1056 
1057 }
1058