1 /*
2 ugens7.c:
3
4 Copyright (C) 1995 J. Michael Clarke, based on ideas from CHANT (IRCAM),
5 Barry Vercoe, John ffitch
6
7 This file is part of Csound.
8
9 The Csound Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
13
14 Csound is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18
19 You should have received a copy of the GNU Lesser General Public
20 License along with Csound; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 02110-1301 USA
23 */
24
25 #include "stdopcod.h" /* UGENS7.C */
26 #include "ugens7.h"
27 #include <math.h>
28
29 /* loosely based on code of Michael Clarke, University of Huddersfield */
30
31 static int32_t newpulse(CSOUND *, FOFS *, OVRLAP *, MYFLT *, MYFLT *, MYFLT *);
32
fofset0(CSOUND * csound,FOFS * p,int32_t flag)33 static int32_t fofset0(CSOUND *csound, FOFS *p, int32_t flag)
34 {
35 int32_t skip = (*p->iskip != FL(0.0) && p->auxch.auxp != 0);
36 if (LIKELY((p->ftp1 = csound->FTFind(csound, p->ifna)) != NULL &&
37 (p->ftp2 = csound->FTFind(csound, p->ifnb)) != NULL)) {
38 OVRLAP *ovp, *nxtovp;
39 int32 olaps;
40 p->durtogo = (int32)(*p->itotdur * CS_ESR);
41 if (!skip) { /* legato: skip all memory management */
42 if (*p->iphs == FL(0.0)) /* if fundphs zero, */
43 p->fundphs = MAXLEN; /* trigger new FOF */
44 else p->fundphs = (int32)(*p->iphs * FMAXLEN) & PHMASK;
45 if (UNLIKELY((olaps = (int32)*p->iolaps) <= 0)) {
46 return csound->InitError(csound, Str("illegal value for iolaps"));
47 }
48 if (*p->iphs >= FL(0.0))
49 csound->AuxAlloc(csound, (size_t)olaps * sizeof(OVRLAP), &p->auxch);
50 ovp = &p->basovrlap;
51 nxtovp = (OVRLAP *) p->auxch.auxp;
52 do {
53 ovp->nxtact = NULL;
54 ovp->nxtfree = nxtovp; /* link the ovlap spaces */
55 ovp = nxtovp++;
56 } while (--olaps);
57 ovp->nxtact = NULL;
58 ovp->nxtfree = NULL;
59 p->fofcount = -1;
60 p->prvband = FL(0.0);
61 p->expamp = FL(1.0);
62 p->prvsmps = (int32)0;
63 p->preamp = FL(1.0);
64 } /* end of legato code */
65 p->ampcod = IS_ASIG_ARG(p->xamp) ? 1 : 0;
66 p->fundcod = IS_ASIG_ARG(p->xfund) ? 1 : 0;
67 p->formcod = IS_ASIG_ARG(p->xform) ? 1 : 0;
68 p->xincod = p->ampcod || p->fundcod || p->formcod;
69 if (flag)
70 p->fmtmod = (*p->ifmode == FL(0.0)) ? 0 : 1;
71 }
72 else return NOTOK;
73 p->foftype = flag;
74 return OK;
75 }
76
fofset(CSOUND * csound,FOFS * p)77 static int32_t fofset(CSOUND *csound, FOFS *p)
78 {
79 return fofset0(csound, p, 1);
80 }
81
fofset2(CSOUND * csound,FOFS * p)82 static int32_t fofset2(CSOUND *csound, FOFS *p)
83 {
84 return fofset0(csound, p, 0);
85 }
86
fof(CSOUND * csound,FOFS * p)87 static int32_t fof(CSOUND *csound, FOFS *p)
88 {
89 OVRLAP *ovp;
90 FUNC *ftp1, *ftp2;
91 MYFLT *ar, *amp, *fund, *form;
92 uint32_t offset = p->h.insdshead->ksmps_offset;
93 uint32_t early = p->h.insdshead->ksmps_no_end;
94 uint32_t n, nsmps = CS_KSMPS;
95 int32 fund_inc, form_inc;
96 MYFLT v1, fract ,*ftab;
97
98 if (UNLIKELY(p->auxch.auxp==NULL)) goto err1; /* RWD fix */
99 ar = p->ar;
100 amp = p->xamp;
101 fund = p->xfund;
102 form = p->xform;
103 ftp1 = p->ftp1;
104 ftp2 = p->ftp2;
105 fund_inc = (int32)(*fund * csound->sicvt);
106 if (UNLIKELY(offset)) memset(ar, '\0', offset*sizeof(MYFLT));
107 if (UNLIKELY(early)) {
108 nsmps -= early;
109 memset(&ar[nsmps], '\0', early*sizeof(MYFLT));
110 }
111 form_inc = (int32)(*form * csound->sicvt);
112 for (n=offset; n<nsmps; n++) {
113 if (p->fundphs & MAXLEN) { /* if phs has wrapped */
114 p->fundphs &= PHMASK;
115 if ((ovp = p->basovrlap.nxtfree) == NULL) goto err2;
116 if (newpulse(csound, p, ovp, amp, fund, form)) { /* init new fof */
117 ovp->nxtact = p->basovrlap.nxtact; /* & link into */
118 p->basovrlap.nxtact = ovp; /* actlist */
119 p->basovrlap.nxtfree = ovp->nxtfree;
120 }
121 }
122 ar[n] = FL(0.0);
123 ovp = &p->basovrlap;
124 while (ovp->nxtact != NULL) { /* perform cur actlist: */
125 MYFLT result;
126 OVRLAP *prvact = ovp;
127 ovp = ovp->nxtact; /* formant waveform */
128 fract = PFRAC1(ovp->formphs); /* from JMC Fog*/
129 ftab = ftp1->ftable + (ovp->formphs >> ftp1->lobits);/*JMC Fog*/
130 v1 = *ftab++; /*JMC Fog*/
131 result = v1 + (*ftab - v1) * fract; /*JMC Fog*/
132 /* result = *(ftp1->ftable + (ovp->formphs >> ftp1->lobits) ); */
133 if (p->foftype) {
134 if (p->fmtmod)
135 ovp->formphs += form_inc; /* inc phs on mode */
136 else ovp->formphs += ovp->forminc;
137 }
138 else {
139 #define kgliss ifmode
140 /* MYFLT ovp->glissbas = kgliss / grain length. ovp->sampct is
141 incremented each sample. We add glissbas * sampct to the
142 pitch of grain at each a-rate pass (ovp->formphs is the
143 index into ifna; ovp->forminc is the stepping factor that
144 decides pitch) */
145 ovp->formphs += (int32)(ovp->forminc + ovp->glissbas * ovp->sampct++);
146 }
147 ovp->formphs &= PHMASK;
148 if (ovp->risphs < MAXLEN) { /* formant ris envlp */
149 result *= *(ftp2->ftable + (ovp->risphs >> ftp2->lobits) );
150 ovp->risphs += ovp->risinc;
151 }
152 if (ovp->timrem <= ovp->dectim) { /* formant dec envlp */
153 result *= *(ftp2->ftable + (ovp->decphs >> ftp2->lobits) );
154 if ((ovp->decphs -= ovp->decinc) < 0)
155 ovp->decphs = 0;
156 }
157 ar[n] += (result * ovp->curamp); /* add wavfrm to out */
158 if (--ovp->timrem) /* if fof not expird */
159 ovp->curamp *= ovp->expamp; /* apply bw exp dec */
160 else {
161 prvact->nxtact = ovp->nxtact; /* else rm frm activ */
162 ovp->nxtfree = p->basovrlap.nxtfree; /* & ret spc to free */
163 p->basovrlap.nxtfree = ovp;
164 ovp = prvact;
165 }
166 }
167 p->fundphs += fund_inc;
168 if (p->xincod) {
169 if (p->ampcod) amp++;
170 if (p->fundcod) fund_inc = (int32)(*++fund * csound->sicvt);
171 if (p->formcod) form_inc = (int32)(*++form * csound->sicvt);
172 }
173 p->durtogo--;
174 }
175 return OK;
176 err1:
177 return csound->PerfError(csound, &(p->h),
178 Str("fof: not initialised"));
179 err2:
180 return csound->PerfError(csound, &(p->h),
181 Str("FOF needs more overlaps"));
182 }
183
newpulse(CSOUND * csound,FOFS * p,OVRLAP * ovp,MYFLT * amp,MYFLT * fund,MYFLT * form)184 static int32_t newpulse(CSOUND *csound,
185 FOFS *p, OVRLAP *ovp, MYFLT *amp, MYFLT *fund, MYFLT *form)
186 {
187 MYFLT octamp = *amp, oct;
188 int32 rismps, newexp = 0;
189
190 if ((ovp->timrem = (int32)(*p->kdur * CS_ESR)) > p->durtogo &&
191 (*p->iskip==FL(0.0))) /* ringtime */
192 return(0);
193 if ((oct = *p->koct) > FL(0.0)) { /* octaviation */
194 int64_t csnt = -1;
195 int32 ioct = (int32)oct, bitpat = ~(csnt << ioct);
196 if (bitpat & ++p->fofcount)
197 return(0);
198 if ((bitpat += 1) & p->fofcount)
199 octamp *= (FL(1.0) + ioct - oct);
200 }
201 if (*fund == FL(0.0)) /* formant phs */
202 ovp->formphs = 0;
203 else ovp->formphs = (int32)(p->fundphs * *form / *fund) & PHMASK;
204 ovp->forminc = (int32)(*form * csound->sicvt);
205 if (*p->kband != p->prvband) { /* bw: exp dec */
206 p->prvband = *p->kband;
207 p->expamp = EXP(*p->kband * csound->mpidsr);
208 newexp = 1;
209 }
210 /* Init grain rise ftable phase. Negative kform values make
211 the kris (ifnb) initial index go negative and crash csound.
212 So insert another if-test with compensating code. */
213 if (*p->kris >= csound->onedsr && *form != FL(0.0)) { /* init fnb ris */
214 if (*form < FL(0.0) && ovp->formphs != 0)
215 ovp->risphs = (int32)((MAXLEN - ovp->formphs) / -*form / *p->kris);
216 else
217 ovp->risphs = (int32)(ovp->formphs / *form / *p->kris);
218 ovp->risinc = (int32)(csound->sicvt / *p->kris);
219 rismps = MAXLEN / ovp->risinc;
220 }
221 else {
222 ovp->risphs = MAXLEN;
223 rismps = 0;
224 }
225 if (newexp || rismps != p->prvsmps) { /* if new params */
226 if ((p->prvsmps = rismps)) /* redo preamp */
227 p->preamp = csound->intpow(p->expamp, -rismps);
228 else p->preamp = FL(1.0);
229 }
230 ovp->curamp = octamp * p->preamp; /* set startamp */
231 ovp->expamp = p->expamp;
232 if ((ovp->dectim = (int32)(*p->kdec * CS_ESR)) > 0) /* fnb dec */
233 ovp->decinc = (int32)(csound->sicvt / *p->kdec);
234 ovp->decphs = PHMASK;
235 if (!p->foftype) {
236 /* Make fof take k-rate phase increment:
237 Add current iphs to initial form phase */
238 ovp->formphs += (int32)(*p->iphs * FMAXLEN); /* krate phs */
239 ovp->formphs &= PHMASK;
240 /* Set up grain gliss increment: ovp->glissbas will be added to
241 ovp->forminc at each pass in fof2. Thus glissbas must be
242 equal to kgliss / grain playing time. Also make it harmonic,
243 so integer kgliss can represent octaves (ie pow() call). */
244 ovp->glissbas = ovp->forminc * (MYFLT)pow(2.0, (double)*p->kgliss);
245 /* glissbas should be diff of start & end pitch*/
246 ovp->glissbas -= ovp->forminc;
247 ovp->glissbas /= ovp->timrem;
248 ovp->sampct = 0; /* Must be reset in case ovp was used before */
249 }
250 return(1);
251 }
252
253 #if 0
254 static int32_t hrngflg=0;
255 #endif
256
harmset(CSOUND * csound,HARMON * p)257 static int32_t harmset(CSOUND *csound, HARMON *p)
258 {
259 MYFLT minfrq = *p->ilowest;
260 if (UNLIKELY(minfrq < FL(64.0))) {
261 return csound->InitError(csound, Str("Minimum frequency too low"));
262 }
263 if (p->auxch.auxp == NULL || minfrq < p->minfrq) {
264 int32 nbufs = (int32)(CS_EKR * FL(3.0) / minfrq) + 1;
265 int32 nbufsmps = nbufs * CS_KSMPS;
266 int32 maxprd = (int32)(CS_ESR / minfrq);
267 int32 totalsiz = nbufsmps * 5 + maxprd; /* Surely 5! not 4 */
268 /* printf("init: nbufs = %d; nbufsmps = %d; maxprd = %d; totalsiz = %d\n", */
269 /* nbufs, nbufsmps, maxprd, totalsiz); */
270 csound->AuxAlloc(csound, (size_t)totalsiz * sizeof(MYFLT), &p->auxch);
271 p->bufp = (MYFLT *) p->auxch.auxp;
272 p->midp = p->bufp + nbufsmps; /* each >= maxprd * 3 */
273 p->bufq = p->midp + nbufsmps;
274 p->midq = p->bufq + nbufsmps;
275 p->autobuf = p->midq + nbufsmps; /* size of maxprd */
276 p->nbufsmps = nbufsmps;
277 p->n2bufsmps = nbufsmps * 2;
278 p->lomaxdist = maxprd;
279 p->minfrq = minfrq;
280 }
281 if ((p->autoktim = (int32_t)/*MYFLT2LONG*/(*p->iptrkprd * CS_EKR)) < 1)
282 p->autoktim = 1;
283 p->autokcnt = 1; /* init for immediate autocorr attempt */
284 printf("ekr = %f iptrk = %f, autocnt = %d; autotim = %d\n",
285 CS_EKR, *p->iptrkprd, p->autokcnt, p->autoktim);
286 p->lsicvt = FL(65536.0) * csound->onedsr;
287 p->cpsmode = ((*p->icpsmode != FL(0.0)));
288 p->inp1 = p->bufp;
289 p->inp2 = p->midp;
290 p->inq1 = p->bufq;
291 p->inq2 = p->midq;
292 p->puls1 = NULL;
293 p->puls2 = NULL;
294 p->puls3 = NULL;
295 p->prvest = FL(0.0);
296 p->prvq = FL(0.0);
297 p->phase1 = 0;
298 p->phase2 = 0;
299 #if 0
300 hrngflg = 0;
301 p->period = -1;
302 #endif
303 return OK;
304 }
305
306 #if 0
307 static int32_t cycle = 0;
308 #endif
harmon(CSOUND * csound,HARMON * p)309 static int32_t harmon(CSOUND *csound, HARMON *p)
310 {
311 MYFLT *src1, *src2, *src3, *inp1, *inp2, *outp;
312 MYFLT c1, c2, qval, *inq1, *inq2;
313 MYFLT sum, minval, *minqp = NULL, *minq1, *minq2, *endp;
314 MYFLT *pulstrt, lin1, lin2, lin3;
315 int32 cnt1, cnt2, cnt3;
316 int32 nn, phase1, phase2, phsinc1, phsinc2, period;
317 uint32_t offset = p->h.insdshead->ksmps_offset;
318 uint32_t early = p->h.insdshead->ksmps_no_end;
319 uint32_t n, nsmps = CS_KSMPS;
320
321 outp = p->ar;
322 #if 0
323 if (early || offset) printf("early=%d, offet=%d\n", early, offset);
324 #endif
325 if (UNLIKELY(offset)) memset(outp, '\0', offset*sizeof(MYFLT));
326 if (UNLIKELY(early)) {
327 nsmps -= early;
328 memset(&outp[nsmps], '\0', early*sizeof(MYFLT));
329 }
330 inp1 = p->inp1;
331 inp2 = p->inp2;
332 inq1 = p->inq1;
333 inq2 = p->inq2;
334 qval = p->prvq;
335 if (*p->kest != p->prvest &&
336 *p->kest != FL(0.0)) { /* if new pitch estimate */
337 MYFLT estperiod = CS_ESR / *p->kest;
338 double b = 2.0 - cos((double)(*p->kest * csound->tpidsr));
339 p->c2 = (MYFLT)(b - sqrt(b*b - 1.0)); /* recalc lopass coefs */
340 p->c1 = FL(1.0) - p->c2;
341 p->prvest = *p->kest;
342 p->estprd = estperiod;
343 p->prvar = FL(0.0);
344 }
345 if (*p->kvar != p->prvar) {
346 MYFLT oneplusvar = FL(1.0) + *p->kvar;
347 /* prd window is prd +/- var int32_t */
348 p->mindist = (int32)(p->estprd/oneplusvar);
349 /* if (p->mindist==0) p->mindist=1; */
350 p->maxdist = (int32)(p->estprd*oneplusvar);
351 if (p->maxdist > p->lomaxdist)
352 p->maxdist = p->lomaxdist;
353 p->max2dist = p->maxdist * 2;
354 p->prvar = *p->kvar;
355 }
356 c1 = p->c1;
357 c2 = p->c2;
358 //printf("cycle %d\n", ++cycle);
359 for (src1 = p->asig, n = offset; n<nsmps; n++) {
360 *inp1++ = *inp2++ = src1[n]; /* dbl store the wavform */
361 //printf("src[%d] = %f\n", n, src1[n]);
362 if (src1[n] > FL(0.0))
363 qval = c1 * src1[n] + c2 * qval; /* & its half-wave rect */
364 else qval = c2 * qval;
365 *inq1++ = *inq2++ = qval;
366 }
367 if (!(--p->autokcnt)) { /* if time for new autocorr */
368 MYFLT *mid1, *mid2, *src4;
369 MYFLT *autop, *maxp;
370 MYFLT dsum, dinv, win, windec, maxval;
371 int32 dist;
372 //printf("AUTOCORRELATE min/max = %d,%d\n",p->mindist, p->maxdist);
373 p->autokcnt = p->autoktim;
374 mid2 = inp2 - p->max2dist;
375 mid1 = mid2 - 1;
376 autop = p->autobuf;
377 for (dist = p->mindist; dist <= p->maxdist; dist++) {
378 dsum = FL(0.0);
379 dinv = FL(1.0) / dist;
380 src1 = mid1; src3 = mid1 + dist;
381 src2 = mid2; src4 = mid2 + dist;
382 for (win = FL(1.0), windec = dinv, nn = dist; nn--; ) {
383 dsum += win * (*src1 * *src3 + *src2 * *src4);
384 //printf("dsum = %f from %f %f %f %f\n", dsum, *src1, *src2, *src3, *src4);
385 src1--; src2++; src3--; src4++;
386 win -= windec;
387 }
388 *autop++ = dsum * dinv;
389 }
390 maxval = FL(0.0);
391 maxp = autop = p->autobuf;
392 endp = autop + p->maxdist - p->mindist;
393 while (autop < endp) {
394 //printf("newval, maxval = %f, %f\n", *autop, maxval);
395 if (*autop > maxval) { /* max autocorr gives new period */
396 maxval = *autop;
397 maxp = autop;
398 #if 0
399 csound->Message(csound, "new maxval %f at %p\n", maxval, (int64_t)maxp);
400 #endif
401 }
402 autop++;
403 }
404 //printf("**** maxval = %f ****\n", maxval);
405 period = p->mindist + maxp - p->autobuf;
406 if (period != p->period) {
407 #if 0
408 csound->Message(csound, "New period %d %d\n", period, p->period);
409 #endif
410 p->period = period;
411 if (!p->cpsmode)
412 p->lsicvt = FL(65536.0) / period;
413 p->pnt1 = (int32)((MYFLT)period * FL(0.2));
414 p->pnt2 = (int32)((MYFLT)period * FL(0.8));
415 p->pnt3 = period;
416 p->inc1 = FL(1.0) / p->pnt1;
417 p->inc2 = FL(1.0) / (period - p->pnt2);
418 }
419 }
420 else period = p->period;
421
422 minval = (MYFLT)HUGE_VAL; /* Suitably large ! */
423 minq2 = inq2 - period; /* srch the qbuf for minima */
424 minq1 = minq2 - period; /* which are 1 period apart */
425 endp = inq2; /* move srch over 1 period */
426 while (minq2 < endp) {
427 if ((sum = *minq1 + *minq2) < minval) {
428 minval = sum;
429 minqp = minq1;
430 }
431 minq1++; minq2++;
432 }
433 src1 = minqp - p->n2bufsmps; /* get src equiv of 1st min */
434 if (period==0) {
435 csound->Warning(csound, Str("Period zero\n"));
436 outp = p->ar;
437 memset(outp, 0, sizeof(MYFLT)*CS_KSMPS);
438 return OK;
439 }
440 while (src1 + CS_KSMPS > inp2) /* if not enough smps presnt */
441 src1 -= period; /* back up 1 prd */
442 pulstrt = src1; /* curr available pulse beg */
443
444 src1 = p->puls1; /* insert pulses into output */
445 src2 = p->puls2;
446 src3 = p->puls3;
447 lin1 = p->lin1;
448 lin2 = p->lin2;
449 lin3 = p->lin3;
450 cnt1 = p->cnt1;
451 cnt2 = p->cnt2;
452 cnt3 = p->cnt3;
453 phase1 = p->phase1;
454 phase2 = p->phase2;
455 phsinc1 = (int32)(*p->kfrq1 * p->lsicvt);
456 phsinc2 = (int32)(*p->kfrq2 * p->lsicvt);
457 for (n=offset; n<nsmps; n++) {
458 MYFLT sum;
459 if (src1 != NULL) {
460 if (++cnt1 < p->pnt11) {
461 sum = *src1++ * lin1;
462 lin1 += p->inc11;
463 }
464 else if (cnt1 <= p->pnt12)
465 sum = *src1++;
466 else if (cnt1 <= p->pnt13) {
467 sum = *src1++ * lin1;
468 lin1 -= p->inc12;
469 }
470 else {
471 sum = FL(0.0);
472 src1 = NULL;
473 }
474 }
475 else sum = FL(0.0);
476 if (src2 != NULL) {
477 if (++cnt2 < p->pnt21) {
478 sum += *src2++ * lin2;
479 lin2 += p->inc21;
480 }
481 else if (cnt2 <= p->pnt22)
482 sum += *src2++;
483 else if (cnt2 <= p->pnt23) {
484 sum += *src2++ * lin2;
485 lin2 -= p->inc22;
486 }
487 else src2 = NULL;
488 }
489 if (src3 != NULL) {
490 if (++cnt3 < p->pnt31) {
491 sum += *src3++ * lin3;
492 lin3 += p->inc31;
493 }
494 else if (cnt3 <= p->pnt32)
495 sum += *src3++;
496 else if (cnt3 <= p->pnt33) {
497 sum += *src3++ * lin3;
498 lin3 -= p->inc32;
499 }
500 else src3 = NULL;
501 }
502 if ((phase1 += phsinc1) & (~0xFFFFL)) { /* 64bit safe! */
503 phase1 &= 0x0000FFFFL;
504 if (src1 == NULL) {
505 src1 = pulstrt;
506 cnt1 = 0;
507 lin1 = p->inc1;
508 p->inc11 = p->inc1;
509 p->inc12 = p->inc2;
510 p->pnt11 = p->pnt1;
511 p->pnt12 = p->pnt2;
512 p->pnt13 = p->pnt3;
513 }
514 else if (src2 == NULL) {
515 src2 = pulstrt;
516 cnt2 = 0;
517 lin2 = p->inc1;
518 p->inc21 = p->inc1;
519 p->inc22 = p->inc2;
520 p->pnt21 = p->pnt1;
521 p->pnt22 = p->pnt2;
522 p->pnt23 = p->pnt3;
523 }
524 else if (src3 == NULL) {
525 src3 = pulstrt;
526 cnt3 = 0;
527 lin3 = p->inc1;
528 p->inc31 = p->inc1;
529 p->inc32 = p->inc2;
530 p->pnt31 = p->pnt1;
531 p->pnt32 = p->pnt2;
532 p->pnt33 = p->pnt3;
533 }
534 #if 0
535 else if (UNLIKELY(++hrngflg > 200)) {
536 csound->Message(csound, Str("harmon out of range...\n"));
537 hrngflg = 0;
538 }
539 #endif
540 }
541 if ((phase2 += phsinc2) & (~0xFFFFL)) {
542 phase2 &= 0x0000FFFFL;
543 if (src1 == NULL) {
544 src1 = pulstrt;
545 cnt1 = 0;
546 lin1 = p->inc1;
547 p->inc11 = p->inc1;
548 p->inc12 = p->inc2;
549 p->pnt11 = p->pnt1;
550 p->pnt12 = p->pnt2;
551 p->pnt13 = p->pnt3;
552 }
553 else if (src2 == NULL) {
554 src2 = pulstrt;
555 cnt2 = 0;
556 lin2 = p->inc1;
557 p->inc21 = p->inc1;
558 p->inc22 = p->inc2;
559 p->pnt21 = p->pnt1;
560 p->pnt22 = p->pnt2;
561 p->pnt23 = p->pnt3;
562 }
563 else if (src3 == NULL) {
564 src3 = pulstrt;
565 cnt3 = 0;
566 lin3 = p->inc1;
567 p->inc31 = p->inc1;
568 p->inc32 = p->inc2;
569 p->pnt31 = p->pnt1;
570 p->pnt32 = p->pnt2;
571 p->pnt33 = p->pnt3;
572 }
573 #if 0
574 else if (UNLIKELY(++hrngflg > 200)) {
575 csound->Message(csound, Str("harmon out of range\n"));
576 hrngflg = 0;
577 }
578 #endif
579 }
580 outp[n] = sum;
581 }
582 if (inp1 >= p->midp) {
583 p->inp1 = p->bufp;
584 p->inp2 = p->midp;
585 p->inq1 = p->bufq;
586 p->inq2 = p->midq;
587 if (src1 != NULL)
588 src1 -= p->nbufsmps;
589 if (src2 != NULL)
590 src2 -= p->nbufsmps;
591 if (src3 != NULL)
592 src3 -= p->nbufsmps;
593 }
594 else {
595 p->inp1 = inp1;
596 p->inp2 = inp2;
597 p->inq1 = inq1;
598 p->inq2 = inq2;
599 }
600 p->puls1 = src1;
601 p->puls2 = src2;
602 p->puls3 = src3;
603 p->lin1 = lin1;
604 p->lin2 = lin2;
605 p->lin3 = lin3;
606 p->cnt1 = cnt1;
607 p->cnt2 = cnt2;
608 p->cnt3 = cnt3;
609 p->phase1 = phase1;
610 p->phase2 = phase2;
611 p->prvq = qval;
612 return OK;
613 }
614
615 #define S(x) sizeof(x)
616
617 static OENTRY localops[] =
618 {
619 { "fof", S(FOFS), TR, 3, "a","xxxkkkkkiiiiooo",(SUBR)fofset,(SUBR)fof },
620 { "fof2", S(FOFS), TR, 3, "a","xxxkkkkkiiiikko",(SUBR)fofset2,(SUBR)fof },
621 { "harmon", S(HARMON), 0,3, "a", "akkkkiii",(SUBR)harmset, (SUBR)harmon }
622 };
623
ugens7_init_(CSOUND * csound)624 int32_t ugens7_init_(CSOUND *csound)
625 {
626 return csound->AppendOpcodes(csound, &(localops[0]),
627 (int32_t) (sizeof(localops) / sizeof(OENTRY)));
628 }
629
630