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