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