1 /*
2     vbap.h:
3 
4     Copyright (C) 2000 Ville Pulkki
5 
6     This file is part of Csound.
7 
8     The Csound Library is free software; you can redistribute it
9     and/or modify it under the terms of the GNU Lesser General Public
10     License as published by the Free Software Foundation; either
11     version 2.1 of the License, or (at your option) any later version.
12 
13     Csound is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public
19     License along with Csound; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21     02110-1301 USA
22 */
23 
24 #define LOWEST_ACCEPTABLE_WT FL(0.0)
25 #define CHANNELS 128
26 #define MIN_VOL_P_SIDE_LGTH FL(0.01)
27 
28 typedef struct {
29   MYFLT x;
30   MYFLT y;
31   MYFLT z;
32 } CART_VEC;
33 
34 typedef struct {
35   MYFLT azi;
36   MYFLT ele;
37   MYFLT length;
38 } ANG_VEC;
39 
40 /* A struct for gain factors */
41 typedef struct {
42   MYFLT wt1, wt2, wt3;
43   MYFLT *out_ptr1, *out_ptr2, *out_ptr3;
44 } OUT_WTS;
45 
46 /* A struct for a loudspeaker triplet or pair (set) */
47 typedef struct {
48   int32_t ls_nos[3];
49   MYFLT ls_mx[9];
50   MYFLT set_gains[3];
51   MYFLT smallest_wt;
52   int32_t neg_g_am;
53 } LS_SET;
54 
55 /* VBAP structure of n loudspeaker panning */
56 typedef struct {
57   int32_t number;
58   MYFLT beg_gains[CHANNELS];
59   MYFLT curr_gains[CHANNELS];
60   MYFLT end_gains[CHANNELS];
61   MYFLT updated_gains[CHANNELS];
62   int32_t dim;
63   AUXCH aux;
64   LS_SET *ls_sets;
65   int32_t ls_am;
66   int32_t ls_set_am;
67   CART_VEC cart_dir;
68   CART_VEC spread_base;
69   ANG_VEC ang_dir;
70 } VBAP_DATA;
71 
72 typedef struct {
73   OPDS          h;                  /* required header */
74   MYFLT         *out_array[CHANNELS];
75   MYFLT         *audio, *azi, *ele, *spread, *layout;
76 
77   VBAP_DATA     q;
78 } VBAP;
79 
80 typedef struct {
81   OPDS          h;                  /* required header */
82   ARRAYDAT      *tabout;
83   MYFLT         *audio, *azi, *ele, *spread, *layout;
84 
85   VBAP_DATA     q;
86 } VBAPA;
87 
88 typedef struct {
89   int32_t number;
90   MYFLT gains[CHANNELS];
91   int32_t dim;
92   AUXCH aux;
93   LS_SET *ls_sets;
94   int32_t ls_am;
95   int32_t ls_set_am;
96   CART_VEC cart_dir;
97   CART_VEC spread_base;
98   ANG_VEC ang_dir;
99 } VBAP1_DATA;
100 
101 typedef struct {
102   OPDS      h;                  /* required header */
103   MYFLT         *out_array[CHANNELS];
104   MYFLT         *azi, *ele, *spread, *layout;
105 
106   VBAP1_DATA    q;
107 } VBAP1;
108 
109 typedef struct {
110   OPDS      h;                  /* required header */
111   ARRAYDAT      *tabout;
112   MYFLT         *azi, *ele, *spread, *layout;
113 
114   VBAP1_DATA    q;
115 } VBAPA1;
116 
117 /* VBAP structure of loudspeaker moving panning */
118 typedef struct {
119   MYFLT gains[CHANNELS];
120   int32_t number;
121   int32_t upd_interval;
122   int32_t dim;
123   AUXCH aux;
124   LS_SET *ls_sets;
125   int32_t ls_am;
126   int32_t ls_set_am;
127   CART_VEC cart_dir;
128   CART_VEC spread_base;
129   ANG_VEC ang_dir, prev_ang_dir, next_ang_dir;
130   int32_t point_change_interval, point_change_counter, curr_fld, next_fld;
131   MYFLT ele_vel;
132   MYFLT end_gains[CHANNELS];
133 } VBAP1_MOVE_DATA;
134 
135 typedef struct {
136   OPDS      h;                  /* required header */
137   MYFLT         *out_array[CHANNELS];
138   MYFLT         *dur, *spread, *field_am,
139                 *fld[VARGMAX-3]; /* field_am positive: point to point
140                                            negative: angle velocities */
141   VBAP1_MOVE_DATA q;
142 } VBAP1_MOVING;
143 
144 typedef struct {
145   OPDS           h;                  /* required header */
146   ARRAYDAT      *tabout;
147   MYFLT         *dur, *spread, *field_am,
148                 *fld[VARGMAX-3]; /* field_am positive: point to point
149                                            negative: angle velocities */
150   VBAP1_MOVE_DATA q;
151 } VBAPA1_MOVING;
152 
153 /* VBAP structure of loudspeaker moving panning */
154 typedef struct {
155   MYFLT beg_gains[CHANNELS];
156   MYFLT curr_gains[CHANNELS];
157   MYFLT updated_gains[CHANNELS];
158   int32_t number;
159   int32_t upd_interval;
160   int32_t dim;
161   AUXCH aux;
162   LS_SET *ls_sets;
163   int32_t ls_am;
164   int32_t ls_set_am;
165   CART_VEC cart_dir;
166   CART_VEC spread_base;
167   ANG_VEC ang_dir, prev_ang_dir, next_ang_dir;
168   int32_t point_change_interval, point_change_counter, curr_fld, next_fld;
169   MYFLT ele_vel;
170   MYFLT end_gains[CHANNELS];
171 } VBAP_MOVE_DATA;
172 
173 typedef struct {
174   OPDS      h;                  /* required header */
175   MYFLT         *out_array[CHANNELS];
176   MYFLT         *audio, *dur, *spread, *field_am,
177                 *fld[VARGMAX-4]; /* field_am positive: point to point
178                                            negative: angle velocities */
179   VBAP_MOVE_DATA q;
180 } VBAP_MOVING;
181 
182 
183 typedef struct {
184   OPDS          h;                  /* required header */
185   ARRAYDAT      *tabout;
186   MYFLT         *audio, *dur, *spread, *field_am,
187                 *fld[VARGMAX-4]; /* field_am positive: point to point
188                                            negative: angle velocities */
189   VBAP_MOVE_DATA q;
190 } VBAPA_MOVING;
191 
192 typedef struct {
193   OPDS      h;                  /* required header */
194   MYFLT     *dim, *ls_amount;
195   MYFLT     *f[2*CHANNELS];
196 } VBAP_LS_INIT;
197 
198 typedef struct {
199   OPDS      h;                  /* required header */
200   MYFLT     *dim, *ls_amount;
201   ARRAYDAT  *a;
202 } VBAP_LS_INITA;
203 
204 /* A struct for a loudspeaker instance */
205 typedef struct {
206   CART_VEC coords;
207   ANG_VEC angles;
208   int32_t channel_nbr;
209 } ls;
210 
211 /* A struct for all loudspeakers */
212 typedef struct ls_triplet_chain {
213   int32_t ls_nos[3];
214   MYFLT inv_mx[9];
215   struct ls_triplet_chain *next;
216 } ls_triplet_chain;
217 
218 /* functions */
219 
220 void angle_to_cart_II( ANG_VEC *from,  CART_VEC *to);
221 int32_t lines_intersect(int32_t i,int32_t j,int32_t k,int32_t l, ls lss[]);
222 MYFLT vec_angle(CART_VEC v1, CART_VEC v2);
223 void vec_mean(CART_VEC v1, CART_VEC v2, CART_VEC *v3);
224 MYFLT angle_in_base(CART_VEC vb1,CART_VEC vb2,CART_VEC vec);
225 void cross_prod(CART_VEC v1,CART_VEC v2,
226                 CART_VEC *res) ;
227 /* void sort_angles(MYFLT angles[], int32_t sorted_angles[], */
228 /*                  int32_t ls_amount); */
229 /* void remove_connections_in_planey(int32_t i,int32_t j,int32_t k,int32_t l, */
230 /*                                    ls  lss[CHANNELS], */
231 /*                                     int32_t connections[CHANNELS][CHANNELS]); */
232 int32_t calc_2D_inv_tmatrix(MYFLT azi1,MYFLT azi2, MYFLT inv_mat[4]);
233 
234 extern void cart_to_angle(CART_VEC cvec, ANG_VEC *avec);
235 extern void angle_to_cart(ANG_VEC avec, CART_VEC *cvec);
236 extern void normalize_wts(OUT_WTS *wts);
237 
238 extern int32_t vbap_control(CSOUND*, VBAP_DATA *p, MYFLT*, MYFLT*, MYFLT*);
239 
240 void calc_vbap_gns(int32_t ls_set_am, int32_t dim, LS_SET *sets,
241                    MYFLT *gains, int32_t ls_amount,
242                    CART_VEC cart_dir);
243 void scale_angles(ANG_VEC *avec);
244 MYFLT vol_p_side_lgth(int32_t i, int32_t j, int32_t k, ls  lss[]);
245 
246 void new_spread_dir(CART_VEC *spreaddir, CART_VEC vscartdir,
247                     CART_VEC spread_base, MYFLT azi, MYFLT spread);
248 void new_spread_base(CART_VEC spreaddir, CART_VEC vscartdir,
249                      MYFLT spread, CART_VEC *spread_base);
250 
251 /* VBAP structure for ZAK loudspeaker panning */
252 typedef struct {
253   OPDS      h;                  /* required header */
254   MYFLT     *numb, *ndx, *audio, *azi, *ele, *spread, *layout;
255   int32_t       n;
256   MYFLT     *out_array;
257   AUXCH     auxch;
258   AUXCH     aux;
259   MYFLT     *curr_gains;
260   MYFLT     *beg_gains;
261   MYFLT     *end_gains;
262   MYFLT     *updated_gains;
263   int32_t       dim;
264   LS_SET    *ls_sets;
265   int32_t       ls_am;
266   int32_t       ls_set_am;
267   CART_VEC  cart_dir;
268   CART_VEC  spread_base;
269   ANG_VEC   ang_dir;
270 } VBAP_ZAK;
271 
272 /* VBAP structure of ZAK loudspeaker moving panning */
273 typedef struct {
274   OPDS      h;                  /* required header */
275   MYFLT     *numb, *ndx, *audio, *dur, *spread, *field_am,
276             *fld[VARGMAX-6]; /* field_am positive: point to point
277                                        negative: angle velocities */
278   int32_t   n;
279   MYFLT     *out_array;
280   AUXCH     auxch;
281   AUXCH     aux;
282   MYFLT     *curr_gains;
283   MYFLT     *beg_gains;
284   MYFLT     *end_gains;
285   MYFLT     *updated_gains;
286   int32_t   dim;
287   LS_SET    *ls_sets;
288   int32_t   ls_am;
289   int32_t   ls_set_am;
290   CART_VEC  cart_dir;
291   CART_VEC  spread_base;
292   ANG_VEC   ang_dir, prev_ang_dir, next_ang_dir;
293   int32_t   point_change_interval, point_change_counter, curr_fld, next_fld;
294   MYFLT     ele_vel;
295 } VBAP_ZAK_MOVING;
296 
297 int32_t     vbap_init(CSOUND *, VBAP *);
298 int32_t     vbap_init_a(CSOUND *, VBAPA *);
299 int32_t     vbap(CSOUND *, VBAP *);
300 int32_t     vbap_a(CSOUND *, VBAPA *);
301 int32_t     vbap_zak_init(CSOUND *, VBAP_ZAK *);
302 int32_t     vbap_zak(CSOUND *, VBAP_ZAK *);
303 int32_t     vbap_ls_init(CSOUND *, VBAP_LS_INIT *);
304 int32_t     vbap_moving_init(CSOUND *, VBAP_MOVING *);
305 int32_t     vbap_moving(CSOUND *, VBAP_MOVING *);
306 int32_t     vbap_moving_init_a(CSOUND *, VBAPA_MOVING *);
307 int32_t     vbap_moving_a(CSOUND *, VBAPA_MOVING *);
308 int32_t     vbap_zak_moving_init(CSOUND *, VBAP_ZAK_MOVING *);
309 int32_t     vbap_zak_moving(CSOUND *, VBAP_ZAK_MOVING *);
310 int32_t     vbap1_init(CSOUND *, VBAP1 *);
311 int32_t     vbap1(CSOUND *, VBAP1 *);
312 int32_t     vbap1_init_a(CSOUND *, VBAPA1 *);
313 int32_t     vbap1a(CSOUND *, VBAPA1 *);
314 int32_t     vbap1_moving_init(CSOUND *, VBAP1_MOVING *);
315 int32_t     vbap1_moving(CSOUND *, VBAP1_MOVING *);
316 int32_t     vbap1_moving_init_a(CSOUND *, VBAPA1_MOVING *);
317 int32_t
318 vbap1_moving_a(CSOUND *, VBAPA1_MOVING *);
319 
320