1 /*
2 ambicode.c:
3
4 Copyright (C) 2005 Samuel Groner,
5 Institute for Computer Music and Sound Technology, www.icst.net
6
7 This file is part of Csound.
8
9 The Csound Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 Csound is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with Csound; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 02110-1301 USA
23 */
24 #include "csoundCore.h"
25 #include "interlocks.h"
26 #include <math.h>
27
28 typedef struct {
29 OPDS h; /* required header */
30 MYFLT *mw, *mx, *my, *mz, *mr, *ms, *mt, *mu, *mv, *mk,
31 *ml, *mm, *mn, *mo, *mp, *mq; /* addr outarg */
32 MYFLT *asig, *kalpha, *kbeta, *kin[4]; /* addr inargs */
33 /* private dataspace */
34 double w, x, y, z, r, s, t, u, v, k, l, m, n, o, p, q;
35 } AMBIC;
36
37 typedef struct {
38 OPDS h; /* required header */
39 MYFLT *m0, *m1, *m2, *m3, *m4, *m5, *m6, *m7; /* addr outarg */
40 MYFLT *isetup, *aw, *ax, *ay, *a[VARGMAX]; /* addr inargs */
41 /* private dataspace */
42 double w[8], x[8], y[8], z[8], r[8], s[8], t[8], u[8],
43 v[8], k[8], l[8], m[8], n[8], o[8], p[8], q[8];
44 } AMBID;
45
iambicode(CSOUND * csound,AMBIC * p)46 static int32_t iambicode(CSOUND *csound, AMBIC *p)
47 {
48 csound->Warning(csound,
49 Str("bformenc is deprecated; use bformenc1 instead\n"));
50 /* check correct number of input and output arguments */
51 switch (p->OUTOCOUNT) {
52 case 4:
53 /* { */
54 /* /\* 2nd order *\/ */
55 /* if (p->INOCOUNT != 5) { */
56 /* return csound->InitError(csound, */
57 /* Str("Wrong number of input arguments! " */
58 /* "5 needed!")); */
59 /* } */
60 /* break; */
61 /* } */
62
63 case 9:
64 /* { */
65 /* /\* 3rd order *\/ */
66 /* if (p->INOCOUNT != 6) { */
67 /* return csound->InitError(csound, */
68 /* Str("Wrong number of input arguments! " */
69 /* "6 needed!")); */
70 /* } */
71 /* break; */
72 /* } */
73
74 case 16:
75 /* { */
76 /* /\* 4th order *\/ */
77 /* if (p->INOCOUNT != 7) { */
78 /* return csound->InitError(csound, */
79 /* Str("Wrong number of input arguments! " */
80 /* "7 needed!")); */
81 /* } */
82 /* break; */
83 /* } */
84 break;
85 default:
86 {
87 return csound->InitError(csound,
88 Str("Wrong number of output arguments! "
89 "4, 9 or 16 needed!"));
90 }
91 }
92 return OK;
93 }
94
ambicode_set_coefficients(AMBIC * p)95 static void ambicode_set_coefficients(AMBIC *p)
96 {
97 /* convert degrees to radian */
98 /* 0.017 = pi/180 */
99 double kalpha_rad = (double)(*p->kalpha)*0.0174532925199432957692369076848861;
100 double kbeta_rad = (double)(*p->kbeta)*0.0174532925199432957692369076848861;
101
102 /* calculate ambisonic coefficients (Furse-Malham-set) */
103
104 /* 0th order */
105 p->w = 0.707106781186547524400844362104849 /* (1.0 / sqrt(2.0)) */ ;
106
107 /* 1st order */
108 {
109 double ck = cos(kbeta_rad);
110 p->x = cos(kalpha_rad) * ck;
111 p->y = sin(kalpha_rad) * ck;
112 p->z = sin(kbeta_rad);
113 }
114
115 /* 2nd order */
116 p->r = 0.5 * (3.0 * p->z * p->z - 1.0);
117 p->s = 2.0 * p->x * p->z;
118 p->t = 2.0 * p->y * p->z;
119 p->u = p->x * p->x - p->y * p->y;
120 p->v = 2.0 * p->x * p->y;
121
122 /* 3rd order */
123 p->k = 0.5 * p->z * (5.0 * p->z * p->z - 3.0);
124 p->l = (8.0 / 11.0) * p->y * (5.0 * p->z * p->z - 1.0);
125 p->m = (8.0 / 11.0) * p->x * (5.0 * p->z * p->z - 1.0);
126 p->n = 2.0 * p->x * p->y * p->z;
127 p->o = p->z * (p->x * p->x - p->y * p->y);
128 p->p = 3.0 * p->y * (3.0 * p->x * p->x - p->y * p->y);
129 p->q = 3.0 * p->x * (p->x * p->x - 3.0 * p->y * p->y);
130 }
131
aambicode(CSOUND * csound,AMBIC * p)132 static int32_t aambicode(CSOUND *csound, AMBIC *p)
133 {
134 IGN(csound);
135 uint32_t offset = p->h.insdshead->ksmps_offset;
136 uint32_t early = p->h.insdshead->ksmps_no_end;
137 uint32_t n, nsmps = CS_KSMPS; /* array size from orchestra */
138
139 /* init input array pointer */
140 MYFLT *inptp = p->asig;
141
142 /* init output array pointer 0th order */
143 MYFLT *rsltp_w = p->mw;
144
145 /* init output array pointers 1th order */
146 MYFLT *rsltp_x = p->mx;
147 MYFLT *rsltp_y = p->my;
148 MYFLT *rsltp_z = p->mz;
149
150 /* init output array pointers 2nd order */
151 MYFLT *rsltp_r = p->mr;
152 MYFLT *rsltp_s = p->ms;
153 MYFLT *rsltp_t = p->mt;
154 MYFLT *rsltp_u = p->mu;
155 MYFLT *rsltp_v = p->mv;
156
157 /* init output array pointers 3rd order */
158 MYFLT *rsltp_k = p->mk;
159 MYFLT *rsltp_l = p->ml;
160 MYFLT *rsltp_m = p->mm;
161 MYFLT *rsltp_n = p->mn;
162 MYFLT *rsltp_o = p->mo;
163 MYFLT *rsltp_p = p->mp;
164 MYFLT *rsltp_q = p->mq;
165
166 /* update coefficients */
167 ambicode_set_coefficients(p);
168
169 if (UNLIKELY(offset)) {
170 memset(rsltp_w, '\0', offset*sizeof(MYFLT));
171 memset(rsltp_x, '\0', offset*sizeof(MYFLT));
172 memset(rsltp_y, '\0', offset*sizeof(MYFLT));
173 memset(rsltp_z, '\0', offset*sizeof(MYFLT));
174 }
175 if (UNLIKELY(early)) {
176 nsmps -= early;
177 memset(&rsltp_w[nsmps], '\0', early*sizeof(MYFLT));
178 memset(&rsltp_x[nsmps], '\0', early*sizeof(MYFLT));
179 memset(&rsltp_y[nsmps], '\0', early*sizeof(MYFLT));
180 memset(&rsltp_z[nsmps], '\0', early*sizeof(MYFLT));
181 }
182 if (p->OUTOCOUNT == 4 && p->INOCOUNT >= 5) {
183 /* 1st order */
184 for (n=offset; n<nsmps; n++) {
185 /* 0th order */
186 rsltp_w[n] = *inptp * p->w * *p->kin[0];
187
188 /* 1st order */
189 rsltp_x[n] = inptp[n] * p->x * *p->kin[1];
190 rsltp_y[n] = inptp[n] * p->y * *p->kin[1];
191 rsltp_z[n] = inptp[n] * p->z * *p->kin[1];
192 }
193 }
194 else if (p->OUTOCOUNT == 9 && p->INOCOUNT >= 6) {
195 /* 2nd order */
196
197 if (UNLIKELY(offset)) {
198 memset(rsltp_r, '\0', offset*sizeof(MYFLT));
199 memset(rsltp_s, '\0', offset*sizeof(MYFLT));
200 memset(rsltp_t, '\0', offset*sizeof(MYFLT));
201 memset(rsltp_u, '\0', offset*sizeof(MYFLT));
202 memset(rsltp_v, '\0', offset*sizeof(MYFLT));
203 }
204 if (UNLIKELY(early)) {
205 memset(&rsltp_r[nsmps], '\0', early*sizeof(MYFLT));
206 memset(&rsltp_s[nsmps], '\0', early*sizeof(MYFLT));
207 memset(&rsltp_t[nsmps], '\0', early*sizeof(MYFLT));
208 memset(&rsltp_u[nsmps], '\0', early*sizeof(MYFLT));
209 memset(&rsltp_v[nsmps], '\0', early*sizeof(MYFLT));
210 }
211 for (n=offset; n<nsmps; n++) {
212 /* 0th order */
213 rsltp_w[n] = inptp[n] * p->w * *p->kin[0];
214
215 /* 1st order */
216 rsltp_x[n] = inptp[n] * p->x * *p->kin[1];
217 rsltp_y[n] = inptp[n] * p->y * *p->kin[1];
218 rsltp_z[n] = inptp[n] * p->z * *p->kin[1];
219
220 /* 2nd order */
221 rsltp_r[n] = inptp[n] * p->r * *p->kin[2];
222 rsltp_s[n] = inptp[n] * p->s * *p->kin[2];
223 rsltp_t[n] = inptp[n] * p->t * *p->kin[2];
224 rsltp_u[n] = inptp[n] * p->u * *p->kin[2];
225 rsltp_v[n] = inptp[n] * p->v * *p->kin[2];
226
227 }
228 }
229 else if (p->OUTOCOUNT == 16 && p->INOCOUNT >= 7) {
230 /* 3rd order */
231
232 if (UNLIKELY(offset)) {
233 memset(rsltp_r, '\0', offset*sizeof(MYFLT));
234 memset(rsltp_s, '\0', offset*sizeof(MYFLT));
235 memset(rsltp_t, '\0', offset*sizeof(MYFLT));
236 memset(rsltp_u, '\0', offset*sizeof(MYFLT));
237 memset(rsltp_v, '\0', offset*sizeof(MYFLT));
238 memset(rsltp_k, '\0', offset*sizeof(MYFLT));
239 memset(rsltp_l, '\0', offset*sizeof(MYFLT));
240 memset(rsltp_m, '\0', offset*sizeof(MYFLT));
241 memset(rsltp_n, '\0', offset*sizeof(MYFLT));
242 memset(rsltp_o, '\0', offset*sizeof(MYFLT));
243 memset(rsltp_p, '\0', offset*sizeof(MYFLT));
244 memset(rsltp_q, '\0', offset*sizeof(MYFLT));
245 }
246 if (UNLIKELY(early)) {
247 memset(&rsltp_r[nsmps], '\0', early*sizeof(MYFLT));
248 memset(&rsltp_s[nsmps], '\0', early*sizeof(MYFLT));
249 memset(&rsltp_t[nsmps], '\0', early*sizeof(MYFLT));
250 memset(&rsltp_u[nsmps], '\0', early*sizeof(MYFLT));
251 memset(&rsltp_v[nsmps], '\0', early*sizeof(MYFLT));
252 memset(&rsltp_k[nsmps], '\0', early*sizeof(MYFLT));
253 memset(&rsltp_l[nsmps], '\0', early*sizeof(MYFLT));
254 memset(&rsltp_m[nsmps], '\0', early*sizeof(MYFLT));
255 memset(&rsltp_n[nsmps], '\0', early*sizeof(MYFLT));
256 memset(&rsltp_o[nsmps], '\0', early*sizeof(MYFLT));
257 memset(&rsltp_p[nsmps], '\0', early*sizeof(MYFLT));
258 memset(&rsltp_q[nsmps], '\0', early*sizeof(MYFLT));
259 }
260 for (n=offset; n<nsmps; n++) {
261 /* 0th order */
262 rsltp_w[n] = inptp[n] * p->w * *p->kin[0];
263
264 /* 1st order */
265 rsltp_x[n] = inptp[n] * p->x * *p->kin[1];
266 rsltp_y[n] = inptp[n] * p->y * *p->kin[1];
267 rsltp_z[n] = inptp[n] * p->z * *p->kin[1];
268
269 /* 2nd order */
270 rsltp_r[n] = inptp[n] * p->r * *p->kin[2];
271 rsltp_s[n] = inptp[n] * p->s * *p->kin[2];
272 rsltp_t[n] = inptp[n] * p->t * *p->kin[2];
273 rsltp_u[n] = inptp[n] * p->u * *p->kin[2];
274 rsltp_v[n] = inptp[n] * p->v * *p->kin[2];
275
276 /* 3rd order */
277 rsltp_k[n] = inptp[n] * p->k * *p->kin[3];
278 rsltp_l[n] = inptp[n] * p->l * *p->kin[3];
279 rsltp_m[n] = inptp[n] * p->m * *p->kin[3];
280 rsltp_n[n] = inptp[n] * p->n * *p->kin[3];
281 rsltp_o[n] = inptp[n] * p->o * *p->kin[3];
282 rsltp_p[n] = inptp[n] * p->p * *p->kin[3];
283 rsltp_q[n] = inptp[n] * p->q * *p->kin[3];
284 }
285 }
286 return OK;
287 }
288
ambideco_set_coefficients(AMBID * p,double alpha,double beta,int32_t index)289 static void ambideco_set_coefficients(AMBID *p, double alpha, double beta,
290 int32_t index)
291 {
292 /* convert degrees to radian */
293 /* 0.017... = pi/180 */
294 double alpha_rad = alpha * 0.0174532925199432957692369076848861;
295 double beta_rad = beta * 0.0174532925199432957692369076848861;
296
297 /* calculate ambisonic coefficients (Furse-Malham-set) */
298
299 /* 0th order */
300 p->w[index] = 0.707106781186547524400844362104849; /* 1/sqrt(2) */
301
302 /* 1st order */
303 {
304 double cbeta = cos(beta_rad);
305 p->x[index] = cos(alpha_rad) * cbeta;
306 p->y[index] = sin(alpha_rad) * cbeta;
307 p->z[index] = sin(beta_rad);
308 }
309
310 /* 2nd order */
311 p->r[index] = 0.5 * (3.0 * p->z[index] * p->z[index] - 1.0);
312 p->s[index] = 2.0 * p->x[index] * p->z[index];
313 p->t[index] = 2.0 * p->y[index] * p->z[index];
314 p->u[index] = p->x[index] * p->x[index] - p->y[index] * p->y[index];
315 p->v[index] = 2.0 * p->x[index] * p->y[index];
316
317 /* 3rd order */
318 p->k[index] = 0.5 * p->z[index] * (5.0 * p->z[index] * p->z[index] - 3.0);
319 p->l[index] = (8.0/11.0) * p->y[index] * (5.0*p->z[index]* p->z[index] - 1.0);
320 p->m[index] = (8.0/11.0) * p->x[index] * (5.0*p->z[index]* p->z[index] - 1.0);
321 p->n[index] = 2.0 * p->x[index] * p->y[index] * p->z[index];
322 p->o[index] = p->z[index] *
323 (p->x[index] * p->x[index] - p->y[index] * p->y[index]);
324 p->p[index] = 3.0 * p->y[index] *
325 (3.0 * p->x[index] * p->x[index] - p->y[index] * p->y[index]);
326 p->q[index] = 3.0 * p->x[index] *
327 (p->x[index] * p->x[index] - 3.0 * p->y[index] * p->y[index]);
328 }
329
iambideco(CSOUND * csound,AMBID * p)330 static int32_t iambideco(CSOUND *csound, AMBID *p)
331 {
332 int32_t setup = (int32_t)*p->isetup;
333 csound->Warning(csound,
334 Str("bformdec is deprecated; use bformdec1 instead\n"));
335 if (setup<0) setup = -setup;
336 /* check correct number of input arguments */
337 if (UNLIKELY((p->INOCOUNT != 5) &&
338 (p->INOCOUNT != 10) &&
339 (p->INOCOUNT != 17))) {
340 return csound->InitError(csound, Str("Wrong number of input arguments!"));
341 }
342
343 switch (setup) {
344 case 1:
345 {
346 if (UNLIKELY(p->OUTOCOUNT != 2)) {
347 return csound->InitError(csound,
348 Str("Wrong number of output cells! "
349 "There must be 2 output cells."));
350 }
351 else if (*p->isetup>0) {
352 ambideco_set_coefficients(p, 330.0, 0.0, 0); /* left */
353 ambideco_set_coefficients(p, 30.0, 0.0, 1); /* right */
354 }
355 else {
356 int32_t i;
357 static double w[] = {0.707106781186547524400844362104849,
358 0.707106781186547524400844362104849};
359 /* static double x[] = {0.0, 0.0}; */
360 static double y[] = {0.5000,-0.5000};
361 /* static double z[] = {0.0, 0.0}; */
362 /* static double r[] = {0.0, 0.0}; */
363 /* static double s[] = {0.0, 0.0}; */
364 /* static double t[] = {0.0, 0.0}; */
365 /* static double u[] = {0.0, 0.0}; */
366 /* static double v[] = {0.0, 0.0}; */
367 for (i=0; i<2; i++) {
368 p->w[i] = w[i];
369 p->x[i] = 0.0;
370 p->y[i] = y[i];
371 p->z[i] = 0.0;
372 p->r[i] = 0.0;
373 p->s[i] = 0.0;
374 p->t[i] = 0.0;
375 p->u[i] = 0.0;
376 p->v[i] = 0.0;
377 p->k[i] = 0.0;
378 p->l[i] = 0.0;
379 p->m[i] = 0.0;
380 p->n[i] = 0.0;
381 p->o[i] = 0.0;
382 p->p[i] = 0.0;
383 p->q[i] = 0.0;
384 }
385 }
386 break;
387 }
388
389 case 2:
390 {
391 if (UNLIKELY(p->OUTOCOUNT != 4)) {
392 return csound->InitError(csound,
393 Str("Wrong number of output cells! "
394 "There must be 4 output cells."));
395 }
396 else if (*p->isetup>0) {
397 ambideco_set_coefficients(p, 45.0, 0.0, 0);
398 ambideco_set_coefficients(p, 135.0, 0.0, 1);
399 ambideco_set_coefficients(p, 225.0, 0.0, 2);
400 ambideco_set_coefficients(p, 315.0, 0.0, 3);
401 }
402 else {
403 int32_t i;
404 static double w[] = {0.3536, 0.3536, 0.3536, 0.3536};
405 static double x[] = {0.2434, 0.2434, -0.2434, -0.2434};
406 static double y[] = {0.2434, -0.2434, -0.2434, 0.2434};
407 /* static double z[] = {0.0, 0.0, 0.0, 0.0}; */
408 /* static double r[] = {0.0, 0.0, 0.0, 0.0}; */
409 /* static double s[] = {0.0, 0.0, 0.0, 0.0}; */
410 /* static double t[] = {0.0, 0.0, 0.0, 0.0}; */
411 /* static double u[] = {0.0, 0.0, 0.0, 0.0}; */
412 static double v[] = {0.0964, -0.0964, 0.0964, -0.0964};
413 for (i=0; i<4; i++) {
414 p->w[i] = w[i];
415 p->x[i] = x[i];
416 p->y[i] = y[i];
417 p->z[i] = 0.0;
418 p->r[i] = 0.0;
419 p->s[i] = 0.0;
420 p->t[i] = 0.0;
421 p->u[i] = 0.0;
422 p->v[i] = v[i];
423 p->k[i] = 0.0;
424 p->l[i] = 0.0;
425 p->m[i] = 0.0;
426 p->n[i] = 0.0;
427 p->o[i] = 0.0;
428 p->p[i] = 0.0;
429 p->q[i] = 0.0;
430 }
431 }
432 break;
433 }
434
435 case 3: {
436 if (UNLIKELY(p->OUTOCOUNT != 5)) {
437 return csound->InitError(csound,
438 Str("Wrong number of output cells! "
439 "There must be 5 output cells."));
440 }
441 else if (*p->isetup>0) {
442 ambideco_set_coefficients(p, 330.0, 0.0, 0); /* left */
443 ambideco_set_coefficients(p, 30.0, 0.0, 1); /* right */
444 ambideco_set_coefficients(p, 0.0, 0.0, 2); /* center */
445 ambideco_set_coefficients(p, 250.0, 0.0, 3); /* surround L */
446 ambideco_set_coefficients(p, 110.0, 0.0, 4); /* surround R */
447 }
448 else {
449 int32_t i;
450 /* Furze controlled opposites */
451 static double w[] = {0.2828, 0.2828, 0.2828, 0.2828, 0.2828};
452 static double x[] = {0.2227, -0.0851, -0.2753, -0.0851, 0.2227};
453 static double y[] = {0.1618, 0.2619, 0.0000, -0.2619, -0.1618};
454 /* static double z[] = {0.0, 0.0, 0.0, 0.0}; */
455 /* static double r[] = {0.0, 0.0, 0.0, 0.0}; */
456 /* static double s[] = {0.0, 0.0, 0.0, 0.0}; */
457 /* static double t[] = {0.0, 0.0, 0.0, 0.0}; */
458 static double u[] = {0.0238, -0.0624, 0.0771, -0.0624, 0.0238};
459 static double v[] = {0.0733, -0.0453, 0.0000, 0.0453, -0.0733};
460
461 for (i=0; i<5; i++) {
462 p->w[i] = w[i];
463 p->x[i] = x[i];
464 p->y[i] = y[i];
465 p->z[i] = 0.0;
466 p->r[i] = 0.0;
467 p->s[i] = 0.0;
468 p->t[i] = 0.0;
469 p->u[i] = u[i];
470 p->v[i] = v[i];
471 p->k[i] = 0.0;
472 p->l[i] = 0.0;
473 p->m[i] = 0.0;
474 p->n[i] = 0.0;
475 p->o[i] = 0.0;
476 p->p[i] = 0.0;
477 p->q[i] = 0.0;
478 }
479 }
480 break;
481 }
482
483 case 4:
484 {
485 if (UNLIKELY(p->OUTOCOUNT != 8)) {
486 return csound->InitError(csound,
487 Str("Wrong number of output cells! "
488 "There must be 8 output cells."));
489 }
490 else if (*p->isetup>0) {
491 ambideco_set_coefficients(p, 22.5, 0.0, 0);
492 ambideco_set_coefficients(p, 67.5, 0.0, 1);
493 ambideco_set_coefficients(p, 112.5, 0.0, 2);
494 ambideco_set_coefficients(p, 157.5, 0.0, 3);
495 ambideco_set_coefficients(p, 202.5, 0.0, 4);
496 ambideco_set_coefficients(p, 247.5, 0.0, 5);
497 ambideco_set_coefficients(p, 292.5, 0.0, 6);
498 ambideco_set_coefficients(p, 337.5, 0.0, 7);
499 }
500 else {
501 int32_t i;
502 static double w[] = {0.1768, 0.1768, 0.1768, 0.1768,
503 0.1768, 0.1768, 0.1768, 0.1768};
504 static double x[] = {0.1591, 0.0659, -0.0659,-0.1591,
505 -0.1591,-0.0659, 0.0659, 0.1591};
506 static double y[] = {0.0659, 0.1591, 0.1591, 0.0659,
507 -0.0659,-0.1591,-0.1591,-0.0659};
508 /* static double z[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */
509 /* static double r[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */
510 /* static double s[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */
511 /* static double t[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */
512 static double u[] = {0.0342,-0.0342,-0.0342, 0.0342,
513 0.0342,-0.0342,-0.0342, 0.0342};
514 static double v[] = {0.0342, 0.0342,-0.0342,-0.0342,
515 0.0342, 0.0342,-0.0342,-0.0342};
516 for (i=0; i<8; i++) {
517 p->w[i] = w[i];
518 p->x[i] = x[i];
519 p->y[i] = y[i];
520 p->z[i] = 0.0;
521 p->r[i] = 0.0;
522 p->s[i] = 0.0;
523 p->t[i] = 0.0;
524 p->u[i] = u[i];
525 p->v[i] = v[i];
526 p->k[i] = 0.0;
527 p->l[i] = 0.0;
528 p->m[i] = 0.0;
529 p->n[i] = 0.0;
530 p->o[i] = 0.0;
531 p->p[i] = 0.0;
532 p->q[i] = 0.0;
533 }
534 }
535 break;
536 }
537
538 case 5:
539 {
540 if (UNLIKELY(p->OUTOCOUNT != 8)) {
541 return csound->InitError(csound,
542 Str("Wrong number of output cells! "
543 "There must be 8 output cells."));
544 }
545 else if (*p->isetup>0) {
546 ambideco_set_coefficients(p, 45.0, 0.0, 0);
547 ambideco_set_coefficients(p, 45.0, 30.0, 1);
548 ambideco_set_coefficients(p, 135.0, 0.0, 2);
549 ambideco_set_coefficients(p, 135.0, 30.0, 3);
550 ambideco_set_coefficients(p, 225.0, 0.0, 4);
551 ambideco_set_coefficients(p, 225.0, 30.0, 5);
552 ambideco_set_coefficients(p, 315.0, 0.0, 6);
553 ambideco_set_coefficients(p, 315.0, 30.0, 7);
554 }
555 else {
556 int32_t i;
557 static double w[] = {0.1768,0.1768,0.1768,0.1768,
558 0.1768,0.1768,0.1768,0.1768};
559 static double x[] = {0.1140, 0.1140,-0.1140,-0.1140,
560 0.1140, 0.1140,-0.1140,-0.1140};
561 static double y[] = {0.1140,-0.1140,-0.1140, 0.1140,
562 0.1140,-0.1140,-0.1140, 0.1140};
563 static double z[] = {-0.1140,-0.1140,-0.1140,-0.1140,
564 0.1140, 0.1140, 0.1140, 0.1140};
565 /* static double r[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */
566 static double s[] = {-0.0369,-0.0369, 0.0369, 0.0369,
567 0.0369, 0.0369,-0.0369,-0.0369};
568 static double t[] = {-0.0369, 0.0369, 0.0369,-0.0369,
569 0.0369,-0.0369,-0.0369, 0.0369};
570 /* static double u[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; */
571 static double v[] = { 0.0369,-0.0369, 0.0369,-0.0369,
572 0.0369,-0.0369, 0.0369,-0.0369};
573 for (i=0; i<8; i++) {
574 p->w[i] = w[i];
575 p->x[i] = x[i];
576 p->y[i] = y[i];
577 p->z[i] = z[i];
578 p->r[i] = 0.0;
579 p->s[i] = s[i];
580 p->t[i] = t[i];
581 p->u[i] = 0.0;
582 p->v[i] = v[i];
583 p->k[i] = 0.0;
584 p->l[i] = 0.0;
585 p->m[i] = 0.0;
586 p->n[i] = 0.0;
587 p->o[i] = 0.0;
588 p->p[i] = 0.0;
589 p->q[i] = 0.0;
590 }
591 }
592 break;
593 }
594 case 6: {
595 if (UNLIKELY(p->OUTOCOUNT != 5)) {
596 return csound->InitError(csound,
597 Str("Wrong number of output cells! "
598 "There must be 5 output cells."));
599 }
600 /* These are Wiggins' cpefficients */
601 /* L 30° {0.4724, 0.7143, 0.7258, 0.0000, 0.3456}
602 R -30° {0.4724, 0.7143, -0.7258, 0.0000, -0.3456}
603 C 0° {0.3226, 0.7719, 0.0000, 0.0000, 0.4724}
604 LS 110° {0.9101, -0.7834, 0.9562, -0.0806, 0.0000}
605 RS -110° {0.9101, -0.7834, -0.9562, -0.0806, 0.0000} */
606 {
607 int32_t i;
608 static double w[] = {0.4724, 0.4724, 0.3226, 0.9101, 0.9101};
609 static double x[] = {0.7143, 0.7143, 0.7719,-0.7834,-0.7834};
610 static double y[] = {0.7258,-0.7258, 0.0000, 0.9562,-0.9562};
611 static double u[] = {0.0000,0.0000,0.0000,-0.0806,-0.0806};
612 static double v[] = {0.3456,-0.3456,0.4724,0.0000,0.0000};
613 for (i=0; i<5; i++) {
614 p->w[i] = w[i];
615 p->x[i] = x[i];
616 p->y[i] = y[i];
617 p->z[i] = 0.0;
618 p->r[i] = 0.0;
619 p->s[i] = 0.0;
620 p->t[i] = 0.0;
621 p->u[i] = u[i];
622 p->v[i] = v[i];
623 p->k[i] = 0.0;
624 p->l[i] = 0.0;
625 p->m[i] = 0.0;
626 p->n[i] = 0.0;
627 p->o[i] = 0.0;
628 p->p[i] = 0.0;
629 p->q[i] = 0.0;
630 }
631 }
632 break;
633 }
634
635 default:
636 return csound->InitError(csound, Str("Not supported setup number!"));
637 }
638 return OK;
639 }
640
aambideco(CSOUND * csound,AMBID * p)641 static int32_t aambideco(CSOUND *csound, AMBID *p)
642 {
643 IGN(csound);
644 uint32_t offset = p->h.insdshead->ksmps_offset;
645 uint32_t early = p->h.insdshead->ksmps_no_end;
646 uint32_t i=0, n, nsmps = CS_KSMPS;
647
648 /* init input array pointer 0th order */
649 MYFLT *inptp_w = p->aw;
650
651 /* init input array pointer 1st order */
652 MYFLT *inptp_x = p->ax;
653 MYFLT *inptp_y = p->ay;
654 MYFLT *inptp_z = p->a[0];
655
656 /* init input array pointer 2nd order */
657 MYFLT *inptp_r = p->a[1];
658 MYFLT *inptp_s = p->a[2];
659 MYFLT *inptp_t = p->a[3];
660 MYFLT *inptp_u = p->a[4];
661 MYFLT *inptp_v = p->a[5];
662
663 /* init input array pointer 3rd order */
664 MYFLT *inptp_k = p->a[6];
665 MYFLT *inptp_l = p->a[7];
666 MYFLT *inptp_m = p->a[8];
667 MYFLT *inptp_n = p->a[9];
668 MYFLT *inptp_o = p->a[10];
669 MYFLT *inptp_p = p->a[11];
670 MYFLT *inptp_q = p->a[12];
671
672 /* init output array pointer */
673 MYFLT *rsltp[8];
674
675 rsltp[0] = p->m0;
676 rsltp[1] = p->m1;
677 rsltp[2] = p->m2;
678 rsltp[3] = p->m3;
679 rsltp[4] = p->m4;
680 rsltp[5] = p->m5;
681 rsltp[6] = p->m6;
682 rsltp[7] = p->m7;
683 if (UNLIKELY(offset)) for (i = 0; i < p->OUTOCOUNT; i++)
684 memset(rsltp[i], '\0', offset*sizeof(MYFLT));
685 if (UNLIKELY(early)) {
686 nsmps -= early;
687 for (i = 0; i < p->OUTOCOUNT; i++)
688 memset(&rsltp[i][nsmps], '\0', early*sizeof(MYFLT));
689 }
690 /* L = 0.5 * (0.9397*W + 0.1856*X - j*0.342*W + j*0.5099*X + 0.655*Y)
691
692 R = 0.5 * (0.9397*W+ 0.1856*X + j*0.342*W - j*0.5099*X - 0.655*Y) */
693 if (p->INOCOUNT == 5) {
694 for (n=offset; n<nsmps; n++) {
695 /* 1st order */
696 for (i = 0; i < p->OUTOCOUNT; i++) {
697 /* calculate output for every used loudspeaker */
698 rsltp[i][n] = inptp_w[n] * p->w[i] + inptp_x[n] * p->x[i] +
699 inptp_y[n] * p->y[i] + inptp_z[n] * p->z[i];
700 }
701 }
702 }
703 else if (p->INOCOUNT == 10) {
704 for (n=offset; n<nsmps; n++) {
705 /* 2nd order */
706 for (i = 0; i < p->OUTOCOUNT; i++) {
707 /* calculate output for every used loudspeaker */
708 rsltp[i][n] = inptp_w[n] * p->w[i] + inptp_x[n] * p->x[i] +
709 inptp_y[n] * p->y[i] + inptp_z[n] * p->z[i] +
710 inptp_r[n] * p->r[i] + inptp_s[n] * p->s[i] +
711 inptp_t[n] * p->t[i] + inptp_u[n] * p->u[i] +
712 inptp_v[n] * p->v[i];
713 }
714 }
715 }
716 else if (p->INOCOUNT == 17) {
717 for (n=offset; n<nsmps; n++) {
718 /* 3rd order */
719 for (i = 0; i < p->OUTOCOUNT; i++) {
720 /* calculate output for every used loudspeaker */
721 rsltp[i][n] = inptp_w[n] * p->w[i] + inptp_x[n] * p->x[i] +
722 inptp_y[n] * p->y[i] + inptp_z[n] * p->z[i] +
723 inptp_r[n] * p->r[i] + inptp_s[n] * p->s[i] +
724 inptp_t[n] * p->t[i] + inptp_u[n] * p->u[i] +
725 inptp_v[n] * p->v[i] + inptp_k[n] * p->k[i] +
726 inptp_l[n] * p->l[i] + inptp_m[n] * p->m[i] +
727 inptp_n[n] * p->n[i] + inptp_o[n] * p->o[i] +
728 inptp_p[n] * p->p[i] + inptp_q[n] * p->q[i];
729 }
730 }
731 }
732 return OK;
733 }
734
735 #define S(x) sizeof(x)
736
737 static OENTRY localops[] = {
738 { "bformenc", S(AMBIC), _QQ, 3, "mmmmmmmmmmmmmmmm", "akkPPPP",
739 (SUBR)iambicode, (SUBR)aambicode },
740 { "bformdec", S(AMBID), _QQ, 3, "mmmmmmmm", "iaaay",
741 (SUBR)iambideco, (SUBR)aambideco }
742 };
743
ambicode_init_(CSOUND * csound)744 int32_t ambicode_init_(CSOUND *csound)
745 {
746 return csound->AppendOpcodes(csound, &(localops[0]),
747 (int32_t
748 ) (sizeof(localops) / sizeof(OENTRY)));
749 }
750