1 // ----------------------------------------------------------------------------
2 //
3 //  Copyright (C) 2012-2021 Fons Adriaensen <fons@linuxaudio.org>
4 //
5 //  This program is free software; you can redistribute it and/or modify
6 //  it under the terms of the GNU General Public License as published by
7 //  the Free Software Foundation; either version 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 //
18 // ----------------------------------------------------------------------------
19 
20 
21 #ifndef __AMBROT8_H
22 #define __AMBROT8_H
23 
24 
25 #include <string.h>
26 #include "posixthr.h"
27 
28 
29 class RotMatrix
30 {
31 private:
32 
33     friend class Ambrot8;
34 
RotMatrix(int degree)35     RotMatrix (int degree):
36         _degr (degree)
37     {
38         _size = 2 * _degr + 1;
39         _data = new float [_size * _size];
40         clear ();
41     }
42 
~RotMatrix(void)43     ~RotMatrix (void)
44     {
45         delete[] _data;
46     }
47 
get(int r,int c)48     float get (int r, int c)
49     {
50         return _data [_size * (r + _degr) + c + _degr];
51     }
52 
set(int r,int c,float v)53     void set (int r, int c, float v)
54     {
55         _data [_size * (r + _degr) + c + _degr] = v;
56     }
57 
clear(void)58     void clear (void)
59     {
60         memset (_data, 0, _size * _size * sizeof (float));
61         for (int i = 0; i < _size; i++) _data [i * (_size + 1)] = 1.0f;
62     }
63 
copy(RotMatrix * M)64     void copy (RotMatrix *M)
65     {
66         memcpy (_data, M->_data, _size * _size * sizeof (float));
67     }
68 
69     int     _degr;
70     int     _size;
71     float  *_data;
72 };
73 
74 
75 class RotMagics
76 {
77     friend class Ambrot8;
78 
79     RotMagics (int degree);
80     ~RotMagics (void);
81 
R(int i)82     float R (int i) { return _R [i]; }
U(int i)83     float U (int i) { return _U [i]; }
V(int i)84     float V (int i) { return _V [i]; }
W(int i)85     float W (int i) { return _W [i]; }
86 
87     float *_R;
88     float *_U;
89     float *_V;
90     float *_W;
91 };
92 
93 
94 class Ambrot8
95 {
96 public:
97 
98     enum { MAXDEGR = 8, MAXHARM = 81 };
99 
100     Ambrot8 (int fsamp, int degree);
101     virtual ~Ambrot8 (void);
102 
103     void set_rotation (float a, float x, float y, float z, float dt);
104     void set_quaternion (float w, float x, float y, float z, float dt);
105     void process (int nframes, float *inp[], float *out[]);
106 
107 private:
108 
109     void process0 (float *inp[], float *out[], int k0, int nf);
110     void process1 (float *inp[], float *out[], int k0, int nf, int ni);
111     void update (void);
112     void newmatrix1 (void);
113     void newmatrixd (int d);
114     float funcV (int d, int m, int n);
115     float funcW (int d, int m, int n);
116     float funcP (int d, int m, int n, int i);
117 
118 #ifdef TEST
119     void printmatrix (int d);
120 #endif
121 
122     int              _fsamp;
123     int              _degree;
124     RotMatrix       *_M [MAXDEGR + 1];  // Target matrices.
125     RotMatrix       *_C [MAXDEGR + 1];  // Current matrices.
126     RotMagics       *_Q [MAXDEGR + 1];  // Magic constants.
127     float            _w, _x, _y, _z, _t;  // Target quaternion and time.
128     P_mutex          _mutex;   // Protects current matrices.
129     volatile int     _touch0;  // Update request counter.
130     volatile int     _touch1;  // Update done counter.
131     int              _nipol;   // Number of frames to interpolate.
132 };
133 
134 
135 #endif
136