1 /*
2 goto_ops.c:
3
4 Copyright (C) 1991, 1997, 1999, 2002, 2005
5 Barry Vercoe, Istvan Varga, John ffitch,
6 Gabriel Maldonado, matt ingalls
7
8 This file is part of Csound.
9
10 The Csound Library is free software; you can redistribute it
11 and/or modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
14
15 Csound is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with Csound; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 02110-1301 USA
24 */
25
26 #include "csoundCore.h" /* GOTO_OPS.C */
27 #include "insert.h" /* for goto's */
28 #include "aops.h" /* for cond's */
29 extern int32_t strarg2insno(CSOUND *, void *p, int32_t is_string);
30
igoto(CSOUND * csound,GOTO * p)31 int32_t igoto(CSOUND *csound, GOTO *p)
32 {
33 csound->ids = p->lblblk->prvi;
34 return OK;
35 }
36
kgoto(CSOUND * csound,GOTO * p)37 int32_t kgoto(CSOUND *csound, GOTO *p)
38 {
39 IGN(csound);
40 CS_PDS = p->lblblk->prvp;
41 return OK;
42 }
43
icgoto(CSOUND * csound,CGOTO * p)44 int32_t icgoto(CSOUND *csound, CGOTO *p)
45 {
46 if (*p->cond)
47 csound->ids = p->lblblk->prvi;
48 return OK;
49 }
50
kcgoto(CSOUND * csound,CGOTO * p)51 int32_t kcgoto(CSOUND *csound, CGOTO *p)
52 {
53 IGN(csound);
54 if (*p->cond)
55 CS_PDS = p->lblblk->prvp;
56
57 return OK;
58 }
59
60 /* an 'if-then' variant of 'if-goto' */
ingoto(CSOUND * csound,CGOTO * p)61 int32_t ingoto(CSOUND *csound, CGOTO *p)
62 {
63 /* Make sure we have an i-time conditional */
64 if (p->h.optext->t.intype == 'b' && !*p->cond)
65 csound->ids = p->lblblk->prvi;
66 return OK;
67 }
68
kngoto(CSOUND * csound,CGOTO * p)69 int32_t kngoto(CSOUND *csound, CGOTO *p)
70 {
71 IGN(csound);
72 if (!*p->cond)
73 CS_PDS = p->lblblk->prvp;
74 return OK;
75 }
76
timset(CSOUND * csound,TIMOUT * p)77 int32_t timset(CSOUND *csound, TIMOUT *p)
78 {
79 if (UNLIKELY((p->cnt1 = (int32_t)(*p->idel * CS_EKR + FL(0.5))) < 0L ||
80 (p->cnt2 = (int32_t)(*p->idur * CS_EKR + FL(0.5))) < 0L))
81 return csoundInitError(csound, Str("negative time period"));
82 return OK;
83 }
84
timout(CSOUND * csound,TIMOUT * p)85 int32_t timout(CSOUND *csound, TIMOUT *p)
86 {
87 IGN(csound);
88 if (p->cnt1) /* once delay has expired, */
89 p->cnt1--;
90 else if (--p->cnt2 >= 0L) /* br during idur countdown */
91 CS_PDS = p->lblblk->prvp;
92 return OK;
93 }
94
rireturn(CSOUND * csound,LINK * p)95 int32_t rireturn(CSOUND *csound, LINK *p)
96 {
97 IGN(p);
98 IGN(csound);
99 return OK;
100 }
101
reinit(CSOUND * csound,GOTO * p)102 int32_t reinit(CSOUND *csound, GOTO *p)
103 {
104 csound->reinitflag = p->h.insdshead->reinitflag = 1;
105 if (csound->oparms->realtime == 0) {
106 csound->curip = p->h.insdshead;
107 csound->ids = p->lblblk->prvi; /* now, despite ANSI C warning: */
108 while ((csound->ids = csound->ids->nxti) != NULL &&
109 (csound->ids->iopadr != (SUBR) rireturn))
110 (*csound->ids->iopadr)(csound, csound->ids);
111 csound->reinitflag = p->h.insdshead->reinitflag = 0;
112 }
113 else {
114 uint64_t wp = csound->alloc_queue_wp;
115 ATOMIC_SET(p->h.insdshead->init_done, 0);
116 ATOMIC_SET8(p->h.insdshead->actflg, 0);
117 csound->alloc_queue[wp].ip = p->h.insdshead;
118 csound->alloc_queue[wp].ids = p->lblblk->prvi;
119 csound->alloc_queue[wp].type = 3;
120 csound->alloc_queue_wp = wp + 1 < MAX_ALLOC_QUEUE ? wp + 1 : 0;
121 ATOMIC_INCR(csound->alloc_queue_items);
122 return NOTOK;
123 }
124 return OK;
125 }
126
rigoto(CSOUND * csound,GOTO * p)127 int32_t rigoto(CSOUND *csound, GOTO *p)
128 {
129 if (p->h.insdshead->reinitflag)
130 csound->ids = p->lblblk->prvi;
131 return OK;
132 }
133
tigoto(CSOUND * csound,GOTO * p)134 int32_t tigoto(CSOUND *csound, GOTO *p) /* I-time only, NOP at reinit */
135 {
136 if (p->h.insdshead->tieflag && !p->h.insdshead->reinitflag)
137 csound->ids = p->lblblk->prvi;
138 return OK;
139 }
140
tival(CSOUND * csound,EVAL * p)141 int32_t tival(CSOUND *csound, EVAL *p) /* I-time only, NOP at reinit */
142 {
143 IGN(csound);
144 if (!p->h.insdshead->reinitflag)
145 *p->r = p->h.insdshead->tieflag;
146 /* *p->r = (csound->tieflag ? FL(1.0) : FL(0.0)); */
147 return OK;
148 }
149
ihold(CSOUND * csound,LINK * p)150 int32_t ihold(CSOUND *csound, LINK *p) /* make this note indefinit duration */
151 { /* called by ihold statmnt at Itime */
152 IGN(csound);
153 if (!p->h.insdshead->reinitflag) { /* no-op at reinit */
154 csound->curip->offbet = -1.0;
155 csound->curip->offtim = -1.0;
156 }
157 return OK;
158 }
159
turnoff(CSOUND * csound,LINK * p)160 int32_t turnoff(CSOUND *csound, LINK *p)/* terminate the current instrument */
161 { /* called by turnoff statmt at Ptime */
162 IGN(csound);
163 INSDS *current = p->h.insdshead;
164 INSDS *lcurip = p->h.insdshead;
165 if (lcurip->actflg) {
166 /* IV - Oct 16 2002: check for subinstr and user opcode */
167 /* find top level instrument instance */
168 while (lcurip->opcod_iobufs)
169 lcurip = ((OPCOD_IOBUFS*) lcurip->opcod_iobufs)->parent_ip;
170 xturnoff(csound, lcurip);
171 if (current->xtratim <= 0) {
172 OPDS* curOp = current->pds;
173 while (curOp->nxtp != NULL)
174 curOp = curOp->nxtp; /* loop to last opds */
175 current->pds = curOp;
176 }
177 }
178 return OK;
179 }
180
181 /* turnoff2 opcode */
turnoff2(CSOUND * csound,TURNOFF2 * p,int32_t isStringArg)182 int32_t turnoff2(CSOUND *csound, TURNOFF2 *p, int32_t isStringArg)
183 {
184 MYFLT p1;
185 INSDS *ip, *ip2, *nip;
186 int32_t mode, insno, allow_release;
187
188 if (isStringArg) {
189 p1 = (MYFLT) strarg2insno(csound, ((STRINGDAT *)p->kInsNo)->data, 1);
190 }
191 else if (csound->ISSTRCOD(*p->kInsNo)) {
192 p1 = (MYFLT) strarg2insno(csound, get_arg_string(csound, *p->kInsNo), 1);
193 }
194 else p1 = *(p->kInsNo);
195
196 if (p1 <= FL(0.0))
197 return OK; /* not triggered */
198
199 insno = (int32_t) p1;
200 if (UNLIKELY(insno < 1 || insno > (int32_t) csound->engineState.maxinsno ||
201 csound->engineState.instrtxtp[insno] == NULL)) {
202 return csoundPerfError(csound, &(p->h),
203 Str("turnoff2: invalid instrument number"));
204 }
205 mode = (int32_t) (*(p->kFlags) + FL(0.5));
206 allow_release = (*(p->kRelease) == FL(0.0) ? 0 : 1);
207 if (UNLIKELY(mode < 0 || mode > 15 || (mode & 3) == 3)) {
208 return csoundPerfError(csound, &(p->h),
209 Str("turnoff2: invalid mode parameter"));
210 }
211 ip = &(csound->actanchor);
212 ip2 = NULL;
213 /* if ((mode & 4) && !ip->p1){ */
214 /* return csoundPerfError(csound, &(p->h), */
215 /* Str("turnoff2: invalid instrument number")); */
216 /* } */
217 while ((ip = ip->nxtact) != NULL && (int32_t) ip->insno != insno);
218 if (ip == NULL)
219 return OK;
220 do { /* This loop does not terminate in mode=0 */
221 nip = ip->nxtact;
222 if (((mode & 8) && ip->offtim >= 0.0) ||
223 ((mode & 4) && ip->p1.value != p1) ||
224 (allow_release && ip->relesing)) {
225 ip = nip;
226 continue;
227 }
228 if (!(mode & 3)) {
229 if (allow_release) {
230 xturnoff(csound, ip);
231 }
232 else {
233 nip = ip->nxtact;
234 xturnoff_now(csound, ip);
235 }
236 }
237 else {
238 ip2 = ip;
239 if ((mode & 3) == 1)
240 break;
241 }
242 ip = nip;
243 } while (ip != NULL && (int32_t) ip->insno == insno);
244 if (ip2 != NULL) {
245 if (allow_release) {
246 xturnoff(csound, ip2);
247 }
248 else {
249 xturnoff_now(csound, ip2);
250 }
251 }
252 if (!p->h.insdshead->actflg) { /* if current note was deactivated: */
253 while (CS_PDS->nxtp != NULL)
254 CS_PDS = CS_PDS->nxtp; /* loop to last opds */
255 }
256 return OK;
257 }
258
turnoff2S(CSOUND * csound,TURNOFF2 * p)259 int32_t turnoff2S(CSOUND *csound, TURNOFF2 *p){
260 return turnoff2(csound, p, 1);
261 }
262
turnoff2k(CSOUND * csound,TURNOFF2 * p)263 int32_t turnoff2k(CSOUND *csound, TURNOFF2 *p){
264 return turnoff2(csound, p, 0);
265 }
266
loop_l_i(CSOUND * csound,LOOP_OPS * p)267 int32_t loop_l_i(CSOUND *csound, LOOP_OPS *p)
268 {
269 /* if ((indxvar += iincr) < ilimit) igoto l */
270 *(p->ndxvar) += *(p->incr);
271 if (*(p->ndxvar) < *(p->limit))
272 csound->ids = p->l->prvi;
273 return OK;
274 }
275
loop_le_i(CSOUND * csound,LOOP_OPS * p)276 int32_t loop_le_i(CSOUND *csound, LOOP_OPS *p)
277 {
278 /* if ((indxvar += iincr) <= ilimit) igoto l */
279 *(p->ndxvar) += *(p->incr);
280 if (*(p->ndxvar) <= *(p->limit))
281 csound->ids = p->l->prvi;
282 return OK;
283 }
284
loop_g_i(CSOUND * csound,LOOP_OPS * p)285 int32_t loop_g_i(CSOUND *csound, LOOP_OPS *p)
286 {
287 /* if ((indxvar -= idecr) > ilimit) igoto l */
288 *(p->ndxvar) -= *(p->incr);
289 if (*(p->ndxvar) > *(p->limit))
290 csound->ids = p->l->prvi;
291 return OK;
292 }
293
loop_ge_i(CSOUND * csound,LOOP_OPS * p)294 int32_t loop_ge_i(CSOUND *csound, LOOP_OPS *p)
295 {
296 /* if ((indxvar -= idecr) >= ilimit) igoto l */
297 *(p->ndxvar) -= *(p->incr);
298 if (*(p->ndxvar) >= *(p->limit))
299 csound->ids = p->l->prvi;
300 return OK;
301 }
302
loop_l_p(CSOUND * csound,LOOP_OPS * p)303 int32_t loop_l_p(CSOUND *csound, LOOP_OPS *p)
304 {
305 /* if ((kndxvar += kincr) < klimit) kgoto l */
306 IGN(csound);
307 *(p->ndxvar) += *(p->incr);
308 if (*(p->ndxvar) < *(p->limit))
309 CS_PDS = p->l->prvp;
310 return OK;
311 }
312
loop_le_p(CSOUND * csound,LOOP_OPS * p)313 int32_t loop_le_p(CSOUND *csound, LOOP_OPS *p)
314 {
315 /* if ((kndxvar += kincr) <= klimit) kgoto l */
316 IGN(csound);
317 *(p->ndxvar) += *(p->incr);
318 if (*(p->ndxvar) <= *(p->limit))
319 CS_PDS = p->l->prvp;
320 return OK;
321 }
322
loop_g_p(CSOUND * csound,LOOP_OPS * p)323 int32_t loop_g_p(CSOUND *csound, LOOP_OPS *p)
324 {
325 /* if ((kndxvar -= kdecr) > klimit) kgoto l */
326 IGN(csound);
327 *(p->ndxvar) -= *(p->incr);
328 if (*(p->ndxvar) > *(p->limit))
329 CS_PDS = p->l->prvp;
330 return OK;
331 }
332
loop_ge_p(CSOUND * csound,LOOP_OPS * p)333 int32_t loop_ge_p(CSOUND *csound, LOOP_OPS *p)
334 {
335 /* if ((kndxvar -= kdecr) >= klimit) kgoto l */
336 IGN(csound);
337 *(p->ndxvar) -= *(p->incr);
338 if (*(p->ndxvar) >= *(p->limit))
339 CS_PDS = p->l->prvp;
340 return OK;
341 }
342