1 /*
2 ugnorman.c:
3
4 Copyright 2004 Alex Norman
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 /* ats-csound version 0.1
25 * Mon May 10 19:44:46 PDT 2004
26 * ATScsound Ugens, adapted by Alex Norman (2003)
27 * from the phase vocoder csound code by Richard Karpen
28 * If you find bugs contact me at alexnorman@users.sourceforge.net
29
30 Some basic info:
31
32 ATSinfo:
33
34 idata ATSinfo iatsfile, idataloc
35
36 read functions:
37
38 kfreq, kamp ATSread ktimepnt, ifile, ipartial
39 kenergy ATSreadnz ktimepnt, ifile, iband
40
41 add functions:
42
43 ar ATSadd ktimepnt, kfmod, iatsfile, ifn, ipartials \
44 [, ipartialoffset, ipartialincr, igatefn]
45 ar ATSaddnz ktimepnt, iatsfile, ibands \
46 [, ibandoffset, ibandincr]
47
48 sinnoi function:
49
50 ar ATSsinnoi ktimepnt, ksinlev, knzlev, kfreqscale, \
51 iatsfile, ipartials[, ipartialoffset, ipartialincr]
52
53 buf/cross functions:
54
55 ATSbufread ktimepnt, kfmod, iatsfile, ipartials \
56 [, ipartialoffset, ipartialincr]
57 ar ATScross ktimepnt, kfmod, iatsfile, ifn, kmyamp, \
58 kbufamp, ipartials[, ipartialoffset, ipartialincr]
59 kfreq, kamp ATSpartialtap ipartialnum
60 kamp ATSinterpread kfreq
61
62 */
63
64 //was frIndx > p->maxFr
65 #define OUT_OF_FRAMES (frIndx >= p->maxFr+1)
66
67 #include "ugnorman.h"
68 #include <ctype.h>
69 #include "interlocks.h"
70
71 #define ATSA_NOISE_VARIANCE 0.04
72
73 #define ATSA_CRITICAL_BAND_EDGES \
74 { 0.0, 100.0, 200.0, 300.0, 400.0, 510.0, 630.0, 770.0, 920.0, 1080.0, \
75 1270.0, 1480.0, 1720.0, 2000.0, 2320.0, 2700.0, 3150.0, 3700.0, \
76 4400.0, 5300.0, 6400.0, 7700.0, 9500.0, 12000.0, 15500.0, 20000.0 }
77
78 /* static variables used for atsbufread and atsbufreadnz */
get_atsbufreadaddrp(CSOUND * csound)79 static inline ATSBUFREAD **get_atsbufreadaddrp(CSOUND *csound)
80 {
81 return &(((STDOPCOD_GLOBALS*) csound->stdOp_Env)->atsbufreadaddr);
82 }
83
84 /* byte swaps a double */
85
bswap(const double * swap_me)86 static CS_PURE double bswap(const double *swap_me)
87 {
88 double d;
89 const unsigned char *p1 = (const unsigned char *) swap_me;
90 unsigned char *p2 = (unsigned char *) &d;
91
92 p2[0] = p1[7];
93 p2[1] = p1[6];
94 p2[2] = p1[5];
95 p2[3] = p1[4];
96 p2[4] = p1[3];
97 p2[5] = p1[2];
98 p2[6] = p1[1];
99 p2[7] = p1[0];
100
101 return d;
102 }
103
104 /* load ATS file into memory; returns "is swapped" boolean, or -1 on error */
105
load_atsfile(CSOUND * csound,void * p,MEMFIL ** mfp,char * fname,void * name_arg,int32_t istring)106 static int32_t load_atsfile(CSOUND *csound, void *p, MEMFIL **mfp, char *fname,
107 void *name_arg, int32_t istring)
108 {
109 char opname[64];
110 STDOPCOD_GLOBALS *pp;
111 ATSSTRUCT *atsh;
112 int32_t i;
113
114 strNcpy(opname, csound->GetOpcodeName(p), 63); /* opcode name */
115 opname[63]='\0';
116 for (i = 0; opname[i] != '\0'; i++)
117 opname[i] = toupper(opname[i]); /* converted to upper case */
118
119 /* copy in ats file name */
120 if (istring) strNcpy(fname, ((STRINGDAT*)name_arg)->data,MAXNAME-1) ;
121 else {
122 if (csound->ISSTRCOD(*((MYFLT*)name_arg)))
123 strNcpy(fname,get_arg_string(csound, *((MYFLT*)name_arg)),MAXNAME-1);
124 else csound->strarg2name(csound, fname, name_arg, "ats.",0);
125 }
126 /* load memfile */
127 if (UNLIKELY((*mfp = csound->ldmemfile2withCB(csound, fname,
128 CSFTYPE_ATS, NULL)) == NULL)) {
129 return csound->InitError(csound,
130 Str("%s: Ats file %s not read (does it exist?)"),
131 opname, fname);
132 }
133 atsh = (ATSSTRUCT*) (*mfp)->beginp;
134
135 /* make sure that this is an ats file */
136 if (atsh->magic == 123.0)
137 return 0;
138 /* check to see if it is byteswapped */
139 if (UNLIKELY((int32_t) bswap(&(atsh->magic)) != 123)) {
140 return csound->InitError(csound, Str("%s: either %s is not an ATS file "
141 "or the byte endianness is wrong"),
142 opname, fname);
143 }
144 pp = (STDOPCOD_GLOBALS*) csound->stdOp_Env;
145 if (pp->swapped_warning)
146 return 1;
147 csound->Warning(csound,
148 Str("%s: %s is byte-swapped\n"
149 "\tno future byte-swapping warnings will be given, "
150 "byte-swapped files\n\twill not result in different "
151 "audio, but they may slow down processing."),
152 opname, fname);
153 pp->swapped_warning = 1;
154 return 1;
155 }
156
157 /* ats info simply reads data out of the header of an atsfile. (i-rate) */
atsinfo_S(CSOUND * csound,ATSINFO * p)158 static int32_t atsinfo_S(CSOUND *csound, ATSINFO *p)
159 {
160 char atsfilname[MAXNAME];
161 ATSSTRUCT *atsh;
162 MEMFIL *memfile = NULL;
163 double *ret_data; /* data to return */
164 int32_t swapped = 0; /* flag to indicate if data needs to be swapped */
165
166 /* load memfile */
167 swapped = load_atsfile(csound, p, &memfile, atsfilname, p->ifileno, 1);
168 if (UNLIKELY(swapped < 0))
169 return NOTOK;
170 atsh = (ATSSTRUCT*) memfile->beginp;
171
172 switch ((int32_t) MYFLT2LRND(*p->ilocation)) {
173 case 0: ret_data = &(atsh->sampr); break;
174 case 1: ret_data = &(atsh->frmsz); break;
175 case 2: ret_data = &(atsh->winsz); break;
176 case 3: ret_data = &(atsh->npartials); break;
177 case 4: ret_data = &(atsh->nfrms); break;
178 case 5: ret_data = &(atsh->ampmax); break;
179 case 6: ret_data = &(atsh->freqmax); break;
180 case 7: ret_data = &(atsh->dur); break;
181 case 8: ret_data = &(atsh->type); break;
182 default:
183 return csound->InitError(csound,
184 Str("ATSINFO: location is out of bounds: "
185 "0-8 are the only possible selections"));
186 }
187 /* if not swapped then just return the data */
188 if (!swapped) {
189 *p->ireturn = (MYFLT) *ret_data;
190 return OK;
191 }
192 /* otherwise do byteswapping */
193 *p->ireturn = (MYFLT) bswap(ret_data);
194 return OK;
195 }
196
atsinfo(CSOUND * csound,ATSINFO * p)197 static int32_t atsinfo(CSOUND *csound, ATSINFO *p)
198 {
199 char atsfilname[MAXNAME];
200 ATSSTRUCT *atsh;
201 MEMFIL *memfile = NULL;
202 double *ret_data; /* data to return */
203 int32_t swapped = 0; /* flag to indicate if data needs to be swapped */
204
205 /* load memfile */
206 swapped = load_atsfile(csound, p, &memfile, atsfilname, p->ifileno, 0);
207 if (UNLIKELY(swapped < 0))
208 return NOTOK;
209 atsh = (ATSSTRUCT*) memfile->beginp;
210
211 switch ((int32_t) MYFLT2LRND(*p->ilocation)) {
212 case 0: ret_data = &(atsh->sampr); break;
213 case 1: ret_data = &(atsh->frmsz); break;
214 case 2: ret_data = &(atsh->winsz); break;
215 case 3: ret_data = &(atsh->npartials); break;
216 case 4: ret_data = &(atsh->nfrms); break;
217 case 5: ret_data = &(atsh->ampmax); break;
218 case 6: ret_data = &(atsh->freqmax); break;
219 case 7: ret_data = &(atsh->dur); break;
220 case 8: ret_data = &(atsh->type); break;
221 default:
222 return csound->InitError(csound,
223 Str("ATSINFO: location is out of bounds: "
224 "0-8 are the only possible selections"));
225 }
226 /* if not swapped then just return the data */
227 if (!swapped) {
228 *p->ireturn = (MYFLT) *ret_data;
229 return OK;
230 }
231 /* otherwise do byteswapping */
232 *p->ireturn = (MYFLT) bswap(ret_data);
233 return OK;
234 }
235
236 /************************************************************/
237 /********* ATSREAD ***********************************/
238 /************************************************************/
239
FetchPartial(ATSREAD * p,MYFLT * buf,MYFLT position)240 static void FetchPartial(ATSREAD *p, MYFLT *buf, MYFLT position)
241 {
242 MYFLT frac; /* the distance in time we are between frames */
243 int32_t frame; /* the number of the first frame */
244 double *frm_1, *frm_2; /* a pointer to frame 1 and frame 2 */
245 double frm1amp, frm1freq, frm2amp, frm2freq;
246
247 frame = (int32_t) position;
248 frm_1 = p->datastart + p->frmInc * frame + p->partialloc;
249
250 /* if we are using the data from the last frame */
251 /* we should not try to interpolate */
252 if (frame == p->maxFr) {
253 if (p->swapped == 1) {
254 buf[0] = (MYFLT) bswap(frm_1); /* calc amplitude */
255 buf[1] = (MYFLT) bswap(frm_1 + 1); /* calc freq */
256 }
257 else {
258 buf[0] = (MYFLT) *frm_1; /* calc amplitude */
259 buf[1] = (MYFLT) *(frm_1 + 1); /* calc freq */
260 }
261 return;
262 }
263 frm_2 = frm_1 + p->frmInc;
264 frac = position - frame;
265
266 /* byte swap if needed */
267 if (p->swapped == 1) {
268 frm1amp = bswap(frm_1);
269 frm2amp = bswap(frm_2);
270 frm1freq = bswap(frm_1 + 1);
271 frm2freq = bswap(frm_2 + 1);
272 }
273 else {
274 frm1amp = *frm_1;
275 frm2amp = *frm_2;
276 frm1freq = *(frm_1 + 1);
277 frm2freq = *(frm_2 + 1);
278 }
279 buf[0] = (MYFLT) (frm1amp + frac * (frm2amp - frm1amp)); /* calc amp. */
280 buf[1] = (MYFLT) (frm1freq + frac * (frm2freq - frm1freq)); /* calc freq */
281 }
282
atsreadset(CSOUND * csound,ATSREAD * p)283 static int32_t atsreadset(CSOUND *csound, ATSREAD *p)
284 {
285 char atsfilname[MAXNAME];
286 ATSSTRUCT *atsh;
287 int32_t n_partials;
288 int32_t type;
289
290 /* load memfile */
291 p->swapped = load_atsfile(csound,
292 p, &(p->atsmemfile), atsfilname, p->ifileno, 0);
293 if (UNLIKELY(p->swapped < 0))
294 return NOTOK;
295 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
296
297 /* byte swap if necessary */
298 if (p->swapped == 1) {
299 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
300 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
301 n_partials = (int32_t) bswap(&atsh->npartials);
302 type = (int32_t) bswap(&atsh->type);
303 }
304 else {
305 p->maxFr = (int32_t) atsh->nfrms - 1;
306 p->timefrmInc = atsh->nfrms / atsh->dur;
307 n_partials = (int32_t) atsh->npartials;
308 type = (int32_t) atsh->type;
309 }
310
311 /* check to see if partial is valid */
312 if (UNLIKELY((int32_t) (*p->ipartial) > n_partials ||
313 (int32_t) (*p->ipartial) <= 0)) {
314 return csound->InitError(csound, Str("ATSREAD: partial %i out of range, "
315 "max allowed is %i"),
316 (int32_t) (*p->ipartial), n_partials);
317 }
318
319 /* point the data pointer to the correct partial */
320 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
321
322 switch (type) {
323 case 1:
324 p->partialloc = 1 + 2 * (*p->ipartial - 1);
325 p->frmInc = n_partials * 2 + 1;
326 break;
327 case 2:
328 p->partialloc = 1 + 3 * (*p->ipartial - 1);
329 p->frmInc = n_partials * 3 + 1;
330 break;
331 case 3:
332 p->partialloc = 1 + 2 * (*p->ipartial - 1);
333 p->frmInc = n_partials * 2 + 26;
334 break;
335 case 4:
336 p->partialloc = 1 + 3 * (*p->ipartial - 1);
337 p->frmInc = n_partials * 3 + 26;
338 break;
339 default:
340 return csound->InitError(csound, Str("Type not implemented"));
341 }
342
343 /* flag set to reduce the amount of warnings sent out */
344 /* for time pointer out of range */
345 p->prFlg = 1; /* true */
346 return OK;
347 }
348
349
atsreadset_S(CSOUND * csound,ATSREAD * p)350 static int32_t atsreadset_S(CSOUND *csound, ATSREAD *p)
351 {
352 char atsfilname[MAXNAME];
353 ATSSTRUCT *atsh;
354 int32_t n_partials;
355 int32_t type;
356
357 /* load memfile */
358 p->swapped = load_atsfile(csound,
359 p, &(p->atsmemfile), atsfilname, p->ifileno, 1);
360 if (UNLIKELY(p->swapped < 0))
361 return NOTOK;
362 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
363
364 /* byte swap if necessary */
365 if (p->swapped == 1) {
366 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
367 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
368 n_partials = (int32_t) bswap(&atsh->npartials);
369 type = (int32_t) bswap(&atsh->type);
370 }
371 else {
372 p->maxFr = (int32_t) atsh->nfrms - 1;
373 p->timefrmInc = atsh->nfrms / atsh->dur;
374 n_partials = (int32_t) atsh->npartials;
375 type = (int32_t) atsh->type;
376 }
377
378 /* check to see if partial is valid */
379 if (UNLIKELY((int32_t) (*p->ipartial) > n_partials ||
380 (int32_t) (*p->ipartial) <= 0)) {
381 return csound->InitError(csound, Str("ATSREAD: partial %i out of range, "
382 "max allowed is %i"),
383 (int32_t) (*p->ipartial), n_partials);
384 }
385
386 /* point the data pointer to the correct partial */
387 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
388
389 switch (type) {
390 case 1:
391 p->partialloc = 1 + 2 * (*p->ipartial - 1);
392 p->frmInc = n_partials * 2 + 1;
393 break;
394 case 2:
395 p->partialloc = 1 + 3 * (*p->ipartial - 1);
396 p->frmInc = n_partials * 3 + 1;
397 break;
398 case 3:
399 p->partialloc = 1 + 2 * (*p->ipartial - 1);
400 p->frmInc = n_partials * 2 + 26;
401 break;
402 case 4:
403 p->partialloc = 1 + 3 * (*p->ipartial - 1);
404 p->frmInc = n_partials * 3 + 26;
405 break;
406 default:
407 return csound->InitError(csound, Str("Type not implemented"));
408 }
409
410 /* flag set to reduce the amount of warnings sent out */
411 /* for time pointer out of range */
412 p->prFlg = 1; /* true */
413 return OK;
414 }
415
atsread(CSOUND * csound,ATSREAD * p)416 static int32_t atsread(CSOUND *csound, ATSREAD *p)
417 {
418 MYFLT frIndx;
419 MYFLT buf[2];
420
421 if (UNLIKELY(p->atsmemfile == NULL)) goto err1;
422 if ((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0)) {
423 frIndx = FL(0.0);
424 if (UNLIKELY(p->prFlg)) {
425 p->prFlg = 0; /* set to false */
426 csound->Warning(csound, Str("ATSREAD: only positive time pointer "
427 "values allowed, setting to zero\n"));
428 }
429 }
430 else if (OUT_OF_FRAMES) {
431 /* if we are trying to get frames past where we have data */
432 frIndx = (MYFLT) p->maxFr;
433 if (UNLIKELY(p->prFlg)) {
434 p->prFlg = 0; /* set to false */
435 csound->Warning(csound, Str("ATSREAD: timepointer out of range, "
436 "truncated to last frame\n"));
437 }
438 }
439 else
440 p->prFlg = 1;
441
442 FetchPartial(p, buf, frIndx);
443 *p->kamp = buf[0];
444 *p->kfreq = buf[1];
445
446 return OK;
447 err1:
448 return csound->PerfError(csound, &(p->h),
449 Str("ATSREAD: not initialised"));
450 }
451
452 /*
453 * ATSREADNOISE
454 */
FetchNzBand(ATSREADNZ * p,MYFLT position)455 static MYFLT FetchNzBand(ATSREADNZ *p, MYFLT position)
456 {
457 MYFLT frac; /* the distance in time we are between frames */
458 int32_t frame; /* the time of the first frame */
459 double *frm_1, *frm_2;
460 double frm1val, frm2val;
461
462 frame = (int32_t) position;
463 frm_1 = p->datastart + p->frmInc * frame + p->nzbandloc;
464 frm1val = (p->swapped == 1) ? bswap(frm_1) : *frm_1;
465
466 /* if we are using the data from the last frame */
467 /* we should not try to interpolate */
468 if (UNLIKELY(frame == p->maxFr))
469 return (MYFLT) frm1val;
470
471 frm_2 = frm_1 + p->frmInc;
472 frac = position - frame;
473 frm2val = (p->swapped == 1) ? bswap(frm_2) : *frm_2;
474
475 return (MYFLT) (frm1val + frac * (frm2val - frm1val)); /* calc energy */
476 }
477
atsreadnzset(CSOUND * csound,ATSREADNZ * p)478 static int32_t atsreadnzset(CSOUND *csound, ATSREADNZ *p)
479 {
480 char atsfilname[MAXNAME];
481 ATSSTRUCT *atsh;
482 int32_t n_partials;
483 int32_t type;
484
485 /* load memfile */
486 p->swapped = load_atsfile(csound,
487 p, &(p->atsmemfile), atsfilname, p->ifileno, 0);
488 if (UNLIKELY(p->swapped < 0))
489 return NOTOK;
490 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
491
492 /* byte swap if necessary */
493 if (p->swapped == 1) {
494 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
495 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
496 n_partials = (int32_t) bswap(&atsh->npartials);
497 type = (int32_t) bswap(&atsh->type);
498 }
499 else {
500 p->maxFr = (int32_t) atsh->nfrms - 1;
501 p->timefrmInc = atsh->nfrms / atsh->dur;
502 n_partials = (int32_t) atsh->npartials;
503 type = (int32_t) atsh->type;
504 }
505
506 /* point the data pointer to the correct partial */
507 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
508
509 /* check to see if band is valid */
510 if (UNLIKELY((int32_t) (*p->inzbin) > 25 || (int32_t) (*p->inzbin) <= 0)) {
511 return csound->InitError(csound, Str("ATSREADNZ: band %i out of range, "
512 "1-25 are the valid band values"),
513 (int32_t) (*p->inzbin));
514 }
515
516 switch (type) {
517 case 3:
518 /* get past the partial data to the noise */
519 p->nzbandloc = (int32_t) (2 * n_partials + *p->inzbin);
520 p->frmInc = n_partials * 2 + 26;
521 break;
522
523 case 4:
524 p->nzbandloc = (int32_t) (3 * n_partials + *p->inzbin);
525 p->frmInc = n_partials * 3 + 26;
526 break;
527 default:
528 return csound->InitError(csound,
529 Str("ATSREADNZ: Type either not implemented "
530 "or does not contain noise"));
531 }
532 /* flag set to reduce the amount of warnings sent out */
533 /* for time pointer out of range */
534 p->prFlg = 1; /* true */
535 return OK;
536 }
537
atsreadnzset_S(CSOUND * csound,ATSREADNZ * p)538 static int32_t atsreadnzset_S(CSOUND *csound, ATSREADNZ *p)
539 {
540 char atsfilname[MAXNAME];
541 ATSSTRUCT *atsh;
542 int32_t n_partials;
543 int32_t type;
544
545 /* load memfile */
546 p->swapped = load_atsfile(csound,
547 p, &(p->atsmemfile), atsfilname, p->ifileno, 1);
548 if (UNLIKELY(p->swapped < 0))
549 return NOTOK;
550 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
551
552 /* byte swap if necessary */
553 if (p->swapped == 1) {
554 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
555 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
556 n_partials = (int32_t) bswap(&atsh->npartials);
557 type = (int32_t) bswap(&atsh->type);
558 }
559 else {
560 p->maxFr = (int32_t) atsh->nfrms - 1;
561 p->timefrmInc = atsh->nfrms / atsh->dur;
562 n_partials = (int32_t) atsh->npartials;
563 type = (int32_t) atsh->type;
564 }
565
566 /* point the data pointer to the correct partial */
567 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
568
569 /* check to see if band is valid */
570 if (UNLIKELY((int32_t) (*p->inzbin) > 25 || (int32_t) (*p->inzbin) <= 0)) {
571 return csound->InitError(csound, Str("ATSREADNZ: band %i out of range, "
572 "1-25 are the valid band values"),
573 (int32_t) (*p->inzbin));
574 }
575
576 switch (type) {
577 case 3:
578 /* get past the partial data to the noise */
579 p->nzbandloc = (int32_t) (2 * n_partials + *p->inzbin);
580 p->frmInc = n_partials * 2 + 26;
581 break;
582
583 case 4:
584 p->nzbandloc = (int32_t) (3 * n_partials + *p->inzbin);
585 p->frmInc = n_partials * 3 + 26;
586 break;
587 default:
588 return csound->InitError(csound,
589 Str("ATSREADNZ: Type either not implemented "
590 "or does not contain noise"));
591 }
592 /* flag set to reduce the amount of warnings sent out */
593 /* for time pointer out of range */
594 p->prFlg = 1; /* true */
595 return OK;
596 }
597
598
atsreadnz(CSOUND * csound,ATSREADNZ * p)599 static int32_t atsreadnz(CSOUND *csound, ATSREADNZ *p)
600 {
601 MYFLT frIndx;
602
603 if (UNLIKELY(p->atsmemfile == NULL)) goto err1;
604 /* make sure we have not over steped the bounds of the data */
605 if ((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0)) {
606 frIndx = FL(0.0);
607 if (UNLIKELY(p->prFlg)) {
608 p->prFlg = 0; /* set to false */
609 csound->Warning(csound, Str("ATSREADNZ: only positive time pointer "
610 "values allowed, setting to zero\n"));
611 }
612 }
613 else if (OUT_OF_FRAMES) {
614 /* if we are trying to get frames past where we have data */
615 frIndx = (MYFLT) p->maxFr;
616 if (UNLIKELY(p->prFlg)) {
617 p->prFlg = 0; /* set to false */
618 csound->Warning(csound, Str("ATSREADNZ: timepointer out of range, "
619 "truncated to last frame\n"));
620 }
621 }
622 else
623 p->prFlg = 1;
624 *p->kenergy = FetchNzBand(p, frIndx);
625 return OK;
626 err1:
627 return csound->PerfError(csound, &(p->h),
628 Str("ATSREADNZ: not initialised"));
629 }
630
631 /*
632 * ATSADD
633 */
634 static void FetchADDPartials(ATSADD *, ATS_DATA_LOC *, MYFLT);
635 static void AtsAmpGate(ATS_DATA_LOC *, int32_t, FUNC *, double);
636
atsaddset(CSOUND * csound,ATSADD * p)637 static int32_t atsaddset(CSOUND *csound, ATSADD *p)
638 {
639 char atsfilname[MAXNAME];
640 ATSSTRUCT *atsh;
641 FUNC *ftp, *AmpGateFunc;
642 int32_t memsize, n_partials, type;
643
644 /* set up function table for synthesis */
645 if (UNLIKELY((ftp = csound->FTFind(csound, p->ifn)) == NULL)) {
646 return csound->InitError(csound, Str("ATSADD: Function table number "
647 "for synthesis waveform not valid"));
648 }
649 p->ftp = ftp;
650
651 /* set up gate function table */
652 if (*p->igatefun > FL(0.0)) {
653 if (UNLIKELY((AmpGateFunc = csound->FTFind(csound, p->igatefun)) == NULL)) {
654 return csound->InitError(csound, Str("ATSADD: Gate Function table "
655 "number not valid"));
656 }
657 else
658 p->AmpGateFunc = AmpGateFunc;
659 }
660
661 /* load memfile */
662 p->swapped = load_atsfile(csound,
663 p, &(p->atsmemfile), atsfilname, p->ifileno, 0);
664 if (UNLIKELY(p->swapped < 0))
665 return NOTOK;
666 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
667
668 /* calculate how much memory we have to allocate for this */
669 memsize = (int32_t) (*p->iptls) * sizeof(ATS_DATA_LOC)
670 + (int32_t) (*p->iptls) * sizeof(double)
671 + (int32_t) (*p->iptls) * sizeof(MYFLT);
672 /* allocate space if we need it */
673 /* need room for a buffer and an array of oscillator phase increments */
674 if (p->auxch.auxp == NULL || p->auxch.size < (uint32_t)memsize)
675 csound->AuxAlloc(csound, (size_t) memsize, &p->auxch);
676
677 /* set up the buffer, phase, etc. */
678 p->buf = (ATS_DATA_LOC *) (p->auxch.auxp);
679 p->oscphase = (double *) (p->buf + (int32_t) (*p->iptls));
680 p->oldamps = (MYFLT *) (p->oscphase + (int32_t) (*p->iptls));
681 /* byte swap if necessary */
682 if (p->swapped == 1) {
683 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
684 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
685 n_partials = (int32_t) bswap(&atsh->npartials);
686 p->MaxAmp = bswap(&atsh->ampmax); /* store the maxium amplitude */
687 type = (int32_t) bswap(&atsh->type);
688 }
689 else {
690 p->maxFr = (int32_t) atsh->nfrms - 1;
691 p->timefrmInc = atsh->nfrms / atsh->dur;
692 n_partials = (int32_t) atsh->npartials;
693 p->MaxAmp = atsh->ampmax; /* store the maxium amplitude */
694 type = (int32_t) atsh->type;
695 }
696
697 /* make sure partials are in range */
698 if (UNLIKELY((int32_t) (*p->iptloffset+*p->iptls * *p->iptlincr) > n_partials ||
699 (int32_t) (*p->iptloffset) < 0)) {
700 return csound->InitError(csound, Str("ATSADD: Partial(s) out of range, "
701 "max partial allowed is %i"),
702 n_partials);
703 }
704 /* get a pointer to the beginning of the data */
705 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
706
707 /* get increments for the partials */
708 switch (type) {
709 case 1:
710 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
711 p->partialinc = 2 * (int32_t) (*p->iptlincr);
712 p->frmInc = n_partials * 2 + 1;
713 break;
714
715 case 2:
716 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
717 p->partialinc = 3 * (int32_t) (*p->iptlincr);
718 p->frmInc = n_partials * 3 + 1;
719 break;
720
721 case 3:
722 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
723 p->partialinc = 2 * (int32_t) (*p->iptlincr);
724 p->frmInc = n_partials * 2 + 26;
725 break;
726
727 case 4:
728 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
729 p->partialinc = 3 * (int32_t) (*p->iptlincr);
730 p->frmInc = n_partials * 3 + 26;
731 break;
732
733 default:
734 return csound->InitError(csound, Str("ATSADD: Type not implemented"));
735 }
736
737 /* flag set to reduce the amount of warnings sent out */
738 /* for time pointer out of range */
739 p->prFlg = 1; /* true */
740 return OK;
741 }
742
743
744
atsaddset_S(CSOUND * csound,ATSADD * p)745 static int32_t atsaddset_S(CSOUND *csound, ATSADD *p)
746 {
747 char atsfilname[MAXNAME];
748 ATSSTRUCT *atsh;
749 FUNC *ftp, *AmpGateFunc;
750 int32_t memsize, n_partials, type;
751
752 /* set up function table for synthesis */
753 if (UNLIKELY((ftp = csound->FTFind(csound, p->ifn)) == NULL)) {
754 return csound->InitError(csound, Str("ATSADD: Function table number "
755 "for synthesis waveform not valid"));
756 }
757 p->ftp = ftp;
758
759 /* set up gate function table */
760 if (*p->igatefun > FL(0.0)) {
761 if (UNLIKELY((AmpGateFunc = csound->FTFind(csound, p->igatefun)) == NULL)) {
762 return csound->InitError(csound, Str("ATSADD: Gate Function table "
763 "number not valid"));
764 }
765 else
766 p->AmpGateFunc = AmpGateFunc;
767 }
768
769 /* load memfile */
770 p->swapped = load_atsfile(csound,
771 p, &(p->atsmemfile), atsfilname, p->ifileno, 1);
772 if (UNLIKELY(p->swapped < 0))
773 return NOTOK;
774 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
775
776 /* calculate how much memory we have to allocate for this */
777 memsize = (int32_t) (*p->iptls) * sizeof(ATS_DATA_LOC)
778 + (int32_t) (*p->iptls) * sizeof(double)
779 + (int32_t) (*p->iptls) * sizeof(MYFLT);
780 /* allocate space if we need it */
781 /* need room for a buffer and an array of oscillator phase increments */
782 if (p->auxch.auxp == NULL || p->auxch.size < (uint32_t)memsize)
783 csound->AuxAlloc(csound, (size_t) memsize, &p->auxch);
784
785 /* set up the buffer, phase, etc. */
786 p->buf = (ATS_DATA_LOC *) (p->auxch.auxp);
787 p->oscphase = (double *) (p->buf + (int32_t) (*p->iptls));
788 p->oldamps = (MYFLT *) (p->oscphase + (int32_t) (*p->iptls));
789 /* byte swap if necessary */
790 if (p->swapped == 1) {
791 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
792 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
793 n_partials = (int32_t) bswap(&atsh->npartials);
794 p->MaxAmp = bswap(&atsh->ampmax); /* store the maxium amplitude */
795 type = (int32_t) bswap(&atsh->type);
796 }
797 else {
798 p->maxFr = (int32_t) atsh->nfrms - 1;
799 p->timefrmInc = atsh->nfrms / atsh->dur;
800 n_partials = (int32_t) atsh->npartials;
801 p->MaxAmp = atsh->ampmax; /* store the maxium amplitude */
802 type = (int32_t) atsh->type;
803 }
804
805 /* make sure partials are in range */
806 if (UNLIKELY((int32_t) (*p->iptloffset+*p->iptls * *p->iptlincr) > n_partials ||
807 (int32_t) (*p->iptloffset) < 0)) {
808 return csound->InitError(csound, Str("ATSADD: Partial(s) out of range, "
809 "max partial allowed is %i"),
810 n_partials);
811 }
812 /* get a pointer to the beginning of the data */
813 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
814
815 /* get increments for the partials */
816 switch (type) {
817 case 1:
818 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
819 p->partialinc = 2 * (int32_t) (*p->iptlincr);
820 p->frmInc = n_partials * 2 + 1;
821 break;
822
823 case 2:
824 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
825 p->partialinc = 3 * (int32_t) (*p->iptlincr);
826 p->frmInc = n_partials * 3 + 1;
827 break;
828
829 case 3:
830 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
831 p->partialinc = 2 * (int32_t) (*p->iptlincr);
832 p->frmInc = n_partials * 2 + 26;
833 break;
834
835 case 4:
836 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
837 p->partialinc = 3 * (int32_t) (*p->iptlincr);
838 p->frmInc = n_partials * 3 + 26;
839 break;
840
841 default:
842 return csound->InitError(csound, Str("ATSADD: Type not implemented"));
843 }
844
845 /* flag set to reduce the amount of warnings sent out */
846 /* for time pointer out of range */
847 p->prFlg = 1; /* true */
848 return OK;
849 }
850
atsadd(CSOUND * csound,ATSADD * p)851 static int32_t atsadd(CSOUND *csound, ATSADD *p)
852 {
853 MYFLT frIndx;
854 MYFLT *ar, amp, fract, v1, *ftab,a,inca, *oldamps = p->oldamps;
855 FUNC *ftp;
856 int32 lobits, phase, inc;
857 double *oscphase;
858 int32_t i;
859 uint32_t offset = p->h.insdshead->ksmps_offset;
860 uint32_t early = p->h.insdshead->ksmps_no_end;
861 uint32_t n, nsmps = CS_KSMPS;
862 int32_t numpartials = (int32_t) *p->iptls;
863 ATS_DATA_LOC *buf;
864
865 buf = p->buf;
866
867 /* ftp is a poiter to the ftable */
868 if (UNLIKELY(p->auxch.auxp == NULL || (ftp = p->ftp) == NULL)) goto err1;
869
870 /* make sure time pointer is within range */
871 if ((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0)) {
872 frIndx = FL(0.0);
873 if (UNLIKELY(p->prFlg)) {
874 p->prFlg = 0;
875 csound->Warning(csound, Str("ATSADD: only positive time pointer "
876 "values are allowed, setting to zero\n"));
877 }
878 }
879 else if (OUT_OF_FRAMES) {
880 /* if we are trying to get frames past where we have data */
881 frIndx = (MYFLT) p->maxFr;
882 if (UNLIKELY(p->prFlg)) {
883 p->prFlg = 0; /* set to false */
884 csound->Warning(csound, Str("ATSADD: time pointer out of range, "
885 "truncating to last frame\n"));
886 }
887 }
888 else
889 p->prFlg = 1;
890
891 FetchADDPartials(p, buf, frIndx);
892
893 oscphase = p->oscphase;
894 /* initialise output to zero */
895 ar = p->aoutput;
896 memset(ar, 0, nsmps*sizeof(MYFLT));
897 if (UNLIKELY(early)) nsmps -= early;
898 if (*p->igatefun > FL(0.0))
899 AtsAmpGate(buf, *p->iptls, p->AmpGateFunc, p->MaxAmp);
900
901 for (i = 0; i < numpartials; i++) {
902 lobits = ftp->lobits;
903 amp = csound->e0dbfs * (MYFLT) p->buf[i].amp;
904 phase = MYFLT2LONG(*oscphase);
905 ar = p->aoutput; /* ar is a pointer to the audio output */
906 inca = (amp-oldamps[i])/nsmps;
907 a = oldamps[i];
908 /* put in * kfmod */
909 inc = MYFLT2LONG(p->buf[i].freq * csound->sicvt * *p->kfmod);
910 for (n=offset; n<nsmps; n++) {
911 ftab = ftp->ftable + (phase >> lobits);
912 v1 = *ftab++;
913 fract = (MYFLT) PFRAC(phase);
914 ar[n] += (v1 + fract * (*ftab - v1)) * a;
915 phase += inc;
916 phase &= PHMASK;
917 a+=inca;
918 }
919 *oscphase = (double) phase;
920 oldamps[i] = amp;
921 oscphase++;
922 }
923 return OK;
924 err1:
925 return csound->PerfError(csound, &(p->h),
926 Str("ATSADD: not initialised"));
927 }
928
FetchADDPartials(ATSADD * p,ATS_DATA_LOC * buf,MYFLT position)929 static void FetchADDPartials(ATSADD *p, ATS_DATA_LOC *buf, MYFLT position)
930 {
931 MYFLT frac; /* the distance in time we are between frames */
932 double *frm_0, *frm_1;
933 double temp0amp, temp1amp;
934 double temp0freq, temp1freq;
935 int32_t frame;
936 int32_t i; /* for the for loop */
937 int32_t partialloc = p->firstpartial;
938 int32_t npartials = (int32_t) *p->iptls;
939
940 frame = (int32_t) position;
941 frm_0 = p->datastart + frame * p->frmInc;
942
943 /* if we are using the data from the last frame */
944 /* we should not try to interpolate */
945 if (UNLIKELY(frame == p->maxFr)) {
946 for (i = 0; i < npartials; i++) {
947 if (p->swapped == 1) {
948 buf[i].amp = bswap(&frm_0[partialloc]); /* calc amplitude */
949 buf[i].freq = bswap(&frm_0[partialloc + 1]); /* freq */
950 }
951 else {
952 buf[i].amp = frm_0[partialloc]; /* calc amplitude */
953 buf[i].freq = frm_0[partialloc + 1]; /* freq */
954 }
955 partialloc += p->partialinc;
956 }
957 return;
958 }
959
960 frac = position - frame;
961 frm_1 = frm_0 + p->frmInc;
962
963 for (i = 0; i < npartials; i++) {
964 if (p->swapped == 1) {
965 temp0amp = bswap(&frm_0[partialloc]);
966 temp1amp = bswap(&frm_1[partialloc]);
967 temp0freq = bswap(&frm_0[partialloc + 1]);
968 temp1freq = bswap(&frm_1[partialloc + 1]);
969 }
970 else {
971 temp0amp = frm_0[partialloc];
972 temp1amp = frm_1[partialloc];
973 temp0freq = frm_0[partialloc + 1];
974 temp1freq = frm_1[partialloc + 1];
975 }
976 buf[i].amp = temp0amp + frac * (temp1amp - temp0amp); /* calc amplitude */
977 buf[i].freq = temp0freq + frac * (temp1freq - temp0freq); /* calc freq */
978 partialloc += p->partialinc; /* get to the next partial */
979 }
980 }
981
AtsAmpGate(ATS_DATA_LOC * buf,int32_t npartials,FUNC * ampfunc,double MaxAmpInData)982 static void AtsAmpGate( /* adaption of PvAmpGate by Richard Karpen */
983 ATS_DATA_LOC *buf, /* where to get our mag/freq pairs */
984 int32_t npartials, /* number of partials we are working with */
985 FUNC *ampfunc, double MaxAmpInData)
986 {
987 int32_t j;
988 int32_t funclen, mapPoint;
989
990 funclen = ampfunc->flen;
991
992 for (j = 0; j < npartials; ++j) {
993 /* use normalised amp as index into table for amp scaling */
994 mapPoint = (int32) ((buf[j].amp / MaxAmpInData) * funclen);
995 buf[j].amp *= (double) *(ampfunc->ftable + mapPoint);
996 }
997 }
998
999 /************************************************************/
1000 /********* ATSADDNZ ***********************************/
1001 /************************************************************/
1002
1003 /* copied directly from atsh synth-funcs.c
1004 * with names changed so as not to conflict with csound
1005 * --------------------------------------------------------
1006 * randi output random numbers in the range of 1,-1
1007 * getting a new number at frequency freq and interpolating
1008 * the intermediate values.
1009 */
1010
randiats_setup(CSOUND * csound,MYFLT freq,RANDIATS * radat)1011 static void randiats_setup(CSOUND *csound, MYFLT freq, RANDIATS *radat)
1012 {
1013 radat->size = (int32_t) MYFLT2LRND(CS_ESR / freq);
1014 radat->cnt = 0;
1015 radat->a1 = (int32) csound->Rand31(&(csound->randSeed1));
1016 radat->a2 = (int32) csound->Rand31(&(csound->randSeed1));
1017 }
1018
1019 /* ------------------------------------------------------------------ */
1020
randiats(CSOUND * csound,RANDIATS * radat)1021 static MYFLT randiats(CSOUND *csound, RANDIATS *radat)
1022 {
1023 MYFLT output;
1024
1025 if (radat->cnt == radat->size) { /* get a new random value */
1026 radat->a1 = radat->a2;
1027 radat->a2 = (int32) csound->Rand31(&(csound->randSeed1));
1028 radat->cnt = 0;
1029 }
1030
1031 output = (((MYFLT) (radat->a2 - radat->a1) / (MYFLT) radat->size)
1032 * (MYFLT) radat->cnt) + (MYFLT) radat->a1;
1033 radat->cnt++;
1034 return (FL(1.0) - ((MYFLT) output * (FL(2.0) / (MYFLT) 0x7FFFFFFF)));
1035 }
1036
1037 /* ------------------------------------------------------------------ */
1038
FetchADDNZbands(int32_t ptls,int32_t firstband,double * datastart,int32_t frmInc,int32_t maxFr,int swapped,double * buf,MYFLT position)1039 static void FetchADDNZbands(int32_t ptls, int32_t firstband, double *datastart,
1040 int32_t frmInc, int32_t maxFr, int swapped,
1041 double *buf, MYFLT position)
1042 {
1043 double frac; /* the distance in time we are between frames */
1044 double *frm_0, *frm_1;
1045 double frm0val, frm1val;
1046 int32_t frame;
1047 int32_t i; /* for the for loop */
1048 /*int32_t firstband = p->firstband;*/
1049
1050 #ifdef BETA
1051 printf("FetchADDNZbands: position %f\n", (double)position);
1052 #endif
1053 frame = (int32_t) position;
1054 frm_0 = datastart + frame * frmInc;
1055
1056 /* if we are using the data from the last frame */
1057 /* we should not try to interpolate */
1058 if (UNLIKELY(frame == maxFr)) {
1059 for (i = 0; i < ptls; i++) {
1060 buf[i] = (swapped == 1 ? bswap(&frm_0[firstband + i])
1061 : frm_0[firstband + i]); /* output value */
1062 }
1063 return;
1064 }
1065
1066 frm_1 = frm_0 + frmInc;
1067 frac = (double) (position - frame);
1068
1069 for (i = 0; i < ptls; i++) {
1070 if (swapped == 1) {
1071 frm0val = bswap(&(frm_0[firstband + i]));
1072 frm1val = bswap(&(frm_1[firstband + i]));
1073 }
1074 else {
1075 frm0val = frm_0[firstband + i];
1076 frm1val = frm_1[firstband + i];
1077 }
1078
1079 buf[i] = frm0val + frac * (frm1val - frm0val); /* calc energy */
1080
1081 }
1082
1083 }
1084
1085 static const double freqs[25]= {
1086 100.0, 100.0, 100.0, 100.0, 110.0, 120.0, 140.0, 150.0, 160.0, 190.0,
1087 210.0, 240.0, 280.0, 320.0, 380.0, 450.0, 550.0, 700.0, 900.0, 1100.0,
1088 1300.0, 1800.0, 2500.0, 3500.0, 4500.0};
1089
atsaddnzset(CSOUND * csound,ATSADDNZ * p)1090 static int32_t atsaddnzset(CSOUND *csound, ATSADDNZ *p)
1091 {
1092 char atsfilname[MAXNAME];
1093 ATSSTRUCT *atsh;
1094 int32_t i, type, n_partials;
1095
1096 /* load memfile */
1097 p->swapped = load_atsfile(csound,
1098 p, &(p->atsmemfile), atsfilname, p->ifileno, 0);
1099 if (UNLIKELY(p->swapped < 0))
1100 return NOTOK;
1101 p->bands = (int32_t)(*p->ibands);
1102 p->bandoffset = (int32_t) (*p->ibandoffset);
1103 p->bandincr = (int32_t) (*p->ibandincr);
1104 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
1105
1106 /* make sure that this file contains noise */
1107 type = (p->swapped == 1) ? (int32_t) bswap(&atsh->type) : (int32_t) atsh->type;
1108
1109 if (UNLIKELY(type != 4 && type != 3)) {
1110 if (type < 5)
1111 return csound->InitError(csound,
1112 Str("ATSADDNZ: "
1113 "This file type contains no noise"));
1114 else
1115 return csound->InitError(csound,
1116 Str("ATSADDNZ: This file type has not been "
1117 "implemented in this code yet."));
1118 }
1119
1120 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
1121 /* byte swap if necessary */
1122 if (p->swapped == 1) {
1123 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
1124 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
1125 n_partials = (int32_t) bswap(&atsh->npartials);
1126 p->winsize = (MYFLT) bswap(&atsh->winsz);
1127 }
1128 else {
1129 p->maxFr = (int32_t) atsh->nfrms - 1;
1130 p->timefrmInc = atsh->nfrms / atsh->dur;
1131 n_partials = (int32_t) atsh->npartials;
1132 p->winsize = (MYFLT) atsh->winsz;
1133 }
1134
1135 /* make sure partials are in range */
1136 if (UNLIKELY((p->bandoffset + p->bands * p->bandincr) > 25 ||
1137 p->bands <0 || /* Allow zero bands for no good reason */
1138 p->bandoffset < 0)) {
1139 return csound->InitError(csound, Str("ATSADDNZ: Band(s) out of range, "
1140 "max band allowed is 25"));
1141 }
1142
1143 /* point the data pointer to the correct partials */
1144 switch (type) {
1145 case 3:
1146 p->firstband = 1 + 2 * n_partials;
1147 p->frmInc = n_partials * 2 + 26;
1148 break;
1149
1150 case 4:
1151 p->firstband = 1 + 3 * n_partials;
1152 p->frmInc = n_partials * 3 + 26;
1153 break;
1154
1155 /* default: // Cannot happen */
1156 /* return csound->InitError(csound, */
1157 /* Str("ATSADDNZ: Type either has no noise " */
1158 /* "or is not implemented " */
1159 /* "(only type 3 and 4 work now)")); */
1160 }
1161
1162 /* save bandwidths for creating noise bands */
1163 memcpy(p->nfreq, freqs, 25*sizeof(double));
1164 /* p->nfreq[0] = 100.0; */
1165 /* p->nfreq[1] = 100.0; */
1166 /* p->nfreq[2] = 100.0; */
1167 /* p->nfreq[3] = 100.0; */
1168 /* p->nfreq[4] = 110.0; */
1169 /* p->nfreq[5] = 120.0; */
1170 /* p->nfreq[6] = 140.0; */
1171 /* p->nfreq[7] = 150.0; */
1172 /* p->nfreq[8] = 160.0; */
1173 /* p->nfreq[9] = 190.0; */
1174 /* p->nfreq[10] = 210.0; */
1175 /* p->nfreq[11] = 240.0; */
1176 /* p->nfreq[12] = 280.0; */
1177 /* p->nfreq[13] = 320.0; */
1178 /* p->nfreq[14] = 380.0; */
1179 /* p->nfreq[15] = 450.0; */
1180 /* p->nfreq[16] = 550.0; */
1181 /* p->nfreq[17] = 700.0; */
1182 /* p->nfreq[18] = 900.0; */
1183 /* p->nfreq[19] = 1100.0; */
1184 /* p->nfreq[20] = 1300.0; */
1185 /* p->nfreq[21] = 1800.0; */
1186 /* p->nfreq[22] = 2500.0; */
1187 /* p->nfreq[23] = 3500.0; */
1188 /* p->nfreq[24] = 4500.0; */
1189
1190 {
1191 double tmp = TWOPI * csound->onedsr;
1192
1193 /* initialise frequencies to modulate noise by */
1194 p->phaseinc[0] = 50.0 * tmp;
1195 p->phaseinc[1] = 150.0 * tmp;
1196 p->phaseinc[2] = 250.0 * tmp;
1197 p->phaseinc[3] = 350.0 * tmp;
1198 p->phaseinc[4] = 455.0 * tmp;
1199 p->phaseinc[5] = 570.0 * tmp;
1200 p->phaseinc[6] = 700.0 * tmp;
1201 p->phaseinc[7] = 845.0 * tmp;
1202 p->phaseinc[8] = 1000.0 * tmp;
1203 p->phaseinc[9] = 1175.0 * tmp;
1204 p->phaseinc[10] = 1375.0 * tmp;
1205 p->phaseinc[11] = 1600.0 * tmp;
1206 p->phaseinc[12] = 1860.0 * tmp;
1207 p->phaseinc[13] = 2160.0 * tmp;
1208 p->phaseinc[14] = 2510.0 * tmp;
1209 p->phaseinc[15] = 2925.0 * tmp;
1210 p->phaseinc[16] = 3425.0 * tmp;
1211 p->phaseinc[17] = 4050.0 * tmp;
1212 p->phaseinc[18] = 4850.0 * tmp;
1213 p->phaseinc[19] = 5850.0 * tmp;
1214 p->phaseinc[20] = 7050.0 * tmp;
1215 p->phaseinc[21] = 8600.0 * tmp;
1216 p->phaseinc[22] = 10750.0 * tmp;
1217 p->phaseinc[23] = 13750.0 * tmp;
1218 p->phaseinc[24] = 17750.0 * tmp;
1219 }
1220 /* initialise phase */
1221 memset(p->oscphase, '\0', 25*sizeof(double));
1222 /* p->oscphase[0] = 0.0; */
1223 /* p->oscphase[1] = 0.0; */
1224 /* p->oscphase[2] = 0.0; */
1225 /* p->oscphase[3] = 0.0; */
1226 /* p->oscphase[4] = 0.0; */
1227 /* p->oscphase[5] = 0.0; */
1228 /* p->oscphase[6] = 0.0; */
1229 /* p->oscphase[7] = 0.0; */
1230 /* p->oscphase[8] = 0.0; */
1231 /* p->oscphase[9] = 0.0; */
1232 /* p->oscphase[10] = 0.0; */
1233 /* p->oscphase[11] = 0.0; */
1234 /* p->oscphase[12] = 0.0; */
1235 /* p->oscphase[13] = 0.0; */
1236 /* p->oscphase[14] = 0.0; */
1237 /* p->oscphase[15] = 0.0; */
1238 /* p->oscphase[16] = 0.0; */
1239 /* p->oscphase[17] = 0.0; */
1240 /* p->oscphase[18] = 0.0; */
1241 /* p->oscphase[19] = 0.0; */
1242 /* p->oscphase[20] = 0.0; */
1243 /* p->oscphase[21] = 0.0; */
1244 /* p->oscphase[22] = 0.0; */
1245 /* p->oscphase[23] = 0.0; */
1246 /* p->oscphase[24] = 0.0; */
1247
1248 /* initialise band limited noise parameters */
1249 for (i = 0; i < 25; i++) {
1250 randiats_setup(csound, p->nfreq[i], &(p->randinoise[i]));
1251 }
1252
1253 /* flag set to reduce the amount of warnings sent out */
1254 /* for time pointer out of range */
1255 p->prFlg = 1; /* true */
1256
1257 return OK;
1258 }
1259
atsaddnzset_S(CSOUND * csound,ATSADDNZ * p)1260 static int32_t atsaddnzset_S(CSOUND *csound, ATSADDNZ *p)
1261 {
1262 char atsfilname[MAXNAME];
1263 ATSSTRUCT *atsh;
1264 int32_t i, type, n_partials;
1265
1266 /* load memfile */
1267 p->swapped = load_atsfile(csound,
1268 p, &(p->atsmemfile), atsfilname, p->ifileno, 1);
1269 if (UNLIKELY(p->swapped < 0))
1270 return NOTOK;
1271 p->bands = (int32_t)(*p->ibands);
1272 p->bandoffset = (int32_t) (*p->ibandoffset);
1273 p->bandincr = (int32_t) (*p->ibandincr);
1274 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
1275
1276 /* make sure that this file contains noise */
1277 type = (p->swapped == 1) ? (int32_t) bswap(&atsh->type) : (int32_t) atsh->type;
1278
1279 if (UNLIKELY(type != 4 && type != 3)) {
1280 if (type < 5)
1281 return csound->InitError(csound,
1282 Str("ATSADDNZ: "
1283 "This file type contains no noise"));
1284 else
1285 return csound->InitError(csound,
1286 Str("ATSADDNZ: This file type has not been "
1287 "implemented in this code yet."));
1288 }
1289
1290 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
1291 /* byte swap if necessary */
1292 if (p->swapped == 1) {
1293 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
1294 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
1295 n_partials = (int32_t) bswap(&atsh->npartials);
1296 p->winsize = (MYFLT) bswap(&atsh->winsz);
1297 }
1298 else {
1299 p->maxFr = (int32_t) atsh->nfrms - 1;
1300 p->timefrmInc = atsh->nfrms / atsh->dur;
1301 n_partials = (int32_t) atsh->npartials;
1302 p->winsize = (MYFLT) atsh->winsz;
1303 }
1304
1305 /* make sure partials are in range */
1306 if (UNLIKELY((p->bandoffset + p->bands * p->bandincr) > 25 ||
1307 p->bands <0 || /* Allow zero bands for no good reason */
1308 p->bandoffset < 0)) {
1309 return csound->InitError(csound, Str("ATSADDNZ: Band(s) out of range, "
1310 "max band allowed is 25"));
1311 }
1312
1313 /* point the data pointer to the correct partials */
1314 switch (type) {
1315 case 3:
1316 p->firstband = 1 + 2 * n_partials;
1317 p->frmInc = n_partials * 2 + 26;
1318 break;
1319
1320 case 4:
1321 p->firstband = 1 + 3 * n_partials;
1322 p->frmInc = n_partials * 3 + 26;
1323 break;
1324
1325 /* default: */ // Cannot happen as tested earlier
1326 /* return csound->InitError(csound, */
1327 /* Str("ATSADDNZ: Type either has no noise " */
1328 /* "or is not implemented " */
1329 /* "(only type 3 and 4 work now)")); */
1330 }
1331
1332 /* save bandwidths for creating noise bands */
1333 memcpy(p->nfreq, freqs, 25*sizeof(double));
1334 /* p->nfreq[0] = 100.0; */
1335 /* p->nfreq[1] = 100.0; */
1336 /* p->nfreq[2] = 100.0; */
1337 /* p->nfreq[3] = 100.0; */
1338 /* p->nfreq[4] = 110.0; */
1339 /* p->nfreq[5] = 120.0; */
1340 /* p->nfreq[6] = 140.0; */
1341 /* p->nfreq[7] = 150.0; */
1342 /* p->nfreq[8] = 160.0; */
1343 /* p->nfreq[9] = 190.0; */
1344 /* p->nfreq[10] = 210.0; */
1345 /* p->nfreq[11] = 240.0; */
1346 /* p->nfreq[12] = 280.0; */
1347 /* p->nfreq[13] = 320.0; */
1348 /* p->nfreq[14] = 380.0; */
1349 /* p->nfreq[15] = 450.0; */
1350 /* p->nfreq[16] = 550.0; */
1351 /* p->nfreq[17] = 700.0; */
1352 /* p->nfreq[18] = 900.0; */
1353 /* p->nfreq[19] = 1100.0; */
1354 /* p->nfreq[20] = 1300.0; */
1355 /* p->nfreq[21] = 1800.0; */
1356 /* p->nfreq[22] = 2500.0; */
1357 /* p->nfreq[23] = 3500.0; */
1358 /* p->nfreq[24] = 4500.0; */
1359
1360 {
1361 double tmp = TWOPI * csound->onedsr;
1362
1363 /* initialise frequencies to modulate noise by */
1364 p->phaseinc[0] = 50.0 * tmp;
1365 p->phaseinc[1] = 150.0 * tmp;
1366 p->phaseinc[2] = 250.0 * tmp;
1367 p->phaseinc[3] = 350.0 * tmp;
1368 p->phaseinc[4] = 455.0 * tmp;
1369 p->phaseinc[5] = 570.0 * tmp;
1370 p->phaseinc[6] = 700.0 * tmp;
1371 p->phaseinc[7] = 845.0 * tmp;
1372 p->phaseinc[8] = 1000.0 * tmp;
1373 p->phaseinc[9] = 1175.0 * tmp;
1374 p->phaseinc[10] = 1375.0 * tmp;
1375 p->phaseinc[11] = 1600.0 * tmp;
1376 p->phaseinc[12] = 1860.0 * tmp;
1377 p->phaseinc[13] = 2160.0 * tmp;
1378 p->phaseinc[14] = 2510.0 * tmp;
1379 p->phaseinc[15] = 2925.0 * tmp;
1380 p->phaseinc[16] = 3425.0 * tmp;
1381 p->phaseinc[17] = 4050.0 * tmp;
1382 p->phaseinc[18] = 4850.0 * tmp;
1383 p->phaseinc[19] = 5850.0 * tmp;
1384 p->phaseinc[20] = 7050.0 * tmp;
1385 p->phaseinc[21] = 8600.0 * tmp;
1386 p->phaseinc[22] = 10750.0 * tmp;
1387 p->phaseinc[23] = 13750.0 * tmp;
1388 p->phaseinc[24] = 17750.0 * tmp;
1389 }
1390 /* initialise phase */
1391 memset(p->oscphase, '\0', 25*sizeof(double));
1392 /* p->oscphase[0] = 0.0; */
1393 /* p->oscphase[1] = 0.0; */
1394 /* p->oscphase[2] = 0.0; */
1395 /* p->oscphase[3] = 0.0; */
1396 /* p->oscphase[4] = 0.0; */
1397 /* p->oscphase[5] = 0.0; */
1398 /* p->oscphase[6] = 0.0; */
1399 /* p->oscphase[7] = 0.0; */
1400 /* p->oscphase[8] = 0.0; */
1401 /* p->oscphase[9] = 0.0; */
1402 /* p->oscphase[10] = 0.0; */
1403 /* p->oscphase[11] = 0.0; */
1404 /* p->oscphase[12] = 0.0; */
1405 /* p->oscphase[13] = 0.0; */
1406 /* p->oscphase[14] = 0.0; */
1407 /* p->oscphase[15] = 0.0; */
1408 /* p->oscphase[16] = 0.0; */
1409 /* p->oscphase[17] = 0.0; */
1410 /* p->oscphase[18] = 0.0; */
1411 /* p->oscphase[19] = 0.0; */
1412 /* p->oscphase[20] = 0.0; */
1413 /* p->oscphase[21] = 0.0; */
1414 /* p->oscphase[22] = 0.0; */
1415 /* p->oscphase[23] = 0.0; */
1416 /* p->oscphase[24] = 0.0; */
1417
1418 /* initialise band limited noise parameters */
1419 for (i = 0; i < 25; i++) {
1420 randiats_setup(csound, p->nfreq[i], &(p->randinoise[i]));
1421 }
1422
1423 /* flag set to reduce the amount of warnings sent out */
1424 /* for time pointer out of range */
1425 p->prFlg = 1; /* true */
1426
1427 return OK;
1428 }
1429
atsaddnz(CSOUND * csound,ATSADDNZ * p)1430 static int32_t atsaddnz(CSOUND *csound, ATSADDNZ *p)
1431 {
1432 MYFLT frIndx;
1433 MYFLT *ar, amp;
1434 int32_t i;
1435 uint32_t offset = p->h.insdshead->ksmps_offset;
1436 uint32_t early = p->h.insdshead->ksmps_no_end;
1437 uint32_t n, nsmps = CS_KSMPS;
1438 int32_t synthme;
1439 int32_t nsynthed;
1440
1441 /* make sure time pointer is within range */
1442 if ((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0)) {
1443 frIndx = FL(0.0);
1444 if (UNLIKELY(p->prFlg)) {
1445 p->prFlg = 0;
1446 csound->Warning(csound, Str("ATSADDNZ: only positive time pointer "
1447 "values are allowed, setting to zero\n"));
1448 }
1449 }
1450 else if (OUT_OF_FRAMES) {
1451 /* if we are trying to get frames past where we have data */
1452 frIndx = (MYFLT) p->maxFr;
1453 if (UNLIKELY(p->prFlg)) {
1454 p->prFlg = 0; /* set to false */
1455 csound->Warning(csound, Str("ATSADDNZ: time pointer out of range, "
1456 "truncating to last frame\n"));
1457 }
1458 }
1459 else
1460 p->prFlg = 1;
1461
1462 FetchADDNZbands(25, p->firstband, p->datastart, p->frmInc, p->maxFr,
1463 p->swapped, p->buf, frIndx);
1464
1465 /* set local pointer to output and initialise output to zero */
1466 ar = p->aoutput;
1467
1468 memset(ar, 0, CS_KSMPS*sizeof(MYFLT));
1469 if (UNLIKELY(early)) nsmps -= early;
1470
1471 synthme = p->bandoffset;
1472 nsynthed = 0;
1473 ar = p->aoutput;
1474 for (i = 0; i < 25; i++) {
1475 /* do we even have to synthesize it? */
1476 if (i == synthme && nsynthed < p->bands) { /* synthesize cosine */
1477 amp = csound->e0dbfs*
1478 SQRT((p->buf[i] / (p->winsize*(MYFLT)ATSA_NOISE_VARIANCE)));
1479 for (n=offset; n<nsmps; n++) {
1480 ar[n] += (COS(p->oscphase[i])
1481 * amp * randiats(csound, &(p->randinoise[i])));
1482 p->oscphase[i] += p->phaseinc[i];
1483 }
1484 /* make sure that the phase does not overflow */
1485 /*
1486 while (phase >= costabsz)
1487 phase = phase - costabsz;
1488 */
1489 nsynthed++;
1490 synthme += p->bandincr;
1491 }
1492 }
1493 return OK;
1494 }
1495
band_energy_to_res(CSOUND * csound,ATSSINNOI * p)1496 static void band_energy_to_res(CSOUND *csound, ATSSINNOI *p)
1497 {
1498 int32_t i, j, k;
1499 MYFLT edges[] = ATSA_CRITICAL_BAND_EDGES;
1500 double *curframe = p->datastart;
1501 double bandsum[25];
1502 double partialfreq;
1503 double partialamp;
1504 double **partialband;
1505 int32_t *bandnum;
1506
1507 partialband = (double **) csound->Malloc(csound, sizeof(double*)
1508 * (int32_t) p->atshead->npartials);
1509 bandnum =
1510 (int32_t *) csound->Malloc(csound,
1511 sizeof(int32_t) * (int32_t) p->atshead->npartials);
1512
1513 for (i = 0; i < (int32_t) p->atshead->nfrms; i++) {
1514 /* init sums */
1515 memset(bandsum, 0, 25*sizeof(double));
1516 /* find sums per band */
1517 for (j = 0; j < (int32_t) p->atshead->npartials; j++) {
1518 partialfreq = *(curframe + 2 + j * (int32_t) p->partialinc);
1519 partialamp = *(curframe + 1 + j * (int32_t) p->partialinc);
1520 for (k = 0; k < 25; k++) {
1521 if ((partialfreq < edges[k + 1]) && (partialfreq >= edges[k])) {
1522 bandsum[k] += partialamp;
1523 bandnum[j] = k;
1524 partialband[j] = (curframe + (int32_t) p->firstband + k);
1525 break;
1526 }
1527 }
1528 }
1529
1530 /* compute energy per partial */
1531 for (j = 0; j < (int32_t) p->atshead->npartials; j++) {
1532 if (bandsum[bandnum[j]] > 0.0)
1533 *(p->nzdata + i * (int32_t) p->atshead->npartials + j) =
1534 (*(curframe + 1 + j * (int32_t) p->partialinc) * *(partialband[j])) /
1535 bandsum[bandnum[j]];
1536 else
1537 *(p->nzdata + i * (int32_t) p->atshead->npartials + j) = 0.0;
1538 }
1539 curframe += p->frmInc;
1540 }
1541
1542 csound->Free(csound,partialband);
1543 csound->Free(csound,bandnum);
1544 }
1545
1546 static void fetchSINNOIpartials(ATSSINNOI *, MYFLT);
1547
atssinnoiset(CSOUND * csound,ATSSINNOI * p)1548 static int32_t atssinnoiset(CSOUND *csound, ATSSINNOI *p)
1549 {
1550 char atsfilname[MAXNAME];
1551 ATSSTRUCT *atsh;
1552 int32_t i, memsize, nzmemsize, type;
1553
1554 /* load memfile */
1555 p->swapped = load_atsfile(csound,
1556 p, &(p->atsmemfile), atsfilname, p->ifileno, 0);
1557 if (UNLIKELY(p->swapped < 0)){
1558 return NOTOK;
1559 }
1560 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
1561 p->atshead = atsh;
1562
1563 /* calculate how much memory we have to allocate for this */
1564 /* need room for a buffer and the noise data and the noise info */
1565 /* per partial for synthesizing noise */
1566 memsize = (int32_t) (*p->iptls) * (sizeof(ATS_DATA_LOC) + 2 * sizeof(double)
1567 + sizeof(RANDIATS));
1568 /* allocate space if we need it */
1569 /* need room for a buffer and an array of oscillator phase increments */
1570 if (p->auxch.auxp != NULL || memsize > (int32_t)p->auxch.size)
1571 csound->AuxAlloc(csound, (size_t) memsize, &p->auxch);
1572
1573 /* set up the buffer, phase, etc. */
1574 p->oscbuf = (ATS_DATA_LOC *) (p->auxch.auxp);
1575 p->randinoise = (RANDIATS *) (p->oscbuf + (int32_t) (*p->iptls));
1576 p->oscphase = (double *) (p->randinoise + (int32_t) (*p->iptls));
1577 p->nzbuf = (double *) (p->oscphase + (int32_t) (*p->iptls));
1578
1579 if (p->swapped == 1) {
1580 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
1581 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
1582 p->npartials = (int32_t) bswap(&atsh->npartials);
1583 nzmemsize = (int32_t) (p->npartials * bswap(&atsh->nfrms));
1584 type = (int32_t) bswap(&atsh->type);
1585 }
1586 else {
1587 p->maxFr = (int32_t) atsh->nfrms - 1;
1588 p->timefrmInc = atsh->nfrms / atsh->dur;
1589 p->npartials = (int32_t) atsh->npartials;
1590 nzmemsize = (int32_t) (p->npartials * atsh->nfrms);
1591 type = (int32_t) atsh->type;
1592 }
1593
1594 /* see if we have to allocate memory for the nzdata */
1595 if (nzmemsize != p->nzmemsize) {
1596 if (p->nzdata != NULL)
1597 csound->Free(csound, p->nzdata);
1598 p->nzdata = (double *) csound->Malloc(csound, sizeof(double) * nzmemsize);
1599 }
1600
1601
1602 /* make sure partials are in range */
1603 if (UNLIKELY((int32_t)(*p->iptloffset+*p->iptls* *p->iptlincr) > p->npartials ||
1604 (int32_t) (*p->iptloffset) < 0)) {
1605 return csound->InitError(csound,
1606 Str("ATSSINNOI: Partial(s) out of range, "
1607 "max partial allowed is %i"), p->npartials);
1608 }
1609 /* get a pointer to the beginning of the data */
1610 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
1611 /* get increments for the partials */
1612
1613 switch (type) {
1614 case 1:
1615 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
1616 p->partialinc = 2 * (int32_t) (*p->iptlincr);
1617 p->frmInc = p->npartials * 2 + 1;
1618 p->firstband = -1;
1619 break;
1620
1621 case 2:
1622 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
1623 p->partialinc = 3 * (int32_t) (*p->iptlincr);
1624 p->frmInc = p->npartials * 3 + 1;
1625 p->firstband = -1;
1626 break;
1627
1628 case 3:
1629 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
1630 p->partialinc = 2 * (int32_t) (*p->iptlincr);
1631 p->frmInc = p->npartials * 2 + 26;
1632 p->firstband = 1 + 2 * p->npartials;
1633 break;
1634
1635 case 4:
1636 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
1637 p->partialinc = 3 * (int32_t) (*p->iptlincr);
1638 p->frmInc = p->npartials * 3 + 26;
1639 p->firstband = 1 + 3 * p->npartials;
1640 break;
1641
1642 default:
1643 return csound->InitError(csound, Str("ATSSINNOI: Type not implemented"));
1644 }
1645 /* convert noise per band to noise per partial */
1646 /* make sure we do not do this if we have done it already. */
1647 if ((p->firstband != -1) &&
1648 ((p->filename == NULL) || (strcmp(atsfilname, p->filename) != 0) ||
1649 (p->nzmemsize != nzmemsize))) {
1650 if (p->filename != NULL)
1651 csound->Free(csound, p->filename);
1652 p->filename = (char *) csound->Malloc(csound,
1653 sizeof(char) * strlen(atsfilname));
1654 strcpy(p->filename, atsfilname);
1655 /* csound->Message(csound, "\n band to energy res calculation %s \n",
1656 p->filename); */
1657 /* calculate the band energys */
1658 band_energy_to_res(csound, p);
1659 }
1660 /* save the memory size of the noise */
1661 p->nzmemsize = nzmemsize;
1662
1663
1664 /* flag set to reduce the amount of warnings sent out */
1665 /* for time pointer out of range */
1666 p->prFlg = 1; /* true */
1667
1668 {
1669 double tmp = TWOPI * csound->onedsr;
1670 p->phaseinc[0] = 50.0 * tmp;
1671 p->phaseinc[1] = 150.0 * tmp;
1672 p->phaseinc[2] = 250.0 * tmp;
1673 p->phaseinc[3] = 350.0 * tmp;
1674 p->phaseinc[4] = 455.0 * tmp;
1675 p->phaseinc[5] = 570.0 * tmp;
1676 p->phaseinc[6] = 700.0 * tmp;
1677 p->phaseinc[7] = 845.0 * tmp;
1678 p->phaseinc[8] = 1000.0 * tmp;
1679 p->phaseinc[9] = 1175.0 * tmp;
1680 p->phaseinc[10] = 1375.0 * tmp;
1681 p->phaseinc[11] = 1600.0 * tmp;
1682 p->phaseinc[12] = 1860.0 * tmp;
1683 p->phaseinc[13] = 2160.0 * tmp;
1684 p->phaseinc[14] = 2510.0 * tmp;
1685 p->phaseinc[15] = 2925.0 * tmp;
1686 p->phaseinc[16] = 3425.0 * tmp;
1687 p->phaseinc[17] = 4050.0 * tmp;
1688 p->phaseinc[18] = 4850.0 * tmp;
1689 p->phaseinc[19] = 5850.0 * tmp;
1690 p->phaseinc[20] = 7050.0 * tmp;
1691 p->phaseinc[21] = 8600.0 * tmp;
1692 p->phaseinc[22] = 10750.0 * tmp;
1693 p->phaseinc[23] = 13750.0 * tmp;
1694 p->phaseinc[24] = 17750.0 * tmp;
1695 }
1696
1697 /* initialise phase */
1698 memset(p->noiphase, 0, 25*sizeof(double));
1699 /* p->noiphase[0] = 0.0; */
1700 /* p->noiphase[1] = 0.0; */
1701 /* p->noiphase[2] = 0.0; */
1702 /* p->noiphase[3] = 0.0; */
1703 /* p->noiphase[4] = 0.0; */
1704 /* p->noiphase[5] = 0.0; */
1705 /* p->noiphase[6] = 0.0; */
1706 /* p->noiphase[7] = 0.0; */
1707 /* p->noiphase[8] = 0.0; */
1708 /* p->noiphase[9] = 0.0; */
1709 /* p->noiphase[10] = 0.0; */
1710 /* p->noiphase[11] = 0.0; */
1711 /* p->noiphase[12] = 0.0; */
1712 /* p->noiphase[13] = 0.0; */
1713 /* p->noiphase[14] = 0.0; */
1714 /* p->noiphase[15] = 0.0; */
1715 /* p->noiphase[16] = 0.0; */
1716 /* p->noiphase[17] = 0.0; */
1717 /* p->noiphase[18] = 0.0; */
1718 /* p->noiphase[19] = 0.0; */
1719 /* p->noiphase[20] = 0.0; */
1720 /* p->noiphase[21] = 0.0; */
1721 /* p->noiphase[22] = 0.0; */
1722 /* p->noiphase[23] = 0.0; */
1723 /* p->oscphase[24] = 0.0; */
1724
1725 /* initialise band limited noise parameters */
1726 for (i = 0; i < (int32_t) *p->iptls; i++) {
1727 randiats_setup(csound, freqs[i], &(p->randinoise[i]));
1728 }
1729
1730 return OK;
1731 }
1732
atssinnoiset_S(CSOUND * csound,ATSSINNOI * p)1733 static int32_t atssinnoiset_S(CSOUND *csound, ATSSINNOI *p)
1734 {
1735 char atsfilname[MAXNAME];
1736 ATSSTRUCT *atsh;
1737 int32_t i, memsize, nzmemsize, type;
1738
1739 /* load memfile */
1740 p->swapped = load_atsfile(csound,
1741 p, &(p->atsmemfile), atsfilname, p->ifileno, 1);
1742 if (UNLIKELY(p->swapped < 0)){
1743 return NOTOK;
1744 }
1745 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
1746 p->atshead = atsh;
1747
1748 /* calculate how much memory we have to allocate for this */
1749 /* need room for a buffer and the noise data and the noise info */
1750 /* per partial for synthesizing noise */
1751 memsize = (int32_t) (*p->iptls) * (sizeof(ATS_DATA_LOC) + 2 * sizeof(double)
1752 + sizeof(RANDIATS));
1753 /* allocate space if we need it */
1754 /* need room for a buffer and an array of oscillator phase increments */
1755 if (p->auxch.auxp != NULL || memsize > (int32_t)p->auxch.size)
1756 csound->AuxAlloc(csound, (size_t) memsize, &p->auxch);
1757
1758 /* set up the buffer, phase, etc. */
1759 p->oscbuf = (ATS_DATA_LOC *) (p->auxch.auxp);
1760 p->randinoise = (RANDIATS *) (p->oscbuf + (int32_t) (*p->iptls));
1761 p->oscphase = (double *) (p->randinoise + (int32_t) (*p->iptls));
1762 p->nzbuf = (double *) (p->oscphase + (int32_t) (*p->iptls));
1763
1764 if (p->swapped == 1) {
1765 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
1766 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
1767 p->npartials = (int32_t) bswap(&atsh->npartials);
1768 nzmemsize = (int32_t) (p->npartials * bswap(&atsh->nfrms));
1769 type = (int32_t) bswap(&atsh->type);
1770 }
1771 else {
1772 p->maxFr = (int32_t) atsh->nfrms - 1;
1773 p->timefrmInc = atsh->nfrms / atsh->dur;
1774 p->npartials = (int32_t) atsh->npartials;
1775 nzmemsize = (int32_t) (p->npartials * atsh->nfrms);
1776 type = (int32_t) atsh->type;
1777 }
1778
1779 /* see if we have to allocate memory for the nzdata */
1780 if (nzmemsize != p->nzmemsize) {
1781 if (p->nzdata != NULL)
1782 csound->Free(csound, p->nzdata);
1783 p->nzdata = (double *) csound->Malloc(csound, sizeof(double) * nzmemsize);
1784 }
1785
1786
1787 /* make sure partials are in range */
1788 if (UNLIKELY((int32_t) (*p->iptloffset + *p->iptls * *p->iptlincr) >
1789 p->npartials ||
1790 (int32_t) (*p->iptloffset) < 0)) {
1791 return csound->InitError(csound,
1792 Str("ATSSINNOI: Partial(s) out of range, "
1793 "max partial allowed is %i"), p->npartials);
1794 }
1795 /* get a pointer to the beginning of the data */
1796 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
1797 /* get increments for the partials */
1798
1799 switch (type) {
1800 case 1:
1801 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
1802 p->partialinc = 2 * (int32_t)(*p->iptlincr);
1803 p->frmInc = p->npartials * 2 + 1;
1804 p->firstband = -1;
1805 break;
1806
1807 case 2:
1808 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
1809 p->partialinc = 3 * (int32_t)(*p->iptlincr);
1810 p->frmInc = p->npartials * 3 + 1;
1811 p->firstband = -1;
1812 break;
1813
1814 case 3:
1815 p->firstpartial = 1 + 2 * (int32_t)(*p->iptloffset);
1816 p->partialinc = 2 * (int32_t)(*p->iptlincr);
1817 p->frmInc = p->npartials * 2 + 26;
1818 p->firstband = 1 + 2 * p->npartials;
1819 break;
1820
1821 case 4:
1822 p->firstpartial = 1 + 3 * (int32_t)(*p->iptloffset);
1823 p->partialinc = 3 * (int32_t)(*p->iptlincr);
1824 p->frmInc = p->npartials * 3 + 26;
1825 p->firstband = 1 + 3 * p->npartials;
1826 break;
1827
1828 default:
1829 return csound->InitError(csound, Str("ATSSINNOI: Type not implemented"));
1830 }
1831 /* convert noise per band to noise per partial */
1832 /* make sure we do not do this if we have done it already. */
1833 if ((p->firstband != -1) &&
1834 ((p->filename == NULL) || (strcmp(atsfilname, p->filename) != 0) ||
1835 (p->nzmemsize != nzmemsize))) {
1836 if (p->filename != NULL)
1837 csound->Free(csound, p->filename);
1838 p->filename = (char *) csound->Malloc(csound,
1839 sizeof(char) * strlen(atsfilname));
1840 strcpy(p->filename, atsfilname);
1841 /* csound->Message(csound, "\n band to energy res calculation %s \n",
1842 p->filename); */
1843 /* calculate the band energys */
1844 band_energy_to_res(csound, p);
1845 }
1846 /* save the memory size of the noise */
1847 p->nzmemsize = nzmemsize;
1848
1849
1850 /* flag set to reduce the amount of warnings sent out */
1851 /* for time pointer out of range */
1852 p->prFlg = 1; /* true */
1853
1854 {
1855 double tmp = TWOPI * csound->onedsr;
1856 p->phaseinc[0] = 50.0 * tmp;
1857 p->phaseinc[1] = 150.0 * tmp;
1858 p->phaseinc[2] = 250.0 * tmp;
1859 p->phaseinc[3] = 350.0 * tmp;
1860 p->phaseinc[4] = 455.0 * tmp;
1861 p->phaseinc[5] = 570.0 * tmp;
1862 p->phaseinc[6] = 700.0 * tmp;
1863 p->phaseinc[7] = 845.0 * tmp;
1864 p->phaseinc[8] = 1000.0 * tmp;
1865 p->phaseinc[9] = 1175.0 * tmp;
1866 p->phaseinc[10] = 1375.0 * tmp;
1867 p->phaseinc[11] = 1600.0 * tmp;
1868 p->phaseinc[12] = 1860.0 * tmp;
1869 p->phaseinc[13] = 2160.0 * tmp;
1870 p->phaseinc[14] = 2510.0 * tmp;
1871 p->phaseinc[15] = 2925.0 * tmp;
1872 p->phaseinc[16] = 3425.0 * tmp;
1873 p->phaseinc[17] = 4050.0 * tmp;
1874 p->phaseinc[18] = 4850.0 * tmp;
1875 p->phaseinc[19] = 5850.0 * tmp;
1876 p->phaseinc[20] = 7050.0 * tmp;
1877 p->phaseinc[21] = 8600.0 * tmp;
1878 p->phaseinc[22] = 10750.0 * tmp;
1879 p->phaseinc[23] = 13750.0 * tmp;
1880 p->phaseinc[24] = 17750.0 * tmp;
1881 }
1882
1883 /* initialise phase */
1884 memset(p->noiphase, 0, 25*sizeof(double));
1885
1886 /* initialise band limited noise parameters */
1887 for (i = 0; i < (int32_t) *p->iptls; i++) {
1888 randiats_setup(csound, freqs[i], &(p->randinoise[i]));
1889 }
1890
1891 return OK;
1892 }
1893
atssinnoi(CSOUND * csound,ATSSINNOI * p)1894 static int32_t atssinnoi(CSOUND *csound, ATSSINNOI *p)
1895 {
1896 MYFLT frIndx;
1897 uint32_t offset = p->h.insdshead->ksmps_offset;
1898 uint32_t early = p->h.insdshead->ksmps_no_end;
1899 uint32_t n, nsmps = CS_KSMPS;
1900 MYFLT *ar;
1901 double noise;
1902 double inc;
1903 int32_t i;
1904 double phase;
1905 double amp;
1906 double nzamp; /* noize amp */
1907 double sinewave;
1908 MYFLT freq;
1909 ATS_DATA_LOC *oscbuf;
1910 //csound->Message(csound , "start \n");
1911
1912 /* make sure time pointer is within range */
1913 if ((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0)) {
1914 frIndx = FL(0.0);
1915 if (UNLIKELY(p->prFlg)) {
1916 p->prFlg = 0;
1917 csound->Warning(csound, Str("ATSSINNOI: only positive time pointer "
1918 "values are allowed, setting to zero\n"));
1919 }
1920 }
1921 else if (OUT_OF_FRAMES) {
1922 /* if we are trying to get frames past where we have data */
1923 if (UNLIKELY(p->prFlg)) {
1924 p->prFlg = 0; /* set to false */
1925 csound->Warning(csound, Str("ATSSINNOI: time pointer out of range, "
1926 // "frIndx=%g maxFr=%g (%g %g) "
1927 "truncating to last frame\n")
1928 //frIndx, (MYFLT)p->maxFr, *(p->ktimpnt), p->timefrmInc
1929 );
1930 }
1931 frIndx = (MYFLT) p->maxFr;
1932 }
1933 else
1934 p->prFlg = 1;
1935
1936
1937 fetchSINNOIpartials(p, frIndx);
1938
1939 FetchADDNZbands(*p->iptls, p->firstband, p->datastart, p->frmInc, p->maxFr,
1940 p->swapped, p->nzbuf, frIndx);
1941
1942
1943 /* set local pointer to output and initialise output to zero */
1944 ar = p->aoutput;
1945
1946 memset(ar, 0, CS_KSMPS*sizeof(MYFLT));
1947 if (UNLIKELY(early)) nsmps -= early;
1948
1949 oscbuf = p->oscbuf;
1950
1951 /* do synthesis */
1952 if (p->firstband != -1) {
1953
1954 for (i = 0; i < (int32_t) *p->iptls; i++) {
1955 phase = p->oscphase[i];
1956 ar = p->aoutput;
1957 amp = oscbuf[i].amp;
1958 freq = (MYFLT) oscbuf[i].freq * *p->kfreq;
1959 inc = TWOPI * freq * csound->onedsr;
1960 nzamp =
1961 sqrt(*(p->nzbuf + i) / (p->atshead->winsz * ATSA_NOISE_VARIANCE));
1962 for (n=offset; n<nsmps;n++) {
1963 /* calc sine wave */
1964 sinewave = cos(phase);
1965 phase += inc;
1966
1967 /* calc noise */
1968 if (i < 25) {
1969 noise = nzamp * cos(p->noiphase[i]) *
1970 randiats(csound, &(p->randinoise[i]));
1971 p->noiphase[i] += p->phaseinc[i];
1972 }
1973 else noise = FL(0.0);
1974 /* calc output */
1975 ar[n] += csound->e0dbfs *
1976 (MYFLT)(amp * sinewave * *p->ksinamp + noise **p->knzamp);
1977 }
1978 p->oscphase[i] = phase;
1979 }
1980
1981 }
1982 else {
1983 for (i = 0; i < (int32_t) *p->iptls; i++) {
1984 phase = p->oscphase[i];
1985 ar = p->aoutput;
1986 amp = oscbuf[i].amp;
1987 freq = (MYFLT) oscbuf[i].freq * *p->kfreq;
1988 inc = TWOPI * freq * csound->onedsr;
1989 for (n=offset; n<nsmps;n++) {
1990 /* calc sine wave */
1991 sinewave = cos(phase) * amp;
1992 phase += inc;
1993 /* calc output */
1994 ar[n] += csound->e0dbfs * (MYFLT)sinewave * *p->ksinamp;
1995 }
1996 p->oscphase[i] = phase;
1997 }
1998
1999 }
2000
2001 return OK;
2002 }
2003
fetchSINNOIpartials(ATSSINNOI * p,MYFLT position)2004 static void fetchSINNOIpartials(ATSSINNOI *p, MYFLT position)
2005 {
2006 double frac; /* the distance in time we are between frames */
2007 double *frm_0, *frm_1;
2008 double frm0amp, frm0freq, frm1amp, frm1freq;
2009 double nz0, nz1;
2010 ATS_DATA_LOC *oscbuf;
2011 double *nzbuf;
2012 int32_t frame;
2013 int32_t i; /* for the for loop */
2014 int32_t npartials = p->npartials;
2015
2016 frame = (int32_t) position;
2017 frm_0 = p->datastart + frame * p->frmInc;
2018
2019 oscbuf = p->oscbuf;
2020 nzbuf = p->nzbuf;
2021
2022 /* if we are using the data from the last frame */
2023 /* we should not try to interpolate */
2024 if (UNLIKELY(frame == p->maxFr)) {
2025 if (p->firstband == -1) { /* there is no noise data */
2026 if (p->swapped == 1) {
2027 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2028 i += (int32_t) *p->iptlincr) {
2029 oscbuf->amp = bswap(frm_0 + 1 + i * (int32_t) p->partialinc); /* amp */
2030 oscbuf->freq= bswap(frm_0 + 2 + i * (int32_t) p->partialinc); /* freq */
2031 oscbuf++;
2032 }
2033 }
2034 else {
2035 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2036 i += (int32_t) *p->iptlincr) {
2037 oscbuf->amp = *(frm_0 + 1 + i * (int32_t) p->partialinc); /* amp */
2038 oscbuf->freq = *(frm_0 + 2 + i * (int32_t) p->partialinc); /* freq */
2039 oscbuf++;
2040 }
2041 }
2042 }
2043 else {
2044 if (p->swapped == 1) {
2045 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2046 i += (int32_t) *p->iptlincr) {
2047 oscbuf->amp = bswap(frm_0 + 1 + i * (int32_t) p->partialinc); /* amp */
2048 oscbuf->freq= bswap(frm_0 + 2 + i * (int32_t) p->partialinc); /* freq */
2049 *nzbuf = bswap(p->nzdata + frame * npartials + i);
2050 nzbuf++;
2051 oscbuf++;
2052 }
2053 }
2054 else {
2055 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2056 i += (int32_t) *p->iptlincr) {
2057 oscbuf->amp = *(frm_0 + 1 + i * (int32_t) p->partialinc); /* amp */
2058 oscbuf->freq = *(frm_0 + 2 + i * (int32_t) p->partialinc); /* freq */
2059 *nzbuf = *(p->nzdata + frame * npartials + i);
2060 nzbuf++;
2061 oscbuf++;
2062 }
2063 }
2064 }
2065
2066 return;
2067 }
2068 frm_1 = frm_0 + p->frmInc;
2069 frac = (double) (position - frame);
2070
2071 if (p->firstband == -1) { /* there is no noise data */
2072 if (p->swapped == 1) {
2073 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2074 i += (int32_t) *p->iptlincr) {
2075 frm0amp = bswap(frm_0 + 1 + i * (int32_t) p->partialinc);
2076 frm1amp = bswap(frm_1 + 1 + i * (int32_t) p->partialinc);
2077 frm0freq = bswap(frm_0 + 2 + i * (int32_t) p->partialinc);
2078 frm1freq = bswap(frm_1 + 2 + i * (int32_t) p->partialinc);
2079 oscbuf->amp = frm0amp + frac * (frm1amp - frm0amp); /* amp */
2080 oscbuf->freq = frm0freq + frac * (frm1freq - frm0freq); /* freq */
2081 oscbuf++;
2082 }
2083 }
2084 else {
2085 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2086 i += (int32_t) *p->iptlincr) {
2087 frm0amp = *(frm_0 + 1 + i * (int32_t) p->partialinc);
2088 frm1amp = *(frm_1 + 1 + i * (int32_t) p->partialinc);
2089 frm0freq = *(frm_0 + 2 + i * (int32_t) p->partialinc);
2090 frm1freq = *(frm_1 + 2 + i * (int32_t) p->partialinc);
2091 oscbuf->amp = frm0amp + frac * (frm1amp - frm0amp); /* amp */
2092 oscbuf->freq = frm0freq + frac * (frm1freq - frm0freq); /* freq */
2093 oscbuf++;
2094 }
2095 }
2096 }
2097 else {
2098 if (p->swapped == 1) {
2099 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2100 i += (int32_t) *p->iptlincr) {
2101 frm0amp = bswap(frm_0 + 1 + i * (int32_t) p->partialinc);
2102 frm1amp = bswap(frm_1 + 1 + i * (int32_t) p->partialinc);
2103 frm0freq = bswap(frm_0 + 2 + i * (int32_t) p->partialinc);
2104 frm1freq = bswap(frm_1 + 2 + i * (int32_t) p->partialinc);
2105 nz0 = bswap(p->nzdata + frame * npartials + i);
2106 nz1 = bswap(p->nzdata + (frame + 1) * npartials + i);
2107 oscbuf->amp = frm0amp + frac * (frm1amp - frm0amp); /* amp */
2108 oscbuf->freq = frm0freq + frac * (frm1freq - frm0freq); /* freq */
2109 /* noise */
2110 *nzbuf = nz0 + frac * (nz1 - nz0);
2111 nzbuf++;
2112 oscbuf++;
2113 }
2114 }
2115 else {
2116 for (i = (int32_t) *p->iptloffset; i < (int32_t) *p->iptls+*p->iptloffset;
2117 i += (int32_t) *p->iptlincr) {
2118 frm0amp = *(frm_0 + 1 + i * (int32_t) p->partialinc);
2119 frm1amp = *(frm_1 + 1 + i * (int32_t) p->partialinc);
2120 frm0freq = *(frm_0 + 2 + i * (int32_t) p->partialinc);
2121 frm1freq = *(frm_1 + 2 + i * (int32_t) p->partialinc);
2122 nz0 = *(p->nzdata + frame * npartials + i);
2123 nz1 = *(p->nzdata + (frame + 1) * npartials + i);
2124 oscbuf->amp = frm0amp + frac * (frm1amp - frm0amp); /* amp */
2125 oscbuf->freq = frm0freq + frac * (frm1freq - frm0freq); /* freq */
2126 /* noise */
2127 *nzbuf = nz0 + frac * (nz1 - nz0);
2128 nzbuf++;
2129 oscbuf++;
2130 }
2131 }
2132 }
2133 }
2134
2135 /************************************************************/
2136 /*********** ATSBUFREAD *************************************/
2137 /************************************************************/
2138
atsbufreadset(CSOUND * csound,ATSBUFREAD * p)2139 static int32_t atsbufreadset(CSOUND *csound, ATSBUFREAD *p)
2140 {
2141 char atsfilname[MAXNAME];
2142 MEMFIL *mfp;
2143 ATS_DATA_LOC *fltp;
2144 ATSSTRUCT *atsh;
2145 int32_t type, n_partials;
2146 int32_t memsize; /* the size of the memory to request for AUX */
2147
2148 /* load memfile */
2149 p->swapped = load_atsfile(csound, p, &mfp, atsfilname, p->ifileno, 0);
2150 if (UNLIKELY(p->swapped < 0))
2151 return NOTOK;
2152 atsh = (ATSSTRUCT*) mfp->beginp;
2153
2154 /* get past the header to the data, point frptr at time 0 */
2155 p->datastart = (double *) atsh + 10;
2156 p->prFlg = 1; /* true */
2157
2158 /* is swapped? */
2159 if (p->swapped == 1) {
2160 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
2161 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
2162 type = (int32_t) bswap(&atsh->type);
2163 n_partials = (int32_t) bswap(&atsh->npartials);
2164 }
2165 else {
2166 p->maxFr = (int32_t) atsh->nfrms - 1;
2167 p->timefrmInc = atsh->nfrms / atsh->dur;
2168 type = (int32_t) atsh->type;
2169 n_partials = (int32_t) atsh->npartials;
2170 }
2171
2172 /* we need room for 2 * (1 table + 2 for 20 and 20,000 hz) */
2173 /* (one sorted one unsorted) */
2174 memsize = 2 * ((int32_t) *(p->iptls) + 2);
2175
2176 csound->AuxAlloc(csound, (size_t)memsize * sizeof(ATS_DATA_LOC), &p->auxch);
2177
2178 fltp = (ATS_DATA_LOC *) p->auxch.auxp;
2179 p->table = fltp;
2180 p->utable = fltp + ((int32_t) *(p->iptls) + 2);
2181
2182 /* check to see if partial is valid */
2183 if (UNLIKELY((int32_t)(*p->iptloffset+ *p->iptls * *p->iptlincr) > n_partials ||
2184 (int32_t)(*p->iptloffset) < 0)) {
2185 return csound->InitError(csound, Str("ATSBUFREAD: Partial out of range, "
2186 "max partial is %i"), n_partials);
2187 }
2188
2189 /* set up partial locations and frame increments */
2190
2191 switch (type) {
2192 case 1:
2193 p->firstpartial = 1 + 2 * (*p->iptloffset);
2194 p->partialinc = 2;
2195 p->frmInc = n_partials * 2 + 1;
2196 break;
2197
2198 case 2:
2199 p->firstpartial = 1 + 3 * (*p->iptloffset);
2200 p->partialinc = 3;
2201 p->frmInc = n_partials * 3 + 1;
2202 break;
2203
2204 case 3:
2205 p->firstpartial = 1 + 2 * (*p->iptloffset);
2206 p->partialinc = 2;
2207 p->frmInc = n_partials * 2 + 26;
2208 break;
2209
2210 case 4:
2211 p->firstpartial = 1 + 3 * (*p->iptloffset);
2212 p->partialinc = 3;
2213 p->frmInc = n_partials * 3 + 26;
2214 break;
2215
2216 default:
2217 return csound->InitError(csound, Str("ATSBUFREAD: Type not implemented"));
2218 }
2219
2220 /* put 20 hertz = 0amp and 20000 hz = 0amp */
2221 /* to make interpolation easier later */
2222 p->table[0].freq = p->utable[0].freq = 20;
2223 p->table[0].amp = p->utable[0].amp = 0;
2224 p->table[(int32_t) *p->iptls + 1].freq =
2225 p->utable[(int32_t) *p->iptls + 1].freq =
2226 20000;
2227 p->table[(int32_t) *p->iptls + 1].amp =
2228 p->utable[(int32_t) *p->iptls + 1].amp = 0;
2229
2230 *(get_atsbufreadaddrp(csound)) = p;
2231
2232 return OK;
2233 }
2234
atsbufreadset_S(CSOUND * csound,ATSBUFREAD * p)2235 static int32_t atsbufreadset_S(CSOUND *csound, ATSBUFREAD *p)
2236 {
2237 char atsfilname[MAXNAME];
2238 MEMFIL *mfp;
2239 ATS_DATA_LOC *fltp;
2240 ATSSTRUCT *atsh;
2241 int32_t type, n_partials;
2242 int32_t memsize; /* the size of the memory to request for AUX */
2243
2244 /* load memfile */
2245 p->swapped = load_atsfile(csound, p, &mfp, atsfilname, p->ifileno, 1);
2246 if (UNLIKELY(p->swapped < 0))
2247 return NOTOK;
2248 atsh = (ATSSTRUCT*) mfp->beginp;
2249
2250 /* get past the header to the data, point frptr at time 0 */
2251 p->datastart = (double *) atsh + 10;
2252 p->prFlg = 1; /* true */
2253
2254 /* is swapped? */
2255 if (p->swapped == 1) {
2256 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
2257 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
2258 type = (int32_t) bswap(&atsh->type);
2259 n_partials = (int32_t) bswap(&atsh->npartials);
2260 }
2261 else {
2262 p->maxFr = (int32_t) atsh->nfrms - 1;
2263 p->timefrmInc = atsh->nfrms / atsh->dur;
2264 type = (int32_t) atsh->type;
2265 n_partials = (int32_t) atsh->npartials;
2266 }
2267
2268 /* we need room for 2 * (1 table + 2 for 20 and 20,000 hz) */
2269 /* (one sorted one unsorted) */
2270 memsize = 2 * ((int32_t) *(p->iptls) + 2);
2271
2272 csound->AuxAlloc(csound, (size_t)memsize * sizeof(ATS_DATA_LOC), &p->auxch);
2273
2274 fltp = (ATS_DATA_LOC *) p->auxch.auxp;
2275 p->table = fltp;
2276 p->utable = fltp + ((int32_t) *(p->iptls) + 2);
2277
2278 /* check to see if partial is valid */
2279 if (UNLIKELY((int32_t)(*p->iptloffset + *p->iptls * *p->iptlincr) >
2280 n_partials ||
2281 (int32_t)(*p->iptloffset) < 0)) {
2282 return csound->InitError(csound, Str("ATSBUFREAD: Partial out of range, "
2283 "max partial is %i"), n_partials);
2284 }
2285
2286 /* set up partial locations and frame increments */
2287
2288 switch (type) {
2289 case 1:
2290 p->firstpartial = 1 + 2 * (*p->iptloffset);
2291 p->partialinc = 2;
2292 p->frmInc = n_partials * 2 + 1;
2293 break;
2294
2295 case 2:
2296 p->firstpartial = 1 + 3 * (*p->iptloffset);
2297 p->partialinc = 3;
2298 p->frmInc = n_partials * 3 + 1;
2299 break;
2300
2301 case 3:
2302 p->firstpartial = 1 + 2 * (*p->iptloffset);
2303 p->partialinc = 2;
2304 p->frmInc = n_partials * 2 + 26;
2305 break;
2306
2307 case 4:
2308 p->firstpartial = 1 + 3 * (*p->iptloffset);
2309 p->partialinc = 3;
2310 p->frmInc = n_partials * 3 + 26;
2311 break;
2312
2313 default:
2314 return csound->InitError(csound, Str("ATSBUFREAD: Type not implemented"));
2315 }
2316
2317 /* put 20 hertz = 0amp and 20000 hz = 0amp */
2318 /* to make interpolation easier later */
2319 p->table[0].freq = p->utable[0].freq = 20;
2320 p->table[0].amp = p->utable[0].amp = 0;
2321 p->table[(int32_t) *p->iptls + 1].freq =
2322 p->utable[(int32_t) *p->iptls + 1].freq =
2323 20000;
2324 p->table[(int32_t) *p->iptls + 1].amp =
2325 p->utable[(int32_t) *p->iptls + 1].amp = 0;
2326
2327 *(get_atsbufreadaddrp(csound)) = p;
2328
2329 return OK;
2330 }
2331
2332
mycomp(const void * p1,const void * p2)2333 static int32_t mycomp(const void *p1, const void *p2)
2334 {
2335 const ATS_DATA_LOC *a1 = p1;
2336 const ATS_DATA_LOC *a2 = p2;
2337 double a1f = a1->freq;
2338 double a2f = a2->freq;
2339 if (a1f < a2f)
2340 return -1;
2341 else if (a1f == a2f)
2342 return 0;
2343 else
2344 return 1;
2345 }
2346
FetchBUFPartials(ATSBUFREAD * p,ATS_DATA_LOC * buf,ATS_DATA_LOC * buf2,MYFLT position)2347 static void FetchBUFPartials(ATSBUFREAD *p,
2348 ATS_DATA_LOC *buf, ATS_DATA_LOC *buf2,
2349 MYFLT position)
2350 {
2351 MYFLT frac; /* the distance in time we are between frames */
2352 double *frm_0, *frm_1;
2353 double frm0amp, frm0freq, frm1amp, frm1freq;
2354 int32_t frame;
2355 int32_t i; /* for the for loop */
2356 int32_t partialloc = p->firstpartial;
2357 int32_t npartials = (int32_t) *p->iptls;
2358
2359 frame = (int32_t) position;
2360 frm_0 = p->datastart + frame * p->frmInc;
2361
2362 /* if we are using the data from the last frame */
2363 /* we should not try to interpolate */
2364 if (UNLIKELY(frame == p->maxFr)) {
2365 if (p->swapped == 1) {
2366 for (i = 0; i < npartials; i++) { /* calc amplitude */
2367 buf[i].amp = buf2[i].amp = bswap(&frm_0[partialloc]);
2368 buf[i].freq = buf2[i].freq = bswap(&frm_0[partialloc + 1]);
2369 partialloc += p->partialinc;
2370 }
2371 }
2372 else {
2373 for (i = 0; i < npartials; i++) {
2374 buf[i].amp = buf2[i].amp = frm_0[partialloc]; /* calc amplitude */
2375 buf[i].freq = buf2[i].freq = frm_0[partialloc + 1];
2376 partialloc += p->partialinc;
2377 }
2378 }
2379 return;
2380 }
2381
2382 frac = position - frame;
2383 frm_1 = frm_0 + p->frmInc;
2384 if (p->swapped == 1) {
2385 for (i = 0; i < npartials; i++) {
2386 frm0amp = bswap(&frm_0[partialloc]);
2387 frm0freq = bswap(&frm_0[partialloc + 1]);
2388 frm1amp = bswap(&frm_1[partialloc]);
2389 frm1freq = bswap(&frm_1[partialloc + 1]);
2390 /* calc amplitude */
2391 buf[i].amp = buf2[i].amp = frm0amp + frac * (frm1amp - frm0amp);
2392 /* calc freq */
2393 buf[i].freq = buf2[i].freq =
2394 *p->kfmod * (frm0freq + frac * (frm1freq - frm0freq));
2395 partialloc += p->partialinc; /* get to the next partial */
2396 }
2397 }
2398 else {
2399 for (i = 0; i < npartials; i++) {
2400 /* calc amplitude */
2401 buf[i].amp = buf2[i].amp =
2402 frm_0[partialloc] + frac * (frm_1[partialloc] - frm_0[partialloc]);
2403 /* calc freq */
2404 buf[i].freq = buf2[i].freq =
2405 *p->kfmod * (frm_0[partialloc + 1]
2406 + frac * (frm_1[partialloc + 1]
2407 - frm_0[partialloc + 1]));
2408 partialloc += p->partialinc; /* get to the next partial */
2409 }
2410 }
2411 }
2412
atsbufread(CSOUND * csound,ATSBUFREAD * p)2413 static int32_t atsbufread(CSOUND *csound, ATSBUFREAD *p)
2414 {
2415 MYFLT frIndx;
2416 ATS_DATA_LOC *buf;
2417 ATS_DATA_LOC *buf2;
2418
2419 if (UNLIKELY(p->table == NULL)) goto err1; /* RWD fix */
2420
2421 *(get_atsbufreadaddrp(csound)) = p;
2422
2423 /* make sure time pointer is within range */
2424 if ((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0)) {
2425 frIndx = FL(0.0);
2426 if (UNLIKELY(p->prFlg)) {
2427 p->prFlg = 0;
2428 csound->Warning(csound, Str("ATSBUFREAD: only positive time pointer "
2429 "values are allowed, setting to zero\n"));
2430 }
2431 }
2432 else if (OUT_OF_FRAMES) {
2433 /* if we are trying to get frames past where we have data */
2434 frIndx = (MYFLT) p->maxFr;
2435 if (UNLIKELY(p->prFlg)) {
2436 p->prFlg = 0; /* set to false */
2437 csound->Warning(csound, Str("ATSBUFREAD: time pointer out of range, "
2438 "truncating to last frame\n"));
2439 }
2440 }
2441 else
2442 p->prFlg = 1;
2443
2444 /* skip the first value in the table because */
2445 /* we will never have to change it as it is 20hz with amp 0 */
2446 buf = p->table + 1;
2447 buf2 = p->utable + 1;
2448 FetchBUFPartials(p, buf, buf2, frIndx);
2449 /* must sort the buffered values */
2450 qsort(buf, (int32_t) *p->iptls, sizeof(ATS_DATA_LOC), mycomp);
2451
2452 return OK;
2453 err1:
2454 return csound->PerfError(csound, &(p->h),
2455 Str("ATSBUFREAD: not initialised"));
2456 }
2457
2458 /* ATS partial tap */
2459
atspartialtapset(CSOUND * csound,ATSPARTIALTAP * p)2460 static int32_t atspartialtapset(CSOUND *csound, ATSPARTIALTAP *p)
2461 {
2462 ATSBUFREAD *atsbufreadaddr;
2463
2464 atsbufreadaddr = *(get_atsbufreadaddrp(csound));
2465 if (UNLIKELY(atsbufreadaddr == NULL)) {
2466 return csound->InitError(csound,
2467 Str("ATSPARTIALTAP: you must have an "
2468 "atsbufread before an atspartialtap"));
2469 }
2470 if (UNLIKELY((int32_t) *p->iparnum > (int32_t) *(atsbufreadaddr->iptls))) {
2471 return csound->InitError(csound, Str("ATSPARTIALTAP: exceeded "
2472 "max partial %i"),
2473 (int32_t) *(atsbufreadaddr->iptls));
2474 }
2475 if (UNLIKELY((int32_t) *p->iparnum <= 0)) {
2476 return csound->InitError(csound, Str("ATSPARTIALTAP: partial must be "
2477 "positive and nonzero"));
2478 }
2479 return OK;
2480 }
2481
atspartialtap(CSOUND * csound,ATSPARTIALTAP * p)2482 static int32_t atspartialtap(CSOUND *csound, ATSPARTIALTAP *p)
2483 {
2484 ATSBUFREAD *atsbufreadaddr;
2485
2486 atsbufreadaddr = *(get_atsbufreadaddrp(csound));
2487 if (UNLIKELY(atsbufreadaddr == NULL)) goto err1;
2488 *p->kfreq = (MYFLT) ((atsbufreadaddr->utable)[(int32_t)(*p->iparnum)].freq);
2489 *p->kamp = (MYFLT) ((atsbufreadaddr->utable)[(int32_t)(*p->iparnum)].amp);
2490 return OK;
2491 err1:
2492 return csound->PerfError(csound, &(p->h),
2493 Str("ATSPARTIALTAP: you must have an "
2494 "atsbufread before an atspartialtap"));
2495 }
2496
2497 /* ATS interpread */
2498
atsinterpreadset(CSOUND * csound,ATSINTERPREAD * p)2499 static int32_t atsinterpreadset(CSOUND *csound, ATSINTERPREAD *p)
2500 {
2501 if (UNLIKELY(*(get_atsbufreadaddrp(csound)) == NULL))
2502 return csound->InitError(csound,
2503 Str("ATSINTERPREAD: you must have an "
2504 "atsbufread before an atsinterpread"));
2505 p->overflowflag = 1; /* true */
2506 return OK;
2507 }
2508
atsinterpread(CSOUND * csound,ATSINTERPREAD * p)2509 static int32_t atsinterpread(CSOUND *csound, ATSINTERPREAD *p)
2510 {
2511 ATSBUFREAD *atsbufreadaddr;
2512 int32_t i;
2513 MYFLT frac;
2514
2515 /* make sure we have data to read from */
2516 atsbufreadaddr = *(get_atsbufreadaddrp(csound));
2517 if (UNLIKELY(atsbufreadaddr == NULL)) goto err1;
2518 /* make sure we are not asking for unreasonble frequencies */
2519 if (UNLIKELY(*p->kfreq <= FL(20.0) || *p->kfreq >= FL(20000.0))) {
2520 if (UNLIKELY(p->overflowflag)) {
2521 csound->Warning(csound, Str("ATSINTERPREAD: frequency must be greater "
2522 "than 20 and less than 20000 Hz"));
2523 p->overflowflag = 0;
2524 }
2525 *p->kamp = FL(0.0);
2526 return OK;
2527 }
2528 /* find the location in the table */
2529 for (i = 0; i < (int32_t) *(atsbufreadaddr->iptls); i++) {
2530 /* find i such that table i+1 is greater than the specified frequency */
2531 if ((MYFLT) ((atsbufreadaddr->table[i + 1]).freq) > *p->kfreq)
2532 break;
2533 }
2534 if (i == 0) {
2535 *p->kamp = FL(0.0);
2536 return OK;
2537 }
2538 /* linear interpolation */
2539 frac =
2540 (*p->kfreq -
2541 (atsbufreadaddr->table[i]).freq) /
2542 ((atsbufreadaddr->table[i + 1]).freq - (atsbufreadaddr->table[i]).freq);
2543 *p->kamp =
2544 (MYFLT) ((atsbufreadaddr->table[i]).amp +
2545 frac * ((atsbufreadaddr->table[i + 1]).amp -
2546 (atsbufreadaddr->table[i]).amp));
2547 /* *p->kamp = (MYFLT) (atsbufreadaddr->table[i]).amp; */
2548 return OK;
2549 err1:
2550 return csound->PerfError(csound, &(p->h),
2551 Str("ATSINTERPREAD: you must have an "
2552 "atsbufread before an atsinterpread"));
2553 }
2554
2555 /* ATS cross */
2556
atscrossset(CSOUND * csound,ATSCROSS * p)2557 static int32_t atscrossset(CSOUND *csound, ATSCROSS *p)
2558 {
2559 char atsfilname[MAXNAME];
2560 ATSSTRUCT *atsh;
2561 FUNC *ftp;
2562 int32_t memsize;
2563 int32_t type, n_partials;
2564
2565 /* set up function table for synthesis */
2566 if (UNLIKELY((ftp = csound->FTFind(csound, p->ifn)) == NULL)) {
2567 return csound->InitError(csound, Str("ATSCROSS: Function table number for "
2568 "synthesis waveform not valid"));
2569 }
2570 p->ftp = ftp;
2571
2572 /* load memfile */
2573 p->swapped = load_atsfile(csound,
2574 p, &(p->atsmemfile), atsfilname, p->ifileno, 0);
2575 if (UNLIKELY(p->swapped < 0))
2576 return NOTOK;
2577 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
2578
2579 /* calculate how much memory we have to allocate for this */
2580 memsize = (int32_t)(*p->iptls) *
2581 (sizeof(ATS_DATA_LOC) + sizeof(double) + sizeof(MYFLT)) ;
2582 /* allocate space if we need it */
2583 /* need room for a buffer and an array of oscillator phase increments */
2584 if (p->auxch.auxp == NULL || p->auxch.size >= (uint32_t)memsize)
2585 csound->AuxAlloc(csound, (size_t) memsize, &p->auxch);
2586
2587 /* set up the buffer, phase, etc. */
2588 p->buf = (ATS_DATA_LOC *) (p->auxch.auxp);
2589 p->oscphase = (double *) (p->buf + (int32_t)(*p->iptls));
2590 p->oldamps = (MYFLT *) (p->oscphase + (int32_t)(*p->iptls));
2591 if (p->swapped == 1) {
2592 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
2593 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
2594 type = (int32_t) bswap(&atsh->type);
2595 n_partials = (int32_t) bswap(&atsh->npartials);
2596 }
2597 else {
2598 p->maxFr = (int32_t) atsh->nfrms - 1;
2599 p->timefrmInc = atsh->nfrms / atsh->dur;
2600 type = (int32_t) atsh->type;
2601 n_partials = (int32_t) atsh->npartials;
2602 }
2603
2604 /* make sure partials are in range */
2605 if ((int32_t)(*p->iptloffset + *p->iptls * *p->iptlincr) > n_partials ||
2606 (int32_t)(*p->iptloffset) < 0) {
2607 return csound->InitError(csound, Str("ATSCROSS: Partial(s) out of range, "
2608 "max partial allowed is %i"),
2609 n_partials);
2610 }
2611 /* get a pointer to the beginning of the data */
2612 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
2613
2614 /* get increments for the partials */
2615 switch (type) {
2616 case 1:
2617 p->firstpartial = (int32_t) (1 + 2 * (*p->iptloffset));
2618 p->partialinc = 2 * (int32_t)(*p->iptlincr);
2619 p->frmInc = n_partials * 2 + 1;
2620 break;
2621
2622 case 2:
2623 p->firstpartial = (int32_t) (1 + 3 * (*p->iptloffset));
2624 p->partialinc = 3 * (int32_t)(*p->iptlincr);
2625 p->frmInc = n_partials * 3 + 1;
2626 break;
2627
2628 case 3:
2629 p->firstpartial = (int32_t) (1 + 2 * (*p->iptloffset));
2630 p->partialinc = 2 * (int32_t)(*p->iptlincr);
2631 p->frmInc = n_partials * 2 + 26;
2632 break;
2633
2634 case 4:
2635 p->firstpartial = (int32_t) (1 + 3 * (*p->iptloffset));
2636 p->partialinc = 3 * (int32_t)(*p->iptlincr);
2637 p->frmInc = n_partials * 3 + 26;
2638 break;
2639
2640 default:
2641 return csound->InitError(csound, Str("ATSCROSS: Type not implemented"));
2642 }
2643
2644 /* flag set to reduce the amount of warnings sent out */
2645 /* for time pointer out of range */
2646 p->prFlg = 1; /* true */
2647
2648 return OK;
2649 }
2650
atscrossset_S(CSOUND * csound,ATSCROSS * p)2651 static int32_t atscrossset_S(CSOUND *csound, ATSCROSS *p)
2652 {
2653 char atsfilname[MAXNAME];
2654 ATSSTRUCT *atsh;
2655 FUNC *ftp;
2656 int32_t memsize;
2657 int32_t type, n_partials;
2658
2659 /* set up function table for synthesis */
2660 if (UNLIKELY((ftp = csound->FTFind(csound, p->ifn)) == NULL)) {
2661 return csound->InitError(csound, Str("ATSCROSS: Function table number for "
2662 "synthesis waveform not valid"));
2663 }
2664 p->ftp = ftp;
2665
2666 /* load memfile */
2667 p->swapped = load_atsfile(csound,
2668 p, &(p->atsmemfile), atsfilname, p->ifileno, 1);
2669 if (UNLIKELY(p->swapped < 0))
2670 return NOTOK;
2671 atsh = (ATSSTRUCT*) p->atsmemfile->beginp;
2672
2673 /* calculate how much memory we have to allocate for this */
2674 memsize = (int32_t)(*p->iptls) *
2675 (sizeof(ATS_DATA_LOC) + sizeof(double) + sizeof(MYFLT)) ;
2676 /* allocate space if we need it */
2677 /* need room for a buffer and an array of oscillator phase increments */
2678 if (p->auxch.auxp == NULL || p->auxch.size >= (uint32_t)memsize)
2679 csound->AuxAlloc(csound, (size_t) memsize, &p->auxch);
2680
2681 /* set up the buffer, phase, etc. */
2682 p->buf = (ATS_DATA_LOC *) (p->auxch.auxp);
2683 p->oscphase = (double *) (p->buf + (int32_t)(*p->iptls));
2684 p->oldamps = (MYFLT *) (p->oscphase + (int32_t)(*p->iptls));
2685 if (p->swapped == 1) {
2686 p->maxFr = (int32_t) bswap(&atsh->nfrms) - 1;
2687 p->timefrmInc = bswap(&atsh->nfrms) / bswap(&atsh->dur);
2688 type = (int32_t) bswap(&atsh->type);
2689 n_partials = (int32_t) bswap(&atsh->npartials);
2690 }
2691 else {
2692 p->maxFr = (int32_t) atsh->nfrms - 1;
2693 p->timefrmInc = atsh->nfrms / atsh->dur;
2694 type = (int32_t) atsh->type;
2695 n_partials = (int32_t) atsh->npartials;
2696 }
2697
2698 /* make sure partials are in range */
2699 if (UNLIKELY((int32_t)(*p->iptloffset + *p->iptls * *p->iptlincr) >
2700 n_partials ||
2701 (int32_t)(*p->iptloffset) < 0)) {
2702 return csound->InitError(csound, Str("ATSCROSS: Partial(s) out of range, "
2703 "max partial allowed is %i"),
2704 n_partials);
2705 }
2706 /* get a pointer to the beginning of the data */
2707 p->datastart = (double *) (p->atsmemfile->beginp + sizeof(ATSSTRUCT));
2708
2709 /* get increments for the partials */
2710 switch (type) {
2711 case 1:
2712 p->firstpartial = (int32_t) (1 + 2 * (*p->iptloffset));
2713 p->partialinc = 2 * (int32_t)(*p->iptlincr);
2714 p->frmInc = n_partials * 2 + 1;
2715 break;
2716
2717 case 2:
2718 p->firstpartial = (int32_t) (1 + 3 * (*p->iptloffset));
2719 p->partialinc = 3 * (int32_t)(*p->iptlincr);
2720 p->frmInc = n_partials * 3 + 1;
2721 break;
2722
2723 case 3:
2724 p->firstpartial = (int32_t) (1 + 2 * (*p->iptloffset));
2725 p->partialinc = 2 * (int32_t)(*p->iptlincr);
2726 p->frmInc = n_partials * 2 + 26;
2727 break;
2728
2729 case 4:
2730 p->firstpartial = (int32_t) (1 + 3 * (*p->iptloffset));
2731 p->partialinc = 3 * (int32_t)(*p->iptlincr);
2732 p->frmInc = n_partials * 3 + 26;
2733 break;
2734
2735 default:
2736 return csound->InitError(csound, Str("ATSCROSS: Type not implemented"));
2737 }
2738
2739 /* flag set to reduce the amount of warnings sent out */
2740 /* for time pointer out of range */
2741 p->prFlg = 1; /* true */
2742
2743 return OK;
2744 }
2745
FetchCROSSPartials(ATSCROSS * p,ATS_DATA_LOC * buf,MYFLT position)2746 static void FetchCROSSPartials(ATSCROSS *p, ATS_DATA_LOC *buf, MYFLT position)
2747 {
2748 MYFLT frac; /* the distance in time we are between frames */
2749 double *frm_0, *frm_1;
2750 double frm0amp, frm0freq, frm1amp, frm1freq;
2751 int32_t frame;
2752 int32_t i; /* for the for loop */
2753 int32_t partialloc = p->firstpartial;
2754 int32_t npartials = (int32_t) *p->iptls;
2755
2756 frame = (int32_t) position;
2757 frm_0 = p->datastart + frame * p->frmInc;
2758
2759 /* if we are using the data from the last frame */
2760 /* we should not try to interpolate */
2761 if (UNLIKELY(frame == p->maxFr)) {
2762 if (p->swapped == 1) {
2763 for (i = 0; i < npartials; i++) {
2764 buf[i].amp = bswap(&frm_0[partialloc]); /* calc amplitude */
2765 buf[i].freq = bswap(&frm_0[partialloc + 1]);
2766 partialloc += p->partialinc;
2767 }
2768 }
2769 else {
2770 for (i = 0; i < npartials; i++) {
2771 buf[i].amp = frm_0[partialloc]; /* calc amplitude */
2772 buf[i].freq = frm_0[partialloc + 1];
2773 partialloc += p->partialinc;
2774 }
2775 }
2776 return;
2777 }
2778
2779 frac = position - frame;
2780 frm_1 = frm_0 + p->frmInc;
2781 if (p->swapped == 1) {
2782 for (i = 0; i < npartials; i++) {
2783 frm0amp = frm_0[partialloc];
2784 frm0freq = frm_0[partialloc + 1];
2785 frm1amp = frm_1[partialloc];
2786 frm1freq = frm_1[partialloc + 1];
2787
2788 buf[i].amp = frm0amp + frac * (frm1amp - frm0amp); /* calc amplitude */
2789 buf[i].freq = frm0freq + frac * (frm1freq - frm0freq); /* calc freq */
2790 partialloc += p->partialinc; /* get to the next partial */
2791 }
2792 }
2793 else {
2794 for (i = 0; i < npartials; i++) {
2795 /* calc amplitude */
2796 buf[i].amp = frm_0[partialloc]
2797 + frac * (frm_1[partialloc] - frm_0[partialloc]);
2798 /* calc freq */
2799 buf[i].freq = frm_0[partialloc + 1]
2800 + frac * (frm_1[partialloc + 1] - frm_0[partialloc + 1]);
2801 partialloc += p->partialinc; /* get to the next partial */
2802 }
2803 }
2804 }
2805
ScalePartials(CSOUND * csound,ATS_DATA_LOC * cbuf,int32_t cbufnp,MYFLT cbufamp,ATS_DATA_LOC * tbuf,int32_t tbufnp,MYFLT tbufamp,MYFLT kthresh)2806 static void ScalePartials(
2807 CSOUND *csound,
2808 ATS_DATA_LOC *cbuf, /* the current buffer */
2809 int32_t cbufnp, /* the current buffer's number of partials */
2810 MYFLT cbufamp, /* the amplitude for the current buffer */
2811 ATS_DATA_LOC *tbuf, /* the table buffer */
2812 int32_t tbufnp, /* the table buffer's n partials */
2813 MYFLT tbufamp, /* the amp of the table buffer */
2814 MYFLT kthresh )
2815 {
2816 IGN(csound);
2817 MYFLT tempamp; /* hold the cbufn amp for a bit */
2818 MYFLT frac; /* for interpilation */
2819 int32_t i, j=0; /* for the for loop */
2820
2821 for (i = 0; i < cbufnp; i++) {
2822 /* look for closest frequency in buffer */
2823 for(j=0;j < tbufnp; j++) {
2824 if (tbuf[j].freq > cbuf[i].freq)
2825 break;
2826 }
2827 tempamp = FL(0.0);
2828 /* make sure we are not going to overstep our array */
2829 if (LIKELY(j < tbufnp && j > 0)) {
2830 /* interp amplitude from table */
2831 frac =
2832 (cbuf[i].freq - tbuf[j - 1].freq) / (tbuf[j].freq -
2833 tbuf[j - 1].freq);
2834 tempamp = tbuf[j - 1].amp + frac * (tbuf[j].amp - tbuf[j - 1].amp);
2835 }
2836 else if (j == tbufnp) {
2837 /* this means the last value in the table */
2838 /* is equal to a value in the current buffer */
2839 if (cbuf[i + 1].freq == tbuf[tbufnp - 1].freq)
2840 tempamp = tbuf[tbufnp - 1].amp;
2841 }
2842 /* do the actual scaling */
2843
2844 if (i<tbufnp && cbuf[i].amp > kthresh)
2845 cbuf[i].amp = cbuf[i].amp * cbufamp + tempamp*tbufamp;
2846 else cbuf[i].amp *= cbufamp;
2847 }
2848 }
2849
atscross(CSOUND * csound,ATSCROSS * p)2850 static int32_t atscross(CSOUND *csound, ATSCROSS *p)
2851 {
2852 ATSBUFREAD *atsbufreadaddr;
2853 MYFLT frIndx, *oldamps = p->oldamps, a, inca;
2854 MYFLT *ar, amp, fract, v1, *ftab;
2855 FUNC *ftp;
2856 int32 lobits, phase, inc;
2857 double *oscphase;
2858 int32_t i;
2859 uint32_t offset = p->h.insdshead->ksmps_offset;
2860 uint32_t early = p->h.insdshead->ksmps_no_end;
2861 uint32_t n, nsmps = CS_KSMPS;
2862 int32_t numpartials = (int32_t) *p->iptls;
2863 ATS_DATA_LOC *buf;
2864
2865 atsbufreadaddr = *(get_atsbufreadaddrp(csound));
2866 if (UNLIKELY(atsbufreadaddr == NULL)) goto err1;
2867
2868 buf = p->buf;
2869 /* ftp is a pointer to the ftable */
2870 ftp = p->ftp;
2871
2872 /* make sure time pointer is within range */
2873 if (UNLIKELY((frIndx = *(p->ktimpnt) * p->timefrmInc) < FL(0.0))) {
2874 frIndx = FL(0.0);
2875 if (UNLIKELY(p->prFlg)) {
2876 p->prFlg = 0;
2877 csound->Warning(csound, Str("ATSCROSS: only positive time pointer "
2878 "values are allowed, setting to zero\n"));
2879 }
2880 }
2881 else if (OUT_OF_FRAMES) {
2882 /* if we are trying to get frames past where we have data */
2883 frIndx = (MYFLT) p->maxFr;
2884 if (UNLIKELY(p->prFlg)) {
2885 p->prFlg = 0; /* set to false */
2886 csound->Warning(csound, Str("ATSCROSS: time pointer out of range, "
2887 "truncating to last frame\n"));
2888 }
2889 }
2890 else
2891 p->prFlg = 1;
2892
2893 FetchCROSSPartials(p, buf, frIndx);
2894
2895 ScalePartials(csound,
2896 buf, /* the current buffer */
2897 (int32_t) *(p->iptls), /* the current buffer's number of partials */
2898 *(p->kmyamp), /* the amplitude for the current buffer */
2899 atsbufreadaddr->table, /* the table buffer */
2900 (int32_t) *(atsbufreadaddr->iptls), /* the table buffer's n partials */
2901 *p->katsbufamp,
2902 *p->kthresh); /* the amp of the table buffer */
2903
2904 oscphase = p->oscphase;
2905 /* initialise output to zero */
2906 ar = p->aoutput;
2907 memset(ar, 0, nsmps*sizeof(MYFLT));
2908 if (UNLIKELY(early)) nsmps -= early;
2909
2910 for (i = 0; i < numpartials; i++) {
2911 lobits = ftp->lobits;
2912 amp = csound->e0dbfs * (MYFLT) p->buf[i].amp;
2913 phase = MYFLT2LONG (oscphase[i]);
2914 ar = p->aoutput; /* ar is a pointer to the audio output */
2915 inca = (amp-oldamps[i])/nsmps;
2916 /* put in * kfmod */
2917 inc = MYFLT2LONG(p->buf[i].freq * csound->sicvt * *p->kfmod);
2918 a = oldamps[i];
2919 for (n=offset; n<nsmps; n++) {
2920 ftab = ftp->ftable + (phase >> lobits);
2921 v1 = ftab[0];
2922 fract = (MYFLT) PFRAC(phase);
2923 ar[n] += (v1 + fract * (ftab[1] - v1)) * a;
2924 phase += inc;
2925 phase &= PHMASK;
2926 a += inca;
2927 }
2928 oscphase[i] = (double) phase;
2929 oldamps[i] = amp;
2930 //oscphase++;
2931 }
2932 return OK;
2933 err1:
2934 return csound->PerfError(csound, &(p->h),
2935 Str("ATSCROSS: you must have an "
2936 "atsbufread before an atsinterpread"));
2937 }
2938
2939 /* end of ugnorman.c */
2940
2941 #define S(x) sizeof(x)
2942
2943 static OENTRY localops[] = {
2944 { "ATSread", S(ATSREAD), 0, 3, "kk", "kSi",
2945 (SUBR) atsreadset_S, (SUBR) atsread, (SUBR) NULL },
2946 { "ATSread.i", S(ATSREAD), 0, 3, "kk", "kii",
2947 (SUBR) atsreadset, (SUBR) atsread, (SUBR) NULL },
2948 { "ATSreadnz", S(ATSREADNZ), 0, 3, "k", "kSi",
2949 (SUBR) atsreadnzset_S, (SUBR) atsreadnz, (SUBR) NULL },
2950 { "ATSreadnz.i", S(ATSREADNZ), 0, 3, "k", "kii",
2951 (SUBR) atsreadnzset, (SUBR) atsreadnz, (SUBR) NULL },
2952 { "ATSadd", S(ATSADD), TR, 3, "a", "kkSiiopo",
2953 (SUBR) atsaddset_S, (SUBR) atsadd },
2954 { "ATSadd.i", S(ATSADD), TR, 3, "a", "kkiiiopo",
2955 (SUBR) atsaddset, (SUBR) atsadd },
2956 { "ATSaddnz", S(ATSADDNZ), 0, 3, "a", "kSiop",
2957 (SUBR) atsaddnzset_S, (SUBR) atsaddnz },
2958 { "ATSaddnz.i", S(ATSADDNZ), 0, 3, "a", "kiiop",
2959 (SUBR) atsaddnzset, (SUBR) atsaddnz },
2960 { "ATSsinnoi", S(ATSSINNOI), 0,3, "a", "kkkkSiop",
2961 (SUBR) atssinnoiset_S, (SUBR) atssinnoi },
2962 { "ATSsinnoi.i", S(ATSSINNOI), 0,3, "a", "kkkkiiop",
2963 (SUBR) atssinnoiset, (SUBR) atssinnoi },
2964 { "ATSbufread", S(ATSBUFREAD), TW,3, "", "kkSiop",
2965 (SUBR) atsbufreadset_S, (SUBR) atsbufread, (SUBR) NULL },
2966 { "ATSbufread.i", S(ATSBUFREAD), TW,3, "", "kkiiop",
2967 (SUBR) atsbufreadset, (SUBR) atsbufread, (SUBR) NULL },
2968 { "ATSpartialtap", S(ATSPARTIALTAP), 0,3, "kk", "i",
2969 (SUBR) atspartialtapset, (SUBR) atspartialtap, (SUBR) NULL },
2970 { "ATSinterpread", S(ATSINTERPREAD), 0,3, "k", "k",
2971 (SUBR) atsinterpreadset, (SUBR) atsinterpread, (SUBR) NULL },
2972 { "ATScross", S(ATSCROSS), TR, 3, "a", "kkSikkiopoo",
2973 (SUBR) atscrossset_S, (SUBR) atscross },
2974 { "ATSinfo", S(ATSINFO), 0,1, "i", "Si",
2975 (SUBR) atsinfo_S, (SUBR) NULL, (SUBR) NULL },
2976 { "ATScross.i", S(ATSCROSS), TR, 3, "a", "kkiikkiopoo",
2977 (SUBR) atscrossset, (SUBR) atscross },
2978 { "ATSinfo.i", S(ATSINFO), 0,1, "i", "ii",
2979 (SUBR) atsinfo, (SUBR) NULL, (SUBR) NULL }
2980 };
2981
ugnorman_init_(CSOUND * csound)2982 int32_t ugnorman_init_(CSOUND *csound)
2983 {
2984 return csound->AppendOpcodes(csound, &(localops[0]),
2985 (int32_t
2986 ) (sizeof(localops) / sizeof(OENTRY)));
2987 }
2988