1 /*
2  * Contributor(s):
3  *
4  * Eric des Courtis <eric.des.courtis@benbria.com>
5  * Piotr Gregor     <piotrgregor@rsyncme.org>
6  */
7 
8 #include <stdio.h>
9 
10 #ifdef WIN32
11     #include <float.h>
12     #define ISNAN(x) (!!(_isnan(x)))
13     #define ISINF(x) (isinf(x))
14 #endif
15 
16 #include "avmd_buffer.h"
17 #include "avmd_desa2.h"
18 #include "avmd_options.h"
19 
20 #ifdef AVMD_FAST_MATH
21     #include "avmd_fast_acosf.h"
22 #endif
23 
24 
avmd_desa2(circ_buffer_t * b,size_t i,double * amplitude)25 double avmd_desa2(circ_buffer_t *b, size_t i, double *amplitude) {
26     double d;
27     double n;
28     double x0;
29     double x1;
30     double x2;
31     double x3;
32     double x4;
33     double x2sq;
34     double result;
35     double PSI_Xn, PSI_Yn, NEEDED;
36 
37     x0 = GET_SAMPLE((b), (i));
38     x1 = GET_SAMPLE((b), ((i) + 1));
39     x2 = GET_SAMPLE((b), ((i) + 2));
40     x3 = GET_SAMPLE((b), ((i) + 3));
41     x4 = GET_SAMPLE((b), ((i) + 4));
42 
43     x2sq = x2 * x2;
44     d = 2.0 * ((x2sq) - (x1 * x3));
45     if (d == 0.0) {
46         *amplitude = 0.0;
47         return 0.0;
48     }
49     PSI_Xn = ((x2sq) - (x0 * x4));
50     NEEDED = ((x1 * x1) - (x0 * x2)) + ((x3 * x3) - (x2 * x4));
51     n = ((x2sq) - (x0 * x4)) - NEEDED;
52     PSI_Yn = NEEDED + PSI_Xn;
53 
54 #ifdef AVMD_FAST_MATH
55     result = 0.5 * (double)fast_acosf((float)n/d);
56 #else
57     result = 0.5 * acos(n/d);
58 #endif
59 
60     if (ISNAN(result)) {
61         result = 0.0;
62     }
63     *amplitude = 2.0 * PSI_Xn / sqrt(PSI_Yn);
64 
65     return result;
66 
67 }
68