Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate
| Date | 2018-08-18 18:00 |
| From | "Mauro G." |
| Subject | Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate |
Hi, I think I understood why there is the strange behaviour you noticed.
First of all, it is independent from the polymorphism, because the problem arises when you use just a single UDO too.
The problem is in the way Csound manages the UDOs execution that is different from that of native opcodes.
For example, let's take a native opcode with k-time output:
kSomething NATIVE_OPCODE ...params...
the above code will run ONLY at k-time because that native opcode returns a k-value. This is the expected behaviour and it works correctly.
Now, let's take an UDO opcode witk k-time output:
kSomething UDO ...params...
In this case, Csound will run the UDO at i-time too, because inside the UDO definition there could be i-values to initialize. Of course, the k-rate native instructions inside the UDO will be skipped... All except two: "xin" and "xout". These statements are executed at init-time, and this is written in the Csound reference docs (https://csound.com/docs/manual/xout.html):
"[...]These opcodes actually run only at i-time. Performance time copying is done by the user opcode call.[...]"
In your example, the problem is not in the presence of two "RndInt" UDOs, but in the fact that Csound will run the i-time part of your UDO code at i-time, regardless of the type of its output variable types... And, in doing this, your RndInt UDO will not be completely skipped at init-time (as it would be if it was a native opcode with k-value output):
instr 2 (at init-time:)
EXECUTED: kBla init 10
*SKIPPED* printk2 kBla
EXECUTED: kBla RndInt 1, 2 <--- it will be executed the i-time part and kBla will be overwritten by a 0 value
*SKIPPED* turnoff
endin
instr 2 (at performance-time:)
*SKIPPED* kBla init 10
EXECUTED: printk2 kBla
EXECUTED: kBla RndInt 1, 2 <--- it will be executed the k-time part
EXECUTED: turnoff
endin
Of course, at init-time, the instruction "kRnd random kMin, kMax+.999999" inside the RndInt UDO will be skipped because "random" is a native opcode and works, as expected, only at k-time.
So, when RndInt returns from its init-pass, the kBla variable will be set to RndInt->kRnd, that is 0, because during init-time the central line with the 'random' statement ("kRnd random kMin, kMax+.999999") was skipped (being that "random" is a native opcode and works, as expected, only at k-time), therefore RndInt->kRnd wasn't valued yet and Csound considers it as 0...
The result is that, at performance-time, the printed value of kBla, for the second instrument, will be 0, not 10.
This also explains why, in the case of the functional syntax, it works as you expected:
instr 3
kBla init 10
printk2 kBla
;forcing to select the k-rate version of the
;UDO works again
kBla = RndInt:k(1, 2)
turnoff
endin
This works not because you forced the ':k' (in fact you could skip the ':k' and it should work anyway), but because the '=' is like a native opcode to Csound, so its behaviour is to skip its execution at init-time... And the result is that, in "instr 3", kBla will not be touched at init-time, as you expect.
Anyway, altough this explains why there is this strange behaviour, I think it's not the "right" behaviour and it should be corrected in some way, because it is very confusing for the user.
All the problems arise from this:
kBla RndInt 1, 2 <--- at init-time Csound will run the i-time part of the UDO
At init-time it's ok to execute the i-time part of RndInt, I understand... but why you have to return its (undefined at init-time) value too, bein |
| Date | 2018-08-18 18:38 |
| From | Mauro Giubileo |
| Subject | Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate |
|
I want to add, regarding whether or not this is a bug, that in the Csound reference docs for "init" opcode (https://csound.com/docs/manual/init.html) you can read:
Actually, this is not true, because in the example of joachim, the k-rate UDO "RndInt" write a 0 in the k-rate kBla variable at init-time! So, or the above note is false, or we have a bug! :-) Regards, Il 2018-08-18 19:00 Mauro G. ha scritto:
|
| Date | 2018-08-18 20:25 |
| From | joachim heintz |
| Subject | Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate |
thanks, mauro, for these illuminating explanations.
i am curious whether others think it should be changed, too. i agree
with you that it is confusing for users.
joachim
On 18/08/18 19:00, Mauro G. wrote:
> Hi, I think I understood why there is the strange behaviour you noticed.
> First of all, it is independent from the polymorphism, because the problem arises when you use just a single UDO too.
>
> The problem is in the way Csound manages the UDOs execution that is different from that of native opcodes.
> For example, let's take a native opcode with k-time output:
>
> kSomething NATIVE_OPCODE ...params...
>
> the above code will run ONLY at k-time because that native opcode returns a k-value. This is the expected behaviour and it works correctly.
> Now, let's take an UDO opcode witk k-time output:
>
> kSomething UDO ...params...
>
> In this case, Csound will run the UDO at i-time too, because inside the UDO definition there could be i-values to initialize. Of course, the k-rate native instructions inside the UDO will be skipped... All except two: "xin" and "xout". These statements are executed at init-time, and this is written in the Csound reference docs (https://csound.com/docs/manual/xout.html):
>
> "[...]These opcodes actually run only at i-time. Performance time copying is done by the user opcode call.[...]"
>
> In your example, the problem is not in the presence of two "RndInt" UDOs, but in the fact that Csound will run the i-time part of your UDO code at i-time, regardless of the type of its output variable types... And, in doing this, your RndInt UDO will not be completely skipped at init-time (as it would be if it was a native opcode with k-value output):
>
> instr 2 (at init-time:)
> EXECUTED: kBla init 10
> *SKIPPED* printk2 kBla
> EXECUTED: kBla RndInt 1, 2 <--- it will be executed the i-time part and kBla will be overwritten by a 0 value
> *SKIPPED* turnoff
> endin
>
> instr 2 (at performance-time:)
> *SKIPPED* kBla init 10
> EXECUTED: printk2 kBla
> EXECUTED: kBla RndInt 1, 2 <--- it will be executed the k-time part
> EXECUTED: turnoff
> endin
>
> Of course, at init-time, the instruction "kRnd random kMin, kMax+.999999" inside the RndInt UDO will be skipped because "random" is a native opcode and works, as expected, only at k-time.
>
> So, when RndInt returns from its init-pass, the kBla variable will be set to RndInt->kRnd, that is 0, because during init-time the central line with the 'random' statement ("kRnd random kMin, kMax+.999999") was skipped (being that "random" is a native opcode and works, as expected, only at k-time), therefore RndInt->kRnd wasn't valued yet and Csound considers it as 0...
>
> The result is that, at performance-time, the printed value of kBla, for the second instrument, will be 0, not 10.
>
> This also explains why, in the case of the functional syntax, it works as you expected:
>
> instr 3
> kBla init 10
> printk2 kBla
> ;forcing to select the k-rate version of the
> ;UDO works again
> kBla = RndInt:k(1, 2)
> turnoff
> endin
>
> This works not because you forced the ':k' (in fact you could skip the ':k' and it should work anyway), but because the '=' is like a native opcode to Csound, so its behaviour is to skip its execution at init-time... And the result is that, in "instr 3", kBla will not be touched at init-time, as you expect.
>
> Anyway, altough this explains why there is this strange behaviour, I think it's not the "right" behaviour and it should be corrected in some way, because it is very confusing for the user.
>
> All the problems arise from this:
>
> kBla RndInt 1, 2 <--- at init-time Csound will run the i-time part of the UDO
>
> At init-time it's ok to execute the i-time part of RndInt, I understand... but why you have to return its (undefined at init-time) value too, being that the return value in this case is a k-type variable? |
| Date | 2018-08-18 21:35 |
| From | Mauro Giubileo |
| Subject | Re: [Csnd-dev] UDO compilation seclects i- instead of k-rate |
|
I'm glad I could be of help. :-) I'm learning Csound myself so I thank you for giving me the opportunity to deepen these aspects of the language. It is useful to know these little and misleading quirks that otherwise can cause you a lot of headaches. :-D Regards, Il 2018-08-18 21:25 joachim heintz ha scritto:
|