|
I don't understand what is happening in the simple csd below:
During the init pass, gival is initialized to 0, but instr 2 changes it to 2. Meanwhile, instr 1 correctly evaluates it to 0, falling into the if/then construction (print gival), the condition being true. During the k passes, instr 1, consistently prints (printk) gival as = 2, as you'd expect - since instr 2 changed its value. However, *it should never have fallen into the if/then construction*; as the condition is now false (gival == 2). If the if/then construction is changed to if/goto, the same evaluation error occurs. This, BTW, is all with the old parser, Windows XP, Csound 5.06. (And of course if instruments 1 and 2 are interchanged, all works as expected.) What's going on? Art Hunkins <CsoundSynthesizer> <CsOptions> -odac </CsOptions> <CsInstruments> sr = 44100 kr = 44100 nchnls = 1 gival init 0 instr 1 if gival != 2 then print gival printk .1, gival endif endin instr 2 gival = 2 endin </CsInstruments> <CsScore> i1 0 1 i2 0 1 e </CsScore> </CsoundSynthesizer> Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
The reason is this:
1) if ... then is evaluated at i-time when gival == 0 Since the condition is true, both print statements will be executed. At this stage (initi-pass) only print is executed 2) instr 2 changes the value of gival to 2 at its init-pass 3) the printk statement now runs at performance time and correctly reads the global var value (now 2). NB: if you start instr 1 1-kcycle after instr 2, nothing will print. Victor On 17 Feb 2012, at 20:54, Art Hunkins wrote: > I don't understand what is happening in the simple csd below: > > During the init pass, gival is initialized to 0, but instr 2 changes it to 2. Meanwhile, instr 1 correctly evaluates it to 0, falling into the if/then construction (print gival), the condition being true. > > During the k passes, instr 1, consistently prints (printk) gival as = 2, as you'd expect - since instr 2 changed its value. > > However, *it should never have fallen into the if/then construction*; as the condition is now false (gival == 2). > > If the if/then construction is changed to if/goto, the same evaluation error occurs. > > This, BTW, is all with the old parser, Windows XP, Csound 5.06. (And of course if instruments 1 and 2 are interchanged, all works as expected.) > > What's going on? > > Art Hunkins > > > <CsoundSynthesizer> > <CsOptions> > -odac > </CsOptions> > <CsInstruments> > sr = 44100 > kr = 44100 > nchnls = 1 > gival init 0 > > instr 1 > > if gival != 2 then > print gival > printk .1, gival > endif > endin > > instr 2 > gival = 2 > endin > > </CsInstruments> > > <CsScore> > i1 0 1 > i2 0 1 > > e > </CsScore> > </CsoundSynthesizer> > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe csound" > Dr Victor Lazzarini Senior Lecturer Dept. of Music NUI Maynooth Ireland tel.: +353 1 708 3545 Victor dot Lazzarini AT nuim dot ie Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
Victor,
But the problem is with the if/then branch in instr 1. Since during k-time givar == 2, the branch should be taken and nothing should print. Part of instr 1 during this time (the printk) seems to think givar = 2, while another part (if/then) thinks it is some other value (probably 0?) And, as you point out, when instr 1 starts slightly later than instr 2, the if/then construction acts correctly (realizing that givar ==2) and taking the branch. Why it/then works correctly with the delay, but not with a simultaneous start, remains a mystery to me. Art Hunkins ----- Original Message ----- From: "Victor Lazzarini" <[hidden email]> To: <[hidden email]> Sent: Friday, February 17, 2012 4:24 PM Subject: Re: [Csnd] gi variable evaluation? The reason is this: 1) if ... then is evaluated at i-time when gival == 0 Since the condition is true, both print statements will be executed. At this stage (initi-pass) only print is executed 2) instr 2 changes the value of gival to 2 at its init-pass 3) the printk statement now runs at performance time and correctly reads the global var value (now 2). NB: if you start instr 1 1-kcycle after instr 2, nothing will print. Victor On 17 Feb 2012, at 20:54, Art Hunkins wrote: > I don't understand what is happening in the simple csd below: > > During the init pass, gival is initialized to 0, but instr 2 changes it to > 2. Meanwhile, instr 1 correctly evaluates it to 0, falling into the > if/then construction (print gival), the condition being true. > > During the k passes, instr 1, consistently prints (printk) gival as = 2, > as you'd expect - since instr 2 changed its value. > > However, *it should never have fallen into the if/then construction*; as > the condition is now false (gival == 2). > > If the if/then construction is changed to if/goto, the same evaluation > error occurs. > > This, BTW, is all with the old parser, Windows XP, Csound 5.06. (And of > course if instruments 1 and 2 are interchanged, all works as expected.) > > What's going on? > > Art Hunkins > > > <CsoundSynthesizer> > <CsOptions> > -odac > </CsOptions> > <CsInstruments> > sr = 44100 > kr = 44100 > nchnls = 1 > gival init 0 > > instr 1 > > if gival != 2 then > print gival > printk .1, gival > endif > endin > > instr 2 > gival = 2 > endin > > </CsInstruments> > > <CsScore> > i1 0 1 > i2 0 1 > > e > </CsScore> > </CsoundSynthesizer> > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > Dr Victor Lazzarini Senior Lecturer Dept. of Music NUI Maynooth Ireland tel.: +353 1 708 3545 Victor dot Lazzarini AT nuim dot ie Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" = Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
Hi Art,
The reason Victor gave is correct, but may require more explanation. On the whole, one should not ever mix i-time if-then's with any k-rate code within it, as it will lead to this exact situation. When an i-time if-then is evaluated, it is *only* evaluated at i-time. At performance time, Csound essentially goes right through. If-thens are syntax sugar, and Csound will unroll it as an if-goto with labels. Also to note, while we may look at Csound code as having branches, internally it is not a tree but a flat list of opcodes, with labels used for jumping. So imagine this: if (ival != 2) then printk kval endif becomes: #b0 = (ival == 2) cigoto #b0, __label0 printk kval __label0: On the i-time pass, Csound goes through each opcode one-by-one. It will hit that cigoto (I think that's the opcode that gets put in) at that time and then proceed to the label. The printk doesn't happen, but that's expected as it is supposed to print at performance time. At performance time, the cigoto does nothing because it is an i-time only opcode, and csound then proceeds to the printk and calls it's performance function. Even though logically you'll think "but ival is equal to 0," it is only evaluated at that first pass. This is why one should never mix k-rate code within i-time if-then's. The solution is to cast an i-var to k-rate, to force k-rate comparison, or use if-kgoto. (I would need to check about if-kgoto...). Also, the danger in putting in k-rate code within the loop is that i-time it *does* jump, and therefore your opcodes don't get their init-functions called. If they later get called during performance time, those opcodes won't be initialized and you'll get unexpected results. To simplify then, one should always follow the rule that when using if-then, always match up the code within the if-then with the rate of the value used within the if comparison. In general, it becomes pretty natural once you follow the rule. There is one case where there is some weird things going on, which is when you recursively call UDO's and want to limit the number at i-time as well as number called during performance time. It's an edge case though and likely not many people have run into it, but you essentially have to use two sets of if-then's, one at i-time and another at k-time. Hopefully that should explain the issue! steven On Fri, Feb 17, 2012 at 10:17 PM, Art Hunkins <[hidden email]> wrote: > Victor, > > But the problem is with the if/then branch in instr 1. Since during k-time > givar == 2, the branch should be taken and nothing should print. Part of > instr 1 during this time (the printk) seems to think givar = 2, while > another part (if/then) thinks it is some other value (probably 0?) > > And, as you point out, when instr 1 starts slightly later than instr 2, the > if/then construction acts correctly (realizing that givar ==2) and taking > the branch. Why it/then works correctly with the delay, but not with a > simultaneous start, remains a mystery to me. > > Art Hunkins > > ----- Original Message ----- From: "Victor Lazzarini" > <[hidden email]> > To: <[hidden email]> > Sent: Friday, February 17, 2012 4:24 PM > Subject: Re: [Csnd] gi variable evaluation? > > > > The reason is this: > > 1) if ... then is evaluated at i-time when gival == 0 > Since the condition is true, both print statements will be executed. At this > stage (initi-pass) only print is executed > > 2) instr 2 changes the value of gival to 2 at its init-pass > > 3) the printk statement now runs at performance time and correctly reads the > global var value (now 2). > > NB: if you start instr 1 1-kcycle after instr 2, nothing will print. > > Victor > On 17 Feb 2012, at 20:54, Art Hunkins wrote: > >> I don't understand what is happening in the simple csd below: >> >> During the init pass, gival is initialized to 0, but instr 2 changes it to >> 2. Meanwhile, instr 1 correctly evaluates it to 0, falling into the if/then >> construction (print gival), the condition being true. >> >> During the k passes, instr 1, consistently prints (printk) gival as = 2, >> as you'd expect - since instr 2 changed its value. >> >> However, *it should never have fallen into the if/then construction*; as >> the condition is now false (gival == 2). >> >> If the if/then construction is changed to if/goto, the same evaluation >> error occurs. >> >> This, BTW, is all with the old parser, Windows XP, Csound 5.06. (And of >> course if instruments 1 and 2 are interchanged, all works as expected.) >> >> What's going on? >> >> Art Hunkins >> >> >> <CsoundSynthesizer> >> <CsOptions> >> -odac >> </CsOptions> >> <CsInstruments> >> sr = 44100 >> kr = 44100 >> nchnls = 1 >> gival init 0 >> >> instr 1 >> >> if gival != 2 then >> print gival >> printk .1, gival >> endif >> endin >> >> instr 2 >> gival = 2 >> endin >> >> </CsInstruments> >> >> <CsScore> >> i1 0 1 >> i2 0 1 >> >> e >> </CsScore> >> </CsoundSynthesizer> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here >> To unsubscribe, send email [hidden email] with body "unsubscribe >> csound" >> > > Dr Victor Lazzarini > Senior Lecturer > Dept. of Music > NUI Maynooth Ireland > tel.: +353 1 708 3545 > Victor dot Lazzarini AT nuim dot ie > > > > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > > = > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
That's going straight into my next class!
On Friday, 17 February 2012, Steven Yi <[hidden email]> wrote: > Hi Art, > > The reason Victor gave is correct, but may require more explanation. > On the whole, one should not ever mix i-time if-then's with any k-rate > code within it, as it will lead to this exact situation. > > When an i-time if-then is evaluated, it is *only* evaluated at i-time. > At performance time, Csound essentially goes right through. If-thens > are syntax sugar, and Csound will unroll it as an if-goto with labels. > Also to note, while we may look at Csound code as having branches, > internally it is not a tree but a flat list of opcodes, with labels > used for jumping. So imagine this: > > if (ival != 2) then > printk kval > endif > > becomes: > #b0 = (ival == 2) > cigoto #b0, __label0 > printk kval > __label0: > > > On the i-time pass, Csound goes through each opcode one-by-one. It > will hit that cigoto (I think that's the opcode that gets put in) at > that time and then proceed to the label. The printk doesn't happen, > but that's expected as it is supposed to print at performance time. > At performance time, the cigoto does nothing because it is an i-time > only opcode, and csound then proceeds to the printk and calls it's > performance function. Even though logically you'll think "but ival is > equal to 0," it is only evaluated at that first pass. > > This is why one should never mix k-rate code within i-time if-then's. > The solution is to cast an i-var to k-rate, to force k-rate > comparison, or use if-kgoto. (I would need to check about > if-kgoto...). Also, the danger in putting in k-rate code within the > loop is that i-time it *does* jump, and therefore your opcodes don't > get their init-functions called. If they later get called during > performance time, those opcodes won't be initialized and you'll get > unexpected results. > > To simplify then, one should always follow the rule that when using > if-then, always match up the code within the if-then with the rate of > the value used within the if comparison. In general, it becomes > pretty natural once you follow the rule. > > There is one case where there is some weird things going on, which is > when you recursively call UDO's and want to limit the number at i-time > as well as number called during performance time. It's an edge case > though and likely not many people have run into it, but you > essentially have to use two sets of if-then's, one at i-time and > another at k-time. > > Hopefully that should explain the issue! > steven > > > > On Fri, Feb 17, 2012 at 10:17 PM, Art Hunkins <[hidden email]> wrote: >> Victor, >> >> But the problem is with the if/then branch in instr 1. Since during k-time >> givar == 2, the branch should be taken and nothing should print. Part of >> instr 1 during this time (the printk) seems to think givar = 2, while >> another part (if/then) thinks it is some other value (probably 0?) >> >> And, as you point out, when instr 1 starts slightly later than instr 2, the >> if/then construction acts correctly (realizing that givar ==2) and taking >> the branch. Why it/then works correctly with the delay, but not with a >> simultaneous start, remains a mystery to me. >> >> Art Hunkins >> >> ----- Original Message ----- From: "Victor Lazzarini" >> <[hidden email]> >> To: <[hidden email]> >> Sent: Friday, February 17, 2012 4:24 PM >> Subject: Re: [Csnd] gi variable evaluation? >> >> >> >> The reason is this: >> >> 1) if ... then is evaluated at i-time when gival == 0 >> Since the condition is true, both print statements will be executed. At this >> stage (initi-pass) only print is executed >> >> 2) instr 2 changes the value of gival to 2 at its init-pass >> >> 3) the printk statement now runs at performance time and correctly reads the >> global var value (now 2). >> >> NB: if you start instr 1 1-kcycle after instr 2, nothing will print. >> >> Victor >> On 17 Feb 2012, at 20:54, Art Hunkins wrote: >> >>> I don't understand what is happening in the simple csd below: >>> >>> During the init pass, gival is initialized to 0, but instr 2 changes it to >>> 2. Meanwhile, instr 1 correctly evaluates it to 0, falling into the if/then >>> construction (print gival), the condition being true. >>> >>> During the k passes, instr 1, consistently prints (printk) gival as = 2, >>> as you'd expect - since instr 2 changed its value. >>> >>> However, *it should never have fallen into the if/then construction*; as >>> the condition is now false (gival == 2). >>> >>> If the if/then construction is changed to if/goto, the same evaluation >>> error occurs. >>> >>> This, BTW, is all with the old parser, Windows XP, Csound 5.06. (And of >>> course if instruments 1 and 2 are interchanged, all works as expected.) >>> >>> What's going on? >>> >>> Art Hunkins >>> >>> >>> <CsoundSynthesizer> >>> <CsOptions> >>> -odac >>> </CsOptions> >>> <CsInstruments> >>> sr = 44100 >>> kr = 44100 >>> nchnls = 1 >>> gival init 0 >>> >>> instr 1 >>> >>> if gival != 2 then >>> print gival >>> printk .1, gival >>> endif >>> endin >>> >>> instr 2 >>> gival = 2 >>> endin >>> >>> </CsInstruments> >>> >>> <CsScore> >>> i1 0 1 >>> i2 0 1 >>> >>> e >>> </CsScore> >>> </CsoundSynthesizer> >>> >>> >>> Send bugs reports to the Sourceforge bug tracker >>> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >>> Discussions of bugs and features can be posted here >>> To unsubscribe, send email [hidden email] with body "unsubscribe >>> csound" >>> >> >> Dr Victor Lazzarini >> Senior Lecturer >> Dept. of Music >> NUI Maynooth Ireland >> tel.: +353 1 708 3545 >> Victor dot Lazzarini AT nuim dot ie >> >> >> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features |
|
In reply to this post by Steven Yi
steven:
if this is how it works now, then this is a change from the original implementation. if/then is supposed to be the equivalent to if/goto and as should do the conditional at BOTH i and k rates. On Feb 17, 2012, at 2:33 PM, Steven Yi wrote: > if (ival != 2) then > printk kval > endif > > becomes: > #b0 = (ival == 2) > cigoto #b0, __label0 > printk kval > __label0: Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
and just to clarify a bit more, i think this is
how it should work (at least how it used to) ival init 0 if (ival != 0) then ; never gets here at i or k passes endif if (kval == kotherval) then ; always here at i-pass ; could be here or not at k-pass depending on conditional endif if (xval) ithen ; here during the i-pass (if conditional was true) ; never here during k-pass endif On Feb 17, 2012, at 3:47 PM, matt ingalls wrote: > steven: > if this is how it works now, then > this is a change from the original implementation. > > if/then is supposed to be the equivalent to if/goto > and as should do the conditional at BOTH i and k rates. > > > > On Feb 17, 2012, at 2:33 PM, Steven Yi wrote: > >> if (ival != 2) then >> printk kval >> endif >> >> becomes: >> #b0 = (ival == 2) >> cigoto #b0, __label0 >> printk kval >> __label0: > > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
Hmm, interesting! I think I had either looked at this before, forgot
it, and remembered something wrong, or maybe just had it wrong in my head all this time, and the side effect was that it got me the right results. (!!) I went and looked at the code. In the old parser, if-then uses cngoto, and if-ithen uses cogoto. In the new parser, it looks like it is only using cngoto (that's a bug that should be fixed...). So, Matt's correct and the current Csound *does* what he says. However, I think I do understand what is going on with Art's situation. The value that is compared on the first pass is cached as a boolean on that init-pass. At that time, the value evaluated to false, and that is stored in a synthetic b variable. So going back to the translated code: #b0 = (ival == 2) cngoto #b0, __label0 printk kval __label0: That #b0 stores the initial comparison. Therefore, if it's true or false at init-time, it's going to stay that way through performance-time. If the gival changes, it won't affect the value used in the conditional check. This is great that you chimed in Matt, thanks! Now I've got it clearer in my head. (Rory: You may want to revise what you present! :P) steven On Fri, Feb 17, 2012 at 11:58 PM, matt ingalls <[hidden email]> wrote: > and just to clarify a bit more, i think this is > how it should work (at least how it used to) > > ival init 0 > if (ival != 0) then > ; never gets here at i or k passes > endif > > if (kval == kotherval) then > ; always here at i-pass > ; could be here or not at k-pass depending on conditional > endif > > if (xval) ithen > ; here during the i-pass (if conditional was true) > ; never here during k-pass > endif > > On Feb 17, 2012, at 3:47 PM, matt ingalls wrote: > >> steven: >> if this is how it works now, then >> this is a change from the original implementation. >> >> if/then is supposed to be the equivalent to if/goto >> and as should do the conditional at BOTH i and k rates. >> >> >> >> On Feb 17, 2012, at 2:33 PM, Steven Yi wrote: >> >>> if (ival != 2) then >>> printk kval >>> endif >>> >>> becomes: >>> #b0 = (ival == 2) >>> cigoto #b0, __label0 >>> printk kval >>> __label0: >> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here >> To unsubscribe, send email [hidden email] with body "unsubscribe csound" >> > > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
I'm beginning to understand.
It looks like you have to watch out for if/then's as much as for if/goto's. (I was led to believe that if/then's were much "safer.") There is one further complicating factor: even if instr 1 starts a bit *later* than instr 2, the if comparison in instr 1 still evaluates to 0 (or something other than 2) - executing the then condition. It must have to do with the global variable (givar) being evaluated at *orch* initialization rather than at instrument initialization time. I gather that orch initialization is done by instrument number order rather than start time. Does this make sense? Art Hunkins ----- Original Message ----- From: "Steven Yi" <[hidden email]> To: <[hidden email]> Sent: Friday, February 17, 2012 8:13 PM Subject: Re: [Csnd] gi variable evaluation? Hmm, interesting! I think I had either looked at this before, forgot it, and remembered something wrong, or maybe just had it wrong in my head all this time, and the side effect was that it got me the right results. (!!) I went and looked at the code. In the old parser, if-then uses cngoto, and if-ithen uses cogoto. In the new parser, it looks like it is only using cngoto (that's a bug that should be fixed...). So, Matt's correct and the current Csound *does* what he says. However, I think I do understand what is going on with Art's situation. The value that is compared on the first pass is cached as a boolean on that init-pass. At that time, the value evaluated to false, and that is stored in a synthetic b variable. So going back to the translated code: #b0 = (ival == 2) cngoto #b0, __label0 printk kval __label0: That #b0 stores the initial comparison. Therefore, if it's true or false at init-time, it's going to stay that way through performance-time. If the gival changes, it won't affect the value used in the conditional check. This is great that you chimed in Matt, thanks! Now I've got it clearer in my head. (Rory: You may want to revise what you present! :P) steven On Fri, Feb 17, 2012 at 11:58 PM, matt ingalls <[hidden email]> wrote: > and just to clarify a bit more, i think this is > how it should work (at least how it used to) > > ival init 0 > if (ival != 0) then > ; never gets here at i or k passes > endif > > if (kval == kotherval) then > ; always here at i-pass > ; could be here or not at k-pass depending on conditional > endif > > if (xval) ithen > ; here during the i-pass (if conditional was true) > ; never here during k-pass > endif > > On Feb 17, 2012, at 3:47 PM, matt ingalls wrote: > >> steven: >> if this is how it works now, then >> this is a change from the original implementation. >> >> if/then is supposed to be the equivalent to if/goto >> and as should do the conditional at BOTH i and k rates. >> >> >> >> On Feb 17, 2012, at 2:33 PM, Steven Yi wrote: >> >>> if (ival != 2) then >>> printk kval >>> endif >>> >>> becomes: >>> #b0 = (ival == 2) >>> cigoto #b0, __label0 >>> printk kval >>> __label0: >> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here >> To unsubscribe, send email [hidden email] with body "unsubscribe >> csound" >> > > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" = Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
In reply to this post by Steven Yi
Steven,
Just to clarify one thing: the *only* reason why I placed a k-rate opcode within my i-rate if/then was because i needed to see the value of givar within the loop, i.e., to see how if/then was working. Indeed, it showed that the condition was not being evaluated as I wanted. I'm trying to spawn an event on the "then" condition, without much luck. I'll probably need to use schedkwhen with a trigger mechanism instead. Thanks to all for your helpful comments. Art Hunkins ----- Original Message ----- From: "Steven Yi" <[hidden email]> To: <[hidden email]> Sent: Friday, February 17, 2012 5:33 PM Subject: Re: [Csnd] gi variable evaluation? Hi Art, The reason Victor gave is correct, but may require more explanation. On the whole, one should not ever mix i-time if-then's with any k-rate code within it, as it will lead to this exact situation. When an i-time if-then is evaluated, it is *only* evaluated at i-time. At performance time, Csound essentially goes right through. If-thens are syntax sugar, and Csound will unroll it as an if-goto with labels. Also to note, while we may look at Csound code as having branches, internally it is not a tree but a flat list of opcodes, with labels used for jumping. So imagine this: if (ival != 2) then printk kval endif becomes: #b0 = (ival == 2) cigoto #b0, __label0 printk kval __label0: On the i-time pass, Csound goes through each opcode one-by-one. It will hit that cigoto (I think that's the opcode that gets put in) at that time and then proceed to the label. The printk doesn't happen, but that's expected as it is supposed to print at performance time. At performance time, the cigoto does nothing because it is an i-time only opcode, and csound then proceeds to the printk and calls it's performance function. Even though logically you'll think "but ival is equal to 0," it is only evaluated at that first pass. This is why one should never mix k-rate code within i-time if-then's. The solution is to cast an i-var to k-rate, to force k-rate comparison, or use if-kgoto. (I would need to check about if-kgoto...). Also, the danger in putting in k-rate code within the loop is that i-time it *does* jump, and therefore your opcodes don't get their init-functions called. If they later get called during performance time, those opcodes won't be initialized and you'll get unexpected results. To simplify then, one should always follow the rule that when using if-then, always match up the code within the if-then with the rate of the value used within the if comparison. In general, it becomes pretty natural once you follow the rule. There is one case where there is some weird things going on, which is when you recursively call UDO's and want to limit the number at i-time as well as number called during performance time. It's an edge case though and likely not many people have run into it, but you essentially have to use two sets of if-then's, one at i-time and another at k-time. Hopefully that should explain the issue! steven On Fri, Feb 17, 2012 at 10:17 PM, Art Hunkins <[hidden email]> wrote: > Victor, > > But the problem is with the if/then branch in instr 1. Since during k-time > givar == 2, the branch should be taken and nothing should print. Part of > instr 1 during this time (the printk) seems to think givar = 2, while > another part (if/then) thinks it is some other value (probably 0?) > > And, as you point out, when instr 1 starts slightly later than instr 2, > the > if/then construction acts correctly (realizing that givar ==2) and taking > the branch. Why it/then works correctly with the delay, but not with a > simultaneous start, remains a mystery to me. > > Art Hunkins > > ----- Original Message ----- From: "Victor Lazzarini" > <[hidden email]> > To: <[hidden email]> > Sent: Friday, February 17, 2012 4:24 PM > Subject: Re: [Csnd] gi variable evaluation? > > > > The reason is this: > > 1) if ... then is evaluated at i-time when gival == 0 > Since the condition is true, both print statements will be executed. At > this > stage (initi-pass) only print is executed > > 2) instr 2 changes the value of gival to 2 at its init-pass > > 3) the printk statement now runs at performance time and correctly reads > the > global var value (now 2). > > NB: if you start instr 1 1-kcycle after instr 2, nothing will print. > > Victor > On 17 Feb 2012, at 20:54, Art Hunkins wrote: > >> I don't understand what is happening in the simple csd below: >> >> During the init pass, gival is initialized to 0, but instr 2 changes it >> to >> 2. Meanwhile, instr 1 correctly evaluates it to 0, falling into the >> if/then >> construction (print gival), the condition being true. >> >> During the k passes, instr 1, consistently prints (printk) gival as = 2, >> as you'd expect - since instr 2 changed its value. >> >> However, *it should never have fallen into the if/then construction*; as >> the condition is now false (gival == 2). >> >> If the if/then construction is changed to if/goto, the same evaluation >> error occurs. >> >> This, BTW, is all with the old parser, Windows XP, Csound 5.06. (And of >> course if instruments 1 and 2 are interchanged, all works as expected.) >> >> What's going on? >> >> Art Hunkins >> >> >> <CsoundSynthesizer> >> <CsOptions> >> -odac >> </CsOptions> >> <CsInstruments> >> sr = 44100 >> kr = 44100 >> nchnls = 1 >> gival init 0 >> >> instr 1 >> >> if gival != 2 then >> print gival >> printk .1, gival >> endif >> endin >> >> instr 2 >> gival = 2 >> endin >> >> </CsInstruments> >> >> <CsScore> >> i1 0 1 >> i2 0 1 >> >> e >> </CsScore> >> </CsoundSynthesizer> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here >> To unsubscribe, send email [hidden email] with body "unsubscribe >> csound" >> > > Dr Victor Lazzarini > Senior Lecturer > Dept. of Music > NUI Maynooth Ireland > tel.: +353 1 708 3545 > Victor dot Lazzarini AT nuim dot ie > > > > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > > = > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" = Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
In reply to this post by abhunkin
hi art -
you did really start an interesting thread ... i can't confirm that "even if instr 1 starts a bit *later* than instr 2, the if comparison in instr 1 still evaluates to 0 (or something other than 2) - executing the then condition" (see below, case 3). i think there are three cases. i have simplified your instrument slightly to this form: <CsoundSynthesizer> <CsInstruments> gival init 0 instr 1 if gival != 2 then printk .5, gival endif print gival endin instr 2 gival = 2 endin </CsInstruments> <CsScore> i1 0 1 i2 0 1 e </CsScore> </CsoundSynthesizer> CASE 1 running the csd as here (or in your original post) evaluates the condition 'gival != 2' as true. so the gate to the 'then' statement is open, both: at the initialization path and at the performance time. the change of gival in instr 2 has no effect to this, because it's "too late" now. but it changes the value of gival from 0 to 2, so this will be printed during performance time in instr 1 via printk. (printk will ask for the actual value of gival at its printing time, not for the first value ever been there.) my output: instr 1: gival = 0.000 new alloc for instr 2: i 1 time 0.00023: 2.00000 i 1 time 0.50000: 2.00000 i 1 time 1.00000: 2.00000 CASE 2 changing the instrument numbers (instr 1 becomes instr 2 and vice versa) performs the statement 'gival = 2' first, because it now has the lower instrument number. so the if-condition is false, the gate stays closed, and the printk is not evaluated at all. this is my output: new alloc for instr 1: new alloc for instr 2: instr 2: gival = 2.000 CASE 3 going back to the original numbering of instr 1 and instr 2 (as in the csd above), but now starting instr 1 after instr 2 (at least one k-cycle after instr 2, for instance 0.001). now instr 2 can change gival to 2, so when instr 1 starts, the expression 'gival != 2' is false, and the printk statement is not evaluated at all. this is my printout: new alloc for instr 2: B 0.000 .. 0.001 T 0.001 TT 0.001 M: 0.0 new alloc for instr 1: instr 1: gival = 2.000 B 0.001 .. 1.000 T 1.000 TT 1.000 M: 0.0 B 1.000 .. 1.001 T 1.001 TT 1.001 M: 0.0 this is with the old parser (csound 5.16). i get the same result with the new parser. so, no bug / incompatibility, steven?! thanks, matt, for the condensed overview. i never ever used ithen, but it might be very useful in certain cases. joachim Am 18.02.2012 03:13, schrieb Art Hunkins: > I'm beginning to understand. > > It looks like you have to watch out for if/then's as much as for > if/goto's. (I was led to believe that if/then's were much "safer.") > > There is one further complicating factor: even if instr 1 starts a > bit *later* than instr 2, the if comparison in instr 1 still > evaluates to 0 (or something other than 2) - executing the then > condition. > > It must have to do with the global variable (givar) being evaluated > at *orch* initialization rather than at instrument initialization > time. I gather that orch initialization is done by instrument number > order rather than start time. > > Does this make sense? > > Art Hunkins > > ----- Original Message ----- From: "Steven Yi" <[hidden email]> > To: <[hidden email]> Sent: Friday, February 17, 2012 8:13 > PM Subject: Re: [Csnd] gi variable evaluation? > > > Hmm, interesting! I think I had either looked at this before, > forgot it, and remembered something wrong, or maybe just had it wrong > in my head all this time, and the side effect was that it got me the > right results. (!!) I went and looked at the code. In the old > parser, if-then uses cngoto, and if-ithen uses cogoto. In the new > parser, it looks like it is only using cngoto (that's a bug that > should be fixed...). > > So, Matt's correct and the current Csound *does* what he says. > > However, I think I do understand what is going on with Art's > situation. The value that is compared on the first pass is cached > as a boolean on that init-pass. At that time, the value evaluated > to false, and that is stored in a synthetic b variable. So going > back to the translated code: > > #b0 = (ival == 2) cngoto #b0, __label0 printk kval __label0: > > That #b0 stores the initial comparison. Therefore, if it's true or > false at init-time, it's going to stay that way through > performance-time. If the gival changes, it won't affect the value > used in the conditional check. > > This is great that you chimed in Matt, thanks! Now I've got it > clearer in my head. > > (Rory: You may want to revise what you present! :P) > > steven > > > On Fri, Feb 17, 2012 at 11:58 PM, matt ingalls <[hidden email]> > wrote: >> and just to clarify a bit more, i think this is how it should work >> (at least how it used to) >> >> ival init 0 if (ival != 0) then ; never gets here at i or k passes >> endif >> >> if (kval == kotherval) then ; always here at i-pass ; could be here >> or not at k-pass depending on conditional endif >> >> if (xval) ithen ; here during the i-pass (if conditional was true) >> ; never here during k-pass endif >> >> On Feb 17, 2012, at 3:47 PM, matt ingalls wrote: >> >>> steven: if this is how it works now, then this is a change from >>> the original implementation. >>> >>> if/then is supposed to be the equivalent to if/goto and as should >>> do the conditional at BOTH i and k rates. >>> >>> >>> >>> On Feb 17, 2012, at 2:33 PM, Steven Yi wrote: >>> >>>> if (ival != 2) then printk kval endif >>>> >>>> becomes: #b0 = (ival == 2) cigoto #b0, __label0 printk kval >>>> __label0: >>> >>> >>> >>> Send bugs reports to the Sourceforge bug tracker >>> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >>> Discussions of bugs and features can be posted here To >>> unsubscribe, send email [hidden email] with body >>> "unsubscribe csound" >>> >> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here To unsubscribe, >> send email [hidden email] with body "unsubscribe csound" >> > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here To unsubscribe, > send email [hidden email] with body "unsubscribe csound" > > = > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here To unsubscribe, > send email [hidden email] with body "unsubscribe csound" > > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
In reply to this post by Steven Yi
On Feb 17, 2012, at 5:13 PM, Steven Yi wrote: > and if-ithen uses cogoto. In the new parser, it > looks like it is only using cngoto (that's a bug that should be > fixed...). im not exactly sure what cogoto does, but it occurs to me i was wrong about 'ithen' it probably should work the same as an if/goto with an i-pass conditional, but ALWAYS do the conditional at the i-pass, even if there are k-rate variables, so that: instr 1 kvar init 1 if (kvar == 1) ithen ; goes here at i and k passes endif if (kvar == 0) ithen ; never goes here endif if (kvar == 0) then ; goes here at i-pass ; doesnt go here at k-pass (unless we add code that changes kvar to 0 in some k-pass) endif endin Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
cogoto does pretty much what you were saying, always evaluating at
i-time regardless of if it is a k-var in the expression. On Sat, Feb 18, 2012 at 6:23 PM, matt ingalls <[hidden email]> wrote: > > On Feb 17, 2012, at 5:13 PM, Steven Yi wrote: > >> and if-ithen uses cogoto. In the new parser, it >> looks like it is only using cngoto (that's a bug that should be >> fixed...). > > im not exactly sure what cogoto does, but it occurs to me i was wrong about 'ithen' > it probably should work the same as an if/goto with an i-pass conditional, but ALWAYS do the conditional > at the i-pass, even if there are k-rate variables, so that: > > instr 1 > > kvar init 1 > > if (kvar == 1) ithen > ; goes here at i and k passes > endif > > if (kvar == 0) ithen > ; never goes here > endif > > if (kvar == 0) then > ; goes here at i-pass > ; doesnt go here at k-pass (unless we add code that changes kvar to 0 in some k-pass) > endif > > endin > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
|
In reply to this post by joachim-3
Working with these cases a bit more, I've come to see the truth of what
Steven was saying. For me it boils down to this: if you want an if/then condition (or if/goto for that matter) to be (re)evaluated at k-time, the if condition must include a k-variable. If it doesn't, the condition won't be reevaluated. If you are working with i-time variables, as Steven suggests, you can force a k-time reevaluation by casting the variable to k-rate. A revised instrument 1 (that illustrates the difference in behavior) is: instr 1 kval = gival ;if kval != 2 then if gival != 2 then print gival printk .5, gival endif endin Using "if gival" does not reevaluate; using "if kval" does reevaluate. So for me at least, case closed. Thanks again to all who furnished input to this thread. Art Hunkins ----- Original Message ----- From: "joachim heintz" <[hidden email]> To: <[hidden email]> Sent: Saturday, February 18, 2012 9:22 AM Subject: Re: [Csnd] gi variable evaluation? > hi art - > > you did really start an interesting thread ... > > i can't confirm that "even if instr 1 starts a bit *later* than instr > 2, the if comparison in instr 1 still evaluates to 0 (or something other > than 2) - executing the then condition" (see below, case 3). > > i think there are three cases. i have simplified your instrument > slightly to this form: > > <CsoundSynthesizer> > <CsInstruments> > gival init 0 > instr 1 > if gival != 2 then > printk .5, gival > endif > print gival > endin > instr 2 > gival = 2 > endin > </CsInstruments> > <CsScore> > i1 0 1 > i2 0 1 > e > </CsScore> > </CsoundSynthesizer> > > CASE 1 > running the csd as here (or in your original post) evaluates the > condition 'gival != 2' as true. so the gate to the 'then' statement is > open, both: at the initialization path and at the performance time. > the change of gival in instr 2 has no effect to this, because it's "too > late" now. but it changes the value of gival from 0 to 2, so this will > be printed during performance time in instr 1 via printk. (printk will > ask for the actual value of gival at its printing time, not for the > first value ever been there.) my output: > instr 1: gival = 0.000 > new alloc for instr 2: > i 1 time 0.00023: 2.00000 > i 1 time 0.50000: 2.00000 > i 1 time 1.00000: 2.00000 > > CASE 2 > changing the instrument numbers (instr 1 becomes instr 2 and vice versa) > performs the statement 'gival = 2' first, because it now has the lower > instrument number. so the if-condition is false, the gate stays closed, > and the printk is not evaluated at all. this is my output: > new alloc for instr 1: > new alloc for instr 2: > instr 2: gival = 2.000 > > CASE 3 > going back to the original numbering of instr 1 and instr 2 (as in the > csd above), but now starting instr 1 after instr 2 (at least one k-cycle > after instr 2, for instance 0.001). now instr 2 can change gival to 2, > so when instr 1 starts, the expression 'gival != 2' is false, and the > printk statement is not evaluated at all. this is my printout: > new alloc for instr 2: > B 0.000 .. 0.001 T 0.001 TT 0.001 M: 0.0 > new alloc for instr 1: > instr 1: gival = 2.000 > B 0.001 .. 1.000 T 1.000 TT 1.000 M: 0.0 > B 1.000 .. 1.001 T 1.001 TT 1.001 M: 0.0 > > this is with the old parser (csound 5.16). i get the same result with > the new parser. so, no bug / incompatibility, steven?! > > thanks, matt, for the condensed overview. i never ever used ithen, but > it might be very useful in certain cases. > > joachim > > > Am 18.02.2012 03:13, schrieb Art Hunkins: >> I'm beginning to understand. >> >> It looks like you have to watch out for if/then's as much as for >> if/goto's. (I was led to believe that if/then's were much "safer.") >> >> There is one further complicating factor: even if instr 1 starts a >> bit *later* than instr 2, the if comparison in instr 1 still >> evaluates to 0 (or something other than 2) - executing the then >> condition. >> >> It must have to do with the global variable (givar) being evaluated >> at *orch* initialization rather than at instrument initialization >> time. I gather that orch initialization is done by instrument number >> order rather than start time. >> >> Does this make sense? >> >> Art Hunkins >> >> ----- Original Message ----- From: "Steven Yi" <[hidden email]> >> To: <[hidden email]> Sent: Friday, February 17, 2012 8:13 >> PM Subject: Re: [Csnd] gi variable evaluation? >> >> >> Hmm, interesting! I think I had either looked at this before, >> forgot it, and remembered something wrong, or maybe just had it wrong >> in my head all this time, and the side effect was that it got me the >> right results. (!!) I went and looked at the code. In the old >> parser, if-then uses cngoto, and if-ithen uses cogoto. In the new >> parser, it looks like it is only using cngoto (that's a bug that >> should be fixed...). >> >> So, Matt's correct and the current Csound *does* what he says. >> >> However, I think I do understand what is going on with Art's >> situation. The value that is compared on the first pass is cached >> as a boolean on that init-pass. At that time, the value evaluated >> to false, and that is stored in a synthetic b variable. So going >> back to the translated code: >> >> #b0 = (ival == 2) cngoto #b0, __label0 printk kval __label0: >> >> That #b0 stores the initial comparison. Therefore, if it's true or >> false at init-time, it's going to stay that way through >> performance-time. If the gival changes, it won't affect the value >> used in the conditional check. >> >> This is great that you chimed in Matt, thanks! Now I've got it >> clearer in my head. >> >> (Rory: You may want to revise what you present! :P) >> >> steven >> >> >> On Fri, Feb 17, 2012 at 11:58 PM, matt ingalls <[hidden email]> >> wrote: >>> and just to clarify a bit more, i think this is how it should work >>> (at least how it used to) >>> >>> ival init 0 if (ival != 0) then ; never gets here at i or k passes >>> endif >>> >>> if (kval == kotherval) then ; always here at i-pass ; could be here >>> or not at k-pass depending on conditional endif >>> >>> if (xval) ithen ; here during the i-pass (if conditional was true) >>> ; never here during k-pass endif >>> >>> On Feb 17, 2012, at 3:47 PM, matt ingalls wrote: >>> >>>> steven: if this is how it works now, then this is a change from >>>> the original implementation. >>>> >>>> if/then is supposed to be the equivalent to if/goto and as should >>>> do the conditional at BOTH i and k rates. >>>> >>>> >>>> >>>> On Feb 17, 2012, at 2:33 PM, Steven Yi wrote: >>>> >>>>> if (ival != 2) then printk kval endif >>>>> >>>>> becomes: #b0 = (ival == 2) cigoto #b0, __label0 printk kval >>>>> __label0: >>>> >>>> >>>> >>>> Send bugs reports to the Sourceforge bug tracker >>>> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >>>> Discussions of bugs and features can be posted here To >>>> unsubscribe, send email [hidden email] with body >>>> "unsubscribe csound" >>>> >>> >>> >>> >>> Send bugs reports to the Sourceforge bug tracker >>> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >>> Discussions of bugs and features can be posted here To unsubscribe, >>> send email [hidden email] with body "unsubscribe csound" >>> >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here To unsubscribe, >> send email [hidden email] with body "unsubscribe csound" >> >> = >> >> >> Send bugs reports to the Sourceforge bug tracker >> https://sourceforge.net/tracker/?group_id=81968&atid=564599 >> Discussions of bugs and features can be posted here To unsubscribe, >> send email [hidden email] with body "unsubscribe csound" >> >> > > > Send bugs reports to the Sourceforge bug tracker > https://sourceforge.net/tracker/?group_id=81968&atid=564599 > Discussions of bugs and features can be posted here > To unsubscribe, send email [hidden email] with body "unsubscribe > csound" > Send bugs reports to the Sourceforge bug tracker https://sourceforge.net/tracker/?group_id=81968&atid=564599 Discussions of bugs and features can be posted here To unsubscribe, send email [hidden email] with body "unsubscribe csound" |
| Powered by Nabble | See how NAML generates this page |
