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